Получается, что вы здесь.
Основные моменты использования реляционной базы данных.
- Хорошо определенные отношения.
- Хорошо определенная и подробная схема.
- Высокая производительность для больших наборов данных.
Вы должны поддерживать отношения. Но вы теряете схему и много производительности. Схема - это не просто проверка данных. Это означает, что вы не можете использовать триггеры или ограничения для отдельных полей.
Что касается производительности ... вы заметите, что большинство тестов производительности JSONB противоречат другим аналогичным типам данных. Они никогда не противоречат обычным таблицам SQL. Это потому, что, хотя JSONB поразительно эффективен, он не так эффективен, как обычный SQL. Итак, давайте проверим это, оказывается, вы здесь что-то здесь.
Использование набора данных из this JSONB performance presentation я создал правильную схему SQL ...
create table customers (
id text primary key
);
create table products (
id text primary key,
title text,
sales_rank integer,
"group" text,
category text,
subcategory text,
similar_ids text[]
);
create table reviews (
customer_id text references customers(id),
product_id text references products(id),
"date" timestamp,
rating integer,
votes integer,
helpful_votes integer
);
И один, который использует отношения SQL, но JSONB для данных ...
create table customers (
id text primary key
);
create table products_jb (
id text primary key,
fields jsonb
);
create table reviews_jb (
customer_id text references customers(id),
product_id text references products_jb(id),
fields jsonb
);
И одна таблица JSONB ,
create table reviews_jsonb (
review jsonb
);
Then I imported the same data into both sets of tables using a little script. 589859 обзоров, 93319 продуктов, 98761 клиентов.
Давайте попробуем тот же запрос, что и в статье о производительности JSONB, получив средний обзор для категории продукта. Во-первых, без индексов.
Традиционные SQL: 138 мс
test=> select round(avg(r.rating), 2)
from reviews r
join products p on p.id = r.product_id
where p.category = 'Home & Garden';
round
-------
4.59
(1 row)
Time: 138.631 ms
Полный JSONB: 380 мс
test=> select round(avg((review#>>'{review,rating}')::numeric),2)
test-> from reviews_jsonb
test-> where review #>>'{product,category}' = 'Home & Garden';
round
-------
4.59
(1 row)
Time: 380.697 ms
Hybrid JSONB: 190 мс
test=> select round(avg((r.fields#>>'{rating}')::numeric),2)
from reviews_jb r
join products_jb p on p.id = r.product_id
where p.fields#>>'{category}' = 'Home & Garden';
round
-------
4.59
(1 row)
Time: 192.333 ms
Это честно пошли лучше, чем думали. Гибридный подход в два раза быстрее, чем полный JSONB, но на 50% медленнее обычного SQL. Теперь как насчет индексов?
Традиционный SQL-: 130 мс (+500 мс для индекса)
test=> create index products_category on products(category);
CREATE INDEX
Time: 491.969 ms
test=> select round(avg(r.rating), 2)
from reviews r
join products p on p.id = r.product_id
where p.category = 'Home & Garden';
round
-------
4.59
(1 row)
Time: 128.212 ms
Полное JSONB: 360 мс (+ 25000 мс для индекса)
test=> create index on reviews_jsonb using gin(review);
CREATE INDEX
Time: 25253.348 ms
test=> select round(avg((review#>>'{review,rating}')::numeric),2)
from reviews_jsonb
where review #>>'{product,category}' = 'Home & Garden';
round
-------
4.59
(1 row)
Time: 363.222 ms
Гибридный JSONB: 185 мс (+6900 мса для индексов)
test=> create index on products_jb using gin(fields);
CREATE INDEX
Time: 3654.894 ms
test=> create index on reviews_jb using gin(fields);
CREATE INDEX
Time: 3237.534 ms
test=> select round(avg((r.fields#>>'{rating}')::numeric),2)
from reviews_jb r
join products_jb p on p.id = r.product_id
where p.fields#>>'{category}' = 'Home & Garden';
round
-------
4.59
(1 row)
Time: 183.679 ms
Оказывается, это индексация запроса не будет много помощи.
Это то, что я вижу, играя с данными немного, гибридный JSONB всегда медленнее, чем полный SQL, но быстрее, чем Full JSONB. Это похоже на хороший компромисс. Вы можете использовать традиционные внешние ключи и объединения, но имеете гибкость добавления любых полей, которые вам нравятся.
Я рекомендую использовать гибридный подход еще на шаг: используйте столбцы SQL для полей, которые, как вы знаете, будут там, и должны иметь столбец JSONB для получения любых дополнительных полей для гибкости.
Я рекомендую вам поиграть с тестовыми данными здесь и посмотреть, что такое производительность.