Postgres - операции CRUD с массивами составных типов - PullRequest
0 голосов
/ 19 января 2020

Одна действительно замечательная особенность Postgres, которую я только что обнаружил, - это возможность определить composite type - также упоминаемый в их документах как ROWS и как RECORDS. Рассмотрим следующий пример

CREATE TYPE dow_id AS
(
 tslot smallint,
 day smallint
);

Теперь рассмотрим следующие таблицы

CREATE SEQUENCE test_id_seq INCREMENT 1 MINVALUE 1 MAXVALUE 2147483647 START 1 CACHE 1;

CREATE TABLE test_simple_array 
(
 id integer DEFAULT nextval('test_id_seq') NOT NULL,
 dx  integer []
);

CREATE TABLE test_composite_simple 
(
 id integer DEFAULT nextval('test_id_seq') NOT NULL,
 dx  dow_id
);

CREATE TABLE test_composite_array 
(
 id integer DEFAULT nextval('test_id_seq') NOT NULL,
 dx  dow_id[]
);

Операции CRUD в первых двух таблицах относительно просты. Например,

INSERT INTO test_simple_array (dx) VALUES ('{1,1}');
INSERT INTO test_composite_simple (dx) VALUES (ROW(1,1));

Однако я не смог выяснить, как выполнять операции CRUD, когда таблица имеет array of records/composite types, как в test_composite_array. Я попытался

INSERT INTO test_composite_array (dx) VALUES(ARRAY(ROW(1,1),ROW(1,2)));

, который завершается с сообщением

ОШИБКА: синтаксическая ошибка в или около "ROW"

и

INSERT INTO test_composite_array (dx) VALUES("{(1,1),(1,2)}");

, который завершается с сообщением

ОШИБКА: столбец "{(1,1), (1,2)}" не существует

и

INSERT INTO test_composite_array (dx) VALUES('{"(1,1)","(1,2)"}');

, который, кажется, работает, хотя и оставляет меня в замешательстве, так как последующий

SELECT dx FROM test_composite_array

возвращает то, что представляется строковым результатом {"(1,1),(1,2)}, хотя работает следующий запрос, например

SELECT id FROM test_composite_array WHERE (dx[1]).tslot = 1;

. Я также попробовал следующее

SELECT (dx[1]).day FROM test_composite_array;
UPDATE test_composite_array SET dx[1].day = 99 WHERE (dx[1]).tslot = 1;
SELECT (dx[1]).day FROM test_composite_array;

, которое работает, пока

 UPDATE test_composite_array SET (dx[1]).day = 99 WHERE (dx[1]).tslot = 1;

не удается. Я обнаружил, что выясняю, как манипулировать массивами записей / составных типов в Postgres методом проб и ошибок, и - хотя документация Postgres в целом превосходна - похоже, что нет ясного обсуждения этой топи c в документация. Я был бы очень признателен всем, кто может указать мне на авторитетную дискуссию о том, как манипулировать массивами составных типов в Postgres.

Что кроме непредвиденных ошибок при работе с такими массивами?

1 Ответ

1 голос
/ 20 января 2020

Вам нужны квадратные скобки с ARRAY:

ARRAY[ROW(1,1)::dow_id,ROW(1,2)::dow_id]

Предупреждение: составные типы - отличная особенность, но вы усложните свою жизнь, если будете чрезмерно их использовать. Как только вы захотите использовать элементы составного типа в условиях WHERE или JOIN, вы делаете что-то не так, и вы будете страдать. Есть веские причины для нормализации реляционных данных.

...