Объяснение JSONB, представленное PostgreSQL

346

PostgreSQL только что представил JSONB, и он уже в тренде на хакерских новостях . Было бы здорово, если бы кто-то мог объяснить, чем он отличается от Hstore и JSON, ранее присутствовавших в PostgreSQL. Каковы его преимущества и ограничения и когда кто-то должен рассмотреть возможность его использования?

Peeyush
источник
4
От PGCon2014: youtube.com/...
msanford
5
URL @CraigRinger не является достаточно точным, теперь, спустя 1 год, он даже не указывает достаточно близко к контенту, связанному с JSONB.
Беркус
2
@berkus Я думал, что связан с конкретным постом. Как расстраивает.
Крейг Рингер,
1
Это действительно указывает на конкретное видео.
talonx

Ответы:

458

Во-первых, hstoreэто модуль contrib, который позволяет хранить только пары ключ => значение, где ключами и значениями могут быть только texts (однако значения также могут быть sql NULLs).

Обе json& jsonbпозволяет вам сохранить действительное значение JSON (определенное в его спецификации ).

F.ex. они являются действительными представлениями JSON: null, true, [1,false,"string",{"foo":"bar"}], {"foo":"bar","baz":[null]}- hstoreэто просто немного подмножества по сравнению с тем, что JSON может (но если вам нужно только это подмножество, это хорошо).

Единственная разница между json& jsonbявляется их хранением:

  • json хранится в простом текстовом формате, в то время как
  • jsonb хранится в некотором двоичном представлении

Есть 3 основных последствия этого:

  • jsonbобычно занимает больше места на диске, чем json(иногда нет)
  • jsonb требуется больше времени для построения из его входного представления, чем json
  • jsonоперации занимают значительно больше времени jsonb(& анализ также должен выполняться каждый раз, когда вы выполняете какую-либо операцию с jsonвведенным значением)

Когда jsonbбудет доступен стабильный выпуск, будет два основных варианта использования, когда вы легко сможете выбрать между ними:

  1. Если вы работаете только с представлением JSON в своем приложении, PostgreSQL используется только для хранения и извлечения этого представления, которое вы должны использовать json.
  2. Если вы выполняете много операций со значением JSON в PostgreSQL или используете индексирование для какого-либо поля JSON, вам следует использовать jsonb.
pozs
источник
1
привет, так как он имеет двоичное представление, почему jsonbне поддерживает это? UPDATE test SET data->'a' = 123 WHERE id = 1;отCREATE TABLE test(id SERIAL PRIMARY KEY, data JSONB);
Кокиццу
1
Кокиццу, это возможно в 9,5. wiki.postgresql.org/wiki/...
ChelowekKot
1
Просто добавить, одна из причин , вы можете также использовать jsonболее jsonb, если для устаревших причин вашего кода потребляя ваш jsonзависят от упорядочения jsonполей , и они не могут быть перераспределены.
djdrzzy
4
Так же как и по старым причинам: в JSON нет семантической разницы, если пары ключ-значение объекта (таблица, карта, хэш, как бы он ни вызывался на языке хоста) упорядочены по-разному. Если вы полагаетесь на это, вы на самом деле используете что-то отличное от JSON. - Для « textпротив» json: последний поставляется с проверкой JSON, поэтому при неправильном JSON произойдет сбой только при вставке, а не каждый раз, когда ваше приложение читает его (потому что оно получает недопустимое представление). Кроме того, вы можете безопасно привести последнее jsonbв базу данных.
поз
2
Это отличный пост с объяснением деталей реализации JSONB ( pgeoghegan.blogspot.com/2014/03/what-i-think-of-jsonb.html )
manugupt1
132

Peeyush:

Краткий ответ:

  • Если вы делаете много JSON-манипуляций внутри PostgreSQL, таких как сортировка, нарезка, сплайсинг и т. Д., Вы должны использовать JSONB по соображениям скорости.
  • Если вам нужен индексированный поиск для произвольного поиска ключей в JSON, то вам следует использовать JSONB.
  • Если вы не делаете ничего из вышеперечисленного, вам, вероятно, следует использовать JSON.
  • Если вам нужно сохранить порядок ключей, пробелы и дубликаты ключей, вам следует использовать JSON.

