Если схема JSON четко определена, не используйте JSON.Сделайте рефакторинг вашей таблицы, чтобы использовать обычные поля вместо JSON, затем создайте индекс для полей, критичных к производительности.Поля JSON хороши для слабо определенной схемы, например, записей пациентов
При проектировании базы данных для использования обычных полей по сравнению с полями JSON сначала отойдите от базы данных.Подумайте, какое приложение вы бы использовали, если бы не было СУБД для сохранения ваших данных.
Если вы пытаетесь сохранить данные в Excel, то это ваша модель данных, как правило, табличная.
action product qty
received mouse 3
sold mouse 2
received keyboard 26
.. тогда просто используйте обычные поля, не пытайтесь использовать поля JSON.
Если вы стремитесь использовать Word (или даже OneNote или Notepad) вместо Excel, чтобы сохранить ваши данные (например,записи пациентов), то это хороший показатель того, что ваша модель данных является слабо определенной, что может быть облегчено с помощью JSON, тогда во всех случаях используйте JSON.Поскольку не все пациенты имеют одинаковые детали записей, которые нужно хранить, будет трудно, если не невозможно, добавлять новые поля в таблицу каждый раз, когда требуется записать новую деталь;так что да, используйте вместо этого JSON.
Patient: John Doe
Intake Criteria:
Dm Dx Date: 2012/03/12
Initial Hgb A1c: 6.5
Co Morbid: Hypertension, CAD
Labs:
LDL Cholestrol:
LDL Level: 122.5,
LDL Result Date: 2012/07/06
Serum Creatinine:
CreatinineLevel: 1.4
Creatinine Result Date: 12/07/08
------
Patient: Jane Doe
Blood Type: DB
CareLocation:
FacilityName: East Side Clinic
ContactEmail: rsnurse@eastside.org
Weight: 60kg
Если ваши данные, как правило, основаны на документах (например, OneNote, Word и т. д.), используйте JSON.Если ваши данные, как правило, основаны на листах (то есть в табличной форме, например, Excel), не используйте JSON, вместо этого используйте обычные поля.Нормальные поля являются естественными для доступа к СУБД и естественными для СУБД для создания индекса.
Если рефакторинг базы данных для преобразования ваших свойств JSON в обычные поля не может быть учтен в текущем расписании разработки, вы можетесделайте так, чтобы ваши свойства JSON рассматривались как «обычные поля», создав индекс для этих свойств.
Создайте индекс для четко определенных данных, к этим четко определенным данным обычно обращаются и / или они всегда присутствуют в ваших данных JSON, большинство этих четко определенных данных можно найти в GROUPПредложения BY или WHERE.
К счастью, Postgres может создать индекс для выражения, это означает, что вы также можете создать индекс для выражения JSON (например, itemdata->>'itemId'
).Если вы использовали другие СУБД, которые не могут создать индекс для выражения, вы просто нарисовали себя в углу, поскольку планы выполнения для запросов, использующих JSON, всегда будут разрешать последовательное сканирование таблицы вместо сканирования индекса.
По-прежнему целесообразно использовать обычные поля для данных вместо свойств JSON, если эти данные четко определены и регулярно используются.При рефакторинге дизайна вашей базы данных в соответствии с графиком разработки необходимо преобразовать эти поля JSON в обычные поля позже.
Чтобы перейти к следующему этапу, приведем подтверждение концепции, показывающее, что ваш запрос, включающий JSON, все еще можетВоспользуйтесь производительностью, связанной с обычными полями, создав индекс для регулярно используемых свойств JSON.
create table tbl
(
id int generated by default as identity primary key,
-- on older version of Postgres, use this instead:
-- id serial primary key
document jsonb not null
);
create index ix_tbl__document_code on tbl(((document->>'code')::int));
insert into tbl(document)
select
jsonb_build_object
('name', 'Slim',
'nick', 'Shady',
'category', 'Musician',
'ack', x.i,
'code', x.i
)
from generate_series(1,500000) as x(i)
Вот план выполнения при наличии индекса для выражения (document->>'code')::int
:
explain analyze
select * from tbl
where (document->>'code')::int = 42;
Вывод:
Вот план выполнения, если для выражения не создан индекс:
explain analyze
select * from tbl
where (document->>'ack')::int = 42;
Вывод:
0,018 миллисекунд против 52,335 миллисекунд