Исправить JSON ключей в PostgreSQL - PullRequest
0 голосов
/ 17 июня 2020

Я хочу исправить или проверить ключи для объекта JSON в PostgreSQL (v10.7).

Например, у меня есть объект JSON с именем service_config , который выглядит так;

{"con_type": "Foo", "capacity": 2, "capacity_unit": "gbps"}

И у меня есть таблица:

 id(serial)   service_name(char)   service_type(char)    service_config(JSON)
-----------+---------------------+---------------------+---------------------
    1      |          com        |        ethernet     | {"con_type": "ddc", "capacity": 2, "capacity_unit": "gbps"}
    2      |          res        |        gpon         | {"con_type": "ftth", "capacity": 1, "capacity_unit": "gbps"} 

Теперь, когда я вставляю строку в таблицу, я хочу убедиться или подтвердить, что столбец service_config содержит все ключи, упомянутые выше, ни больше, ни меньше. Однако для ключей может быть нулевое значение.

Возможно ли это в Postgres и / или есть лучший способ сделать это?

Возможные решения :

1- Проверьте service_config на внутреннем API и убедитесь, что все ключи там. (в настоящее время на месте и работает)

2- Напишите функцию в Postgres для проверки service_config при вставке и обновлении. (выполнимо, но утомительно)

Ограничение : я не могу добавить какое-либо расширение в Postgres.

1 Ответ

0 голосов
/ 17 июня 2020

Я хочу убедиться или проверить, что столбец service_config содержит все ключи, упомянутые выше, ни больше, ни меньше. Однако для ключей может быть нулевое значение.

Превратите их в столбцы.

JSON хорошо, когда вам нужно просто выгрузить некоторые данные в строку, а вы ' я не уверен, что это будет. Теперь, когда вы уверены, что это будет, и хотите больше ограничений, лучше всего подходят столбцы.

alter table whatever add column con_type text;
alter table whatever add column capacity integer;
alter table whatever add column capacity_unit text;

update whatever set
  con_type = data->'con_type',
  capacity = data->'capacity',
  capacity_unit = data->'capacity_unit';

alter table whatever drop column data

Столбцы всегда будут там. Их значения могут быть нулевыми. Вы можете добавить check ограничений и индексов для каждого столбца. Никаких дополнительных проверок не требуется.

Если вам все еще нужно json, используйте jsonb_build_object.

select
  jsonb_build_object(
    'con_type', con_type,
    'capacity', capacity,
    'capacity_unit', capacity_unit
  )
from whatever;

И, если вам это нужно для совместимости, вы можете сделать это представлением.

create view whatever_as_json
select
  *,
  jsonb_build_object(
    'con_type', con_type,
    'capacity', capacity,
    'capacity_unit', capacity_unit
  ) as data
from whatever;

Обратите внимание, что я использую text, а не char, потому что у char в Postgres нет преимущества. См. Подсказку в 8.3. Типы символов

Между этими тремя типами нет разницы в производительности, за исключением увеличенного места для хранения при использовании типа с заполнением пробелами и нескольких дополнительных циклов ЦП для проверки длины при сохранении в столбец с ограниченной длиной. Хотя у символа (n) есть преимущества в производительности в некоторых других системах баз данных, в PostgreSQL такого преимущества нет; Фактически, character (n) обычно самый медленный из трех из-за дополнительных затрат на хранение. В большинстве случаев вместо этого следует использовать изменение текста или символов.

...