JSONB с индексированием против hstore


28

Я пытаюсь определиться с дизайном базы данных, используя как можно меньше предположений (относительно того, как на самом деле развивается веб-приложение) на данном этапе.

В качестве первого шага, понимая, что СОЕДИНЕНИЯ являются дорогостоящими, я рассматриваю небольшое количество монолитных таблиц, а не большое количество нормализованных меньших таблиц. Во-вторых, я запутался между использованием hstore против обычных таблиц и JSONB (с индексацией GiST).

AFAIK (пожалуйста, не стесняйтесь исправлять):

  1. Как правило, в Postgres hstore работает лучше, чем другие типы данных. Эта презентация от FOSDEM PGDAY содержит некоторые интересные статистические данные (во второй половине слайдов). https://wiki.postgresql.org/images/b/b4/Pg-as-nosql-pgday-fosdem-2013.pdf

  2. Преимущество hstore - быстрая индексация (GiN или GiST). Однако с помощью JSONB индексация GiN и GiST также может применяться к данным JSON.

  3. Этот блог от профессионала из 2nd Quadrant гласит: «На данный момент, вероятно, стоит заменить использование hstore на jsonb во всех новых приложениях» (прокрутите до конца): http://blog.2ndquadrant.com/postgresql-anti-patterns-unneeded -jsonhstore-динамические-столбцы /

Поэтому я хотел бы принять решение о следующем:

  1. Для основной (структурированной) части данных: должны ли они находиться в паре реляционных таблиц (относительно больших с большим количеством столбцов) или это должно быть несколько хранилищ значений ключей, использующих hstore?
  2. Для специальных данных (пользовательские / неструктурированные) данные должны быть в JSON или специальные значения ключей хранятся в hstore (с ключами, хранящимися в одной из основных реляционных таблиц)?

7
Присоединения не дорогие. Кто тебе это сказал? Поскольку в целом вся концепция реляционных баз данных вращается вокруг объединений (с практической точки зрения), эти продукты очень хороши в объединениях. Нормальный образ мышления начинается с правильно нормированных структур и начинается с причудливых денормализаций и тому подобного, когда производительность действительно нуждается в чтении. JSON(B)и hstore(и EAV) хороши для данных с неизвестной структурой.
Дезсо

6
@ Йогеш, эти ссылки содержат некоторые интересные и дико противоречивые вещи :) С моральной точки зрения, похоже, что MySQL (был) плох в объединениях, и люди из NoSQL склонны обобщать это понятие без какой-либо реальной фактической основы. С другой стороны, Аарон и Макс чувствительны к этому p-слову - его широкое использование показывает, как не носители языка (включая меня) счастливо используют не то слово.
Dezso

4
@ Йогеш, реально, я уверен, что в Интернете есть источник, который может «доказать» что-либо, точно так же, как любой религиозный текст может быть использован для оправдания злодеяний (как драматически показано в истории). Это правда, чем меньше работы вы выполняете, тем меньше она стоит, но всегда есть некоторый компромисс .
Эрик

4
@Yogesch: Избегание объединений важно для операций с интенсивным чтением, когда вы заранее знаете схему доступа к данным, и поэтому вы можете безопасно поместить все необходимые данные в одну строку. Однако это делает другие объединения потенциально более дорогостоящими. Кто сказал, что вам не нужно объединять данные разными способами, чтобы отвечать на различные вопросы? Теперь мы просто погрузимся в теорию моделирования реляционных данных ...
Крис

5
@Yogesch В моей практике, с базами данных узким местом является редко ОЗУ или ЦП, но это ввод / вывод - таким образом, избежать хранения избыточных данных все еще важно. Как говорит Крис, если вы всегда видите свои данные только одним способом, это может стоить цену. Если нет, то вы с громоздким и крайне негибким блоком данных.
Dezso

Ответы:


41

Реляционные базы данных созданы на основе объединений и оптимизированы для их успешного выполнения.

Если у вас нет веской причины не использовать нормализованный дизайн, используйте нормализованный дизайн.

jsonbи такие вещи hstoreхороши, когда вы не можете использовать нормализованную модель данных, например, когда модель данных быстро меняется и определяется пользователем.

Если вы можете смоделировать его реляционно, смоделируйте его реляционно. Если вы не можете, рассмотрите json и т. Д. Если вы выбираете между json / jsonb / hstore, обычно выбирайте jsonb, если у вас нет причин не делать этого.

Об этом я и говорил в своем блоге , посвященном именно этой теме. Пожалуйста, прочитайте весь пост . В абзаце, который вы цитировали, указывается, что если вы выбираете динамическую структуру, вам следует выбрать jsonb вместо hstore, но остальная часть поста блога посвящена тому, почему вы, как правило, предпочитаете реляционную модель, если можете.

Так. Смоделируйте основную структурированную часть реляционно. Если таблицы действительно широкие с большим количеством столбцов, это может указывать на необходимость дальнейшей нормализации. Не бойся объединений. Учись любить, присоединяется. Присоединение ко многим маленьким таблицам часто будет быстрее, чем запрашивать и поддерживать большие денормализованные таблицы. Денормализуйте только в том случае, если вам это необходимо для конкретных случаев, и желательно с помощью материализованных представлений ... но не делайте этого, пока не узнаете, что вам нужно, и не решите конкретную конкретную проблему.

Для пользовательских данных, которые имеют произвольную и неструктурированную форму, используйте jsonb. Он должен работать так же хорошо, как и hstore, но он более гибкий и с ним легче работать.

Нужно понимать одну важную вещь: индексы GiST и GIN, подобные тем, которые используются в jsonb, обычно гораздо менее эффективны, чем простые индексы b-дерева. Они более гибкие, но индекс b-дерева в нормальном столбце почти всегда будет намного, намного быстрее.


Большое спасибо, Крейг, теперь я гораздо лучше понимаю и знаю, что делать. Последующий вопрос: если я храню что-то вроде лайков или подписчиков в формате двух столбцов (post_id и user_id для лайков ), лучше ли использовать реляционную таблицу с двумя столбцами или hstore? (Я не против сделать это новым вопросом)
Yogesch

5
@Yogesch Звучит как стандартная таблица соединений m: n с постоянным и стабильным форматом. Вопрос всегда должен быть: «Есть ли веская причина, по которой я не должен делать это обычным реляционным способом для этого конкретного случая?».
Крейг Рингер,

hstoreне рекомендуется. Использование jsonb.
danger89

2
@ danger89 На самом деле, формально это не считается устаревшим, хотя я не думаю, что есть основания использовать его в пользу jsonb. В любом случае ... это как бы упущение. Вопрос в том, следует ли моделировать реляционно или использовать структурированный тип данных.
Крейг Рингер
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.