Пояснення JSONB, запроваджене PostgreSQL


346

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


4
З PGCon2014: youtube.com/…
msanford

5
@CraigRinger URL недостатньо точний, зараз, через 1 рік, він навіть не вказує достатньо близько до вмісту, пов’язаного з JSONB.
berkus

2
@berkus Я подумав, що я пов’язаний із конкретною публікацією. Як засмучує.
Крейг Рінгер

1
Це вказує на конкретне відео.
талонкс

Відповіді:


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 зберігається в якомусь бінарному поданні

Є три основні наслідки цього:

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

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

  1. Якщо ви працюєте лише з представленням JSON у вашій програмі, PostgreSQL використовується лише для зберігання та отримання цього представлення, яке вам слід використовувати json.
  2. Якщо ви робите багато операцій зі значенням JSON в PostgreSQL або використовуєте індексацію в якомусь полі JSON, вам слід скористатися jsonb.

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

Піюш:

Коротка відповідь:

  • Якщо ви робите багато маніпуляцій JSON всередині PostgreSQL, таких як сортування, нарізка, сплайсинг тощо, вам слід скористатися JSONB з міркувань швидкості.
  • Якщо вам потрібні індексовані пошукові запити для довільних пошуків ключів на JSON, тоді вам слід використовувати JSONB.
  • Якщо ви нічого з цього не робите, ви, ймовірно, повинні використовувати JSON.
  • Якщо вам потрібно зберегти впорядкування ключів, пробіли та дублюючі ключі, вам слід скористатися JSON.

Для більш тривалої відповіді вам потрібно буде зачекати, коли я виконаю повний запис "HowTo" ближче до випуску 9.4.


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


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, якщо немає спеціальних потреб, таких як застарілі припущення щодо впорядкування об’єктних ключів.


13

Сьогодні я був у pgopen, орієнтири набагато швидші, ніж mongodb, я вважаю, що це було на 500% швидше для селекторів. Насправді все було швидше, принаймні, на 200% при контрасті з mongodb, ніж один виняток зараз - це оновлення, яке вимагає повного переписування всього стовпця json, що mongodb справляється краще.

Індексація джину на jsonb звучить приголомшливо.

Також postgres будуть зберігати типи jsonb внутрішньо і в основному відповідатимуть таким типам, як числовий, текстовий, булевий тощо.

Також можна буде приєднатись за допомогою jsonb

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

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

Окрім індексу, коли запит проти стовпця jsonb протиставлений postgres стовпця json не повинен фактично запускати функціонал для перетворення тексту в json у кожному рядку, що, ймовірно, заощадить величезну кількість часу на самоті.


8

Щодо відмінностей між типами jsonта jsonbтипами даних, то варто згадати офіційне пояснення:

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


7

Ще одна важлива відмінність, про яку не було сказано в жодній відповіді вище, полягає в тому, що не існує оператора рівності для jsonтипу, але він існує для jsonb.

Це означає , що ви не можете використовувати DISTINCTключове слово при виборі цього json-type і / або інших полів з таблиці (ви можете використовувати DISTINCT ONзамість цього, але це не завжди можливо з - за подібні випадки це ).


6

Наскільки я можу сказати,

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

  • json, як він існує , тепер дозволяє вкладати, але є текстовим і не дозволяє індексувати, таким чином, це "повільно"

  • jsonb, який вийде з 9.4, матиме поточні можливості вкладання json, а також GIN / GIST індексацію hstore, так що це буде швидко

Люди, які працюють над 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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.