Чтобы получить более длинный ответ, вам нужно подождать, пока я полностью выпишу «HowTo», ближе к выпуску 9.4.

FuzzyChef
источник
74

Простое объяснение разницы между json и jsonb ( оригинальное изображение от PostgresProfessional ):

SELECT '{"c":0,   "a":2,"a":1}'::json, '{"c":0,   "a":2,"a":1}'::jsonb;

          json          |        jsonb 
------------------------+--------------------- 
 {"c":0,   "a":2,"a":1} | {"a": 1, "c": 0} 
(1 row)
  • JSON: текстовое хранилище «как есть»
  • JSONB: без пробелов
  • jsonb: нет повторяющихся ключей, выиграл последний ключ
  • jsonb: ключи отсортированы

Больше в речевом видео и презентации слайдов от разработчиков jsonb. Также они представили JsQuery , pg.extension предоставляет мощный язык запросов jsonb

ChelowekKot
источник
1
Спасибо, я заменил его на текст
ChelowekKot
56
  • hstore это больше тип хранения «широкий столбец», это плоский (не вложенный) словарь пар ключ-значение, всегда хранящийся в достаточно эффективном двоичном формате (хеш-таблица, отсюда и название).
  • jsonсохраняет документы JSON в виде текста, выполняя проверку при сохранении документов и анализируя их при выводе (например, обращаясь к отдельным полям); он должен поддерживать всю спецификацию JSON. Поскольку весь текст JSON хранится, его форматирование сохраняется.
  • jsonbиспользует быстродействие по соображениям производительности: данные JSON анализируются при вводе и сохраняются в двоичном формате, упорядочение ключей в словарях не поддерживается, а также дубликаты ключей. Доступ к отдельным элементам в поле JSONB быстрый, так как не требует постоянного анализа текста JSON. При выводе данные JSON восстанавливаются, и первоначальное форматирование теряется.

IMO, нет существенной причины не использовать jsonbего, если он доступен, если вы работаете с машиночитаемыми данными.

Иван Ворас
источник
24

JSONB - это «лучшая» версия JSON.

Давайте посмотрим на пример:

SELECT '{"c":0,   "a":2,"a":1}'::json, '{"c":0,   "a":2,"a":1}'::jsonb;
          json          |        jsonb 
------------------------+--------------------- 
 {"c":0,   "a":2,"a":1} | {"a": 1, "c": 0} 
(1 row)
  1. JSON хранит пробелы, поэтому мы можем видеть пробелы при сохранении ключа «a», а JSONB - нет.
  2. JSON хранит все значения ключа. По этой причине вы можете видеть несколько значений (2 и 1) для клавиши «a», в то время как JSONB только «хранит» последнее значение.
  3. JSON поддерживает порядок вставки элементов, а JSONB поддерживает «отсортированный» порядок.
  4. Объекты JSONB хранятся в виде распакованного двоичного файла, в отличие от «необработанных данных» в JSON, где повторный анализ данных не требуется во время поиска.
  5. JSONB также поддерживает индексирование, что может быть существенным преимуществом.

В общем, следует отдавать предпочтение JSONB, если нет особых потребностей, таких как устаревшие предположения о порядке расположения ключей объектов.

subodhkarwa
источник
13

Я был на pgopen сегодня, тесты намного быстрее, чем mongodb, я думаю, что он был примерно на 500% быстрее для избранных. Практически все было быстрее, по крайней мере, на 200% по сравнению с mongodb, чем одно исключение в настоящий момент - это обновление, которое требует полностью переписать весь столбец json, что-то, что mongodb обрабатывает лучше.

Индексирование джина на jsonb звучит потрясающе.

Также postgres будет внутренне сохранять типы jsonb и в основном сопоставлять их с такими типами, как числовой, текстовый, логический и т. Д.

