Ответ
Основное различие между JSON и JSONB в PostgreSQL заключается в способе хранения данных, что напрямую влияет на производительность и возможности.
-
JSON: Хранит точную текстовую копию входных данных. Сохраняются все пробелы, порядок ключей и дубликаты ключей. При каждом запросе данные требуют повторного парсинга. -
JSONB(Bозначает Binary): Хранит данные в декомпозированном бинарном формате. Пробелы удаляются, порядок ключей не сохраняется (они сортируются), а при наличии дубликатов сохраняется только последнее значение. Данные парсятся один раз при вставке.
Ключевые отличия
| Характеристика | JSON |
JSONB |
|---|---|---|
| Хранение | Текст | Бинарный формат |
| Скорость вставки | Быстрее (нет преобразования) | Медленнее (требуется парсинг) |
| Скорость чтения | Медленнее (требуется парсинг) | Значительно быстрее |
| Индексация | Не поддерживается | Поддерживаются GIN-индексы |
| Пробелы и порядок | Сохраняются | Не сохраняются |
Пример использования
-- Создаем таблицу для демонстрации
CREATE TABLE products (
id serial PRIMARY KEY,
attributes_json JSON,
attributes_jsonb JSONB
);
-- Вставляем данные с пробелами и разным порядком ключей
INSERT INTO products (attributes_json, attributes_jsonb)
VALUES
('{"price": 99.9, "name": "Gadget" }', '{"price": 99.9, "name": "Gadget" }');
-- Проверяем, как данные сохранились
SELECT attributes_json, attributes_jsonb FROM products;
-- attributes_json: {"price": 99.9, "name": "Gadget" } (как есть)
-- attributes_jsonb: {"name": "Gadget", "price": 99.9} (отформатировано)
-- Создаем индекс для JSONB для ускорения запросов
CREATE INDEX idx_products_attributes ON products USING GIN (attributes_jsonb);
-- Этот запрос будет работать очень эффективно благодаря индексу
SELECT * FROM products WHERE attributes_jsonb @> '{"name": "Gadget"}';
Рекомендация: Почти всегда следует использовать JSONB, так как он обеспечивает значительно лучшую производительность запросов и поддерживает индексацию. JSON стоит выбирать только в редких случаях, когда необходимо сохранить исходное форматирование JSON-документа.
Ответ 18+ 🔞
Давай разберёмся с этой парой, блядь, JSON и JSONB. Ситуация, внатуре, как с двумя братанами-близнецами, но один — просто текст, а второй — прокачанный бинарный монстр. Ёпта, сейчас всё разжуем.
JSON — это как архив с бумажками. Засунули туда бумажку с надписью {"price": 99.9, "name": "Gadget" }, он её так и хранит, со всеми пробелами, порядком и даже если ты туда же, сука, второй раз ключ "name" запишешь. Каждый раз, когда надо прочитать, этот архив распаковывают и парсят заново. Медленно, пиздец как неудобно.
JSONB (это B от binary, ёпта) — это уже не архив, а нормальная база данных внутри базы данных. Ты ему суёшь ту же бумажку, а он её, блядь, моментально разбирает на запчасти: выкидывает лишние пробелы, ключи сортирует, дубликаты выпиливает (оставляет последний, хитрая жопа). И всё это складывает в оптимизированный бинарный формат. Парсинг — один раз при вставке, а потом читается мгновенно.
Так в чём разница, блядь? Смотри таблицу, чтобы не еб@ть мозг:
| Прикол | JSON |
JSONB |
|---|---|---|
| Как лежит | Текст, как есть | Разобранный бинарник |
| Запись | Быстро (просто скопировал текст) | Помедленнее (надо разобрать и упаковать) |
| Чтение | Медленно (каждый раз парсить) | Овердохуища быстрее (уже готово) |
| Индексы | Нельзя, нихуя | Можно! GIN-индексы, красота! |
| Порядок и мусор | Сохраняет всё | Выкидывает нахуй |
Пример из жизни, чтобы вообще всё стало ясно:
-- Делаем табличку для экспериментов
CREATE TABLE products (
id serial PRIMARY KEY,
attributes_json JSON,
attributes_jsonb JSONB
);
-- Пихаем данные. Смотри, в JSONB пробелы лишние схавает.
INSERT INTO products (attributes_json, attributes_jsonb)
VALUES
('{"price": 99.9, "name": "Gadget" }', '{"price": 99.9, "name": "Gadget" }');
-- Смотрим, что получилось
SELECT attributes_json, attributes_jsonb FROM products;
-- attributes_json: {"price": 99.9, "name": "Gadget" } (всё на месте, даже пробелы в конце)
-- attributes_jsonb: {"name": "Gadget", "price": 99.9} (причёсано, ключи переставлены)
-- Вот магия! На JSONB можно навесить индекс, и поиск станет мгновенным.
CREATE INDEX idx_products_attributes ON products USING GIN (attributes_jsonb);
-- Этот запрос, блядь, выстрелит как из пушки благодаря индексу.
SELECT * FROM products WHERE attributes_jsonb @> '{"name": "Gadget"}';
Итог, ёпта: Если тебе не нужно срочно сохранить, блядь, точную копию JSON-документа со всеми его тараканами (а такое бывает раз в пятилетку), то всегда, сука, выбирай JSONB. Он быстрее, умнее и с индексами дружит. JSON — это для музея, а JSONB — для боя. Всё, вопрос закрыт.