Присоединения также будут возможны с помощью jsonb

Добавьте PLv8 для хранимых процедур, и для разработчиков node.js это станет мечтой.

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

Помимо индекса при запросе к столбцу jsonb, сопоставленному со столбцом json, postgres не обязательно должен запускать функцию преобразования текста в json в каждой строке, что, вероятно, сэкономит огромное количество времени в одиночку.

Джон
источник
8

Что касается различий между jsonи jsonbDatatypes, то стоит упоминания официального объяснения:

PostgreSQL предлагает два типа для хранения данных JSON: jsonи jsonb. Для реализации эффективных механизмов запросов для этих типов данных PostgreSQL также предоставляет тип данных jsonpath, описанный в разделе 8.14.6. .

Эти jsonи jsonbтипы данных принимают почти идентичные наборы значений в качестве входных данных. Основное практическое отличие заключается в эффективности. Тип jsonданных хранит точную копию входного текста, функции обработки которого должны обрабатываться при каждом выполнении; в то время как jsonbданные хранятся в разложенном двоичном формате, что делает их немного медленнее для ввода из-за дополнительных издержек преобразования, но значительно быстрее для обработки, поскольку повторное анализирование не требуется. jsonbтакже поддерживает индексирование, что может быть существенным преимуществом.

Поскольку jsonтип хранит точную копию входного текста, он сохранит семантически незначимый пробел между токенами, а также порядок ключей в объектах JSON. Кроме того, если объект JSON внутри значения содержит один и тот же ключ более одного раза, все пары ключ / значение сохраняются. (Функции обработки рассматривают последнее значение как оперативное.)jsonb не сохраняет пустое пространство, не сохраняет порядок ключей объекта и не сохраняет дублированные ключи объекта. Если во входных данных указаны повторяющиеся ключи, сохраняется только последнее значение.

Как правило, большинство приложений предпочитают хранить данные JSON как jsonb , если только нет особых потребностей, таких как устаревшие предположения о порядке расположения ключей объекта.

PostgreSQL позволяет использовать только одну кодировку для каждой базы данных. Поэтому типы JSON не могут жестко соответствовать спецификации JSON, если кодировка базы данных не является UTF8. Попытки напрямую включить символы, которые не могут быть представлены в кодировке базы данных, потерпят неудачу; наоборот, символы, которые могут быть представлены в кодировке базы данных, но не в UTF8, будут разрешены.

Источник: https://www.postgresql.org/docs/current/datatype-json.html

Dinei
источник
7

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

Это означает , что вы не можете использовать DISTINCTключевое слово при выборе этого json-type и / или других полей из таблицы (вы можете использовать DISTINCT ONвместо этого, но это не всегда возможно из - за подобные случаи это ).

vlasiak
источник
6

Насколько я могу сказать,

  • hstore в том виде, в каком он существует в настоящее время (в Postgresql 9.3), не допускает вложение других объектов и массивов в качестве значений его пар ключ / значение. тем не менее, будущий патч hstore позволит использовать вложенность. этот патч не будет выпущен в версии 9.4 и может быть не включен в ближайшее время.

  • json в том виде, в каком он существует в настоящее время , допускает вложение, но основывается на тексте и не допускает индексацию, поэтому он «медленный»

  • jsonb, который будет выпущен с 9.4, будет иметь текущие возможности вложения json, а также индексирование hstore в GIN / GIST, так что это будет быстро

Люди, работающие над postgresql 9.4, похоже, говорят, что новый, быстрый тип jsonb понравится людям, которые предпочли бы использовать хранилище данных noSQL, например MongoDB, но теперь могут объединять реляционную базу данных с неструктурированными данными с возможностью запроса под одной крышей.

http://www.databasesoup.com/2014/02/why-hstore2jsonb-is-most-important.html

Тесты postgresql 9.4 jsonb, кажется, находятся на одном уровне или в некоторых случаях быстрее, чем MongoDB

http://texture.io/alphabetum/postgresql-incl-hstore-vs-mongodb

Эрик Шведберг
источник