Postgres - 复合类型数组的 CRUD 操作
Postgres - CRUD operations with arrays of composite types
我刚刚发现的 Postgres 的一个非常巧妙的功能是能够定义 composite type
- 在他们的文档中也称为 ROWS
和 RECORDS
。考虑以下示例
CREATE TYPE dow_id AS
(
tslot smallint,
day smallint
);
现在考虑以下tables
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[]
);
前两个 table 的 CRUD 操作相对简单。例如
INSERT INTO test_simple_array (dx) VALUES ('{1,1}');
INSERT INTO test_composite_simple (dx) VALUES (ROW(1,1));
但是,当 table 有一个 array of records/composite types
时,我无法弄清楚如何执行 CRUD 操作,如 test_composite_array
。我试过了
INSERT INTO test_composite_array (dx) VALUES(ARRAY(ROW(1,1),ROW(1,2)));
失败并显示消息
ERROR: syntax error at or near "ROW"
和
INSERT INTO test_composite_array (dx) VALUES("{(1,1),(1,2)}");
失败并显示消息
ERROR: column "{(1,1),(1,2)}" does not exist
和
INSERT INTO test_composite_array (dx) VALUES('{"(1,1)","(1,2)"}');
这似乎有效,但它让我感到困惑,因为随后
SELECT dx 来自 test_composite_array
returns 似乎是一个字符串结果 {"(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 中操作 records/composite 类型的数组 - 尽管 Postgres 文档通常非常出色 - 文档中似乎没有明确讨论这个主题。如果有人能给我指点有关如何在 Postgres 中操作复合类型数组的权威讨论,我将不胜感激。
除此之外,在使用此类数组时是否有任何意想不到的问题?
你需要方括号 ARRAY
:
ARRAY[ROW(1,1)::dow_id,ROW(1,2)::dow_id]
警告:复合类型是一个很棒的特性,但如果过度使用它们会让你的生活更加艰难。一旦你想在 WHERE
或 JOIN
条件下使用复合类型的元素,你就做错了,你会吃亏的。规范化关系数据是有充分理由的。
我刚刚发现的 Postgres 的一个非常巧妙的功能是能够定义 composite type
- 在他们的文档中也称为 ROWS
和 RECORDS
。考虑以下示例
CREATE TYPE dow_id AS
(
tslot smallint,
day smallint
);
现在考虑以下tables
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[]
);
前两个 table 的 CRUD 操作相对简单。例如
INSERT INTO test_simple_array (dx) VALUES ('{1,1}');
INSERT INTO test_composite_simple (dx) VALUES (ROW(1,1));
但是,当 table 有一个 array of records/composite types
时,我无法弄清楚如何执行 CRUD 操作,如 test_composite_array
。我试过了
INSERT INTO test_composite_array (dx) VALUES(ARRAY(ROW(1,1),ROW(1,2)));
失败并显示消息
ERROR: syntax error at or near "ROW"
和
INSERT INTO test_composite_array (dx) VALUES("{(1,1),(1,2)}");
失败并显示消息
ERROR: column "{(1,1),(1,2)}" does not exist
和
INSERT INTO test_composite_array (dx) VALUES('{"(1,1)","(1,2)"}');
这似乎有效,但它让我感到困惑,因为随后
SELECT dx 来自 test_composite_array
returns 似乎是一个字符串结果 {"(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 中操作 records/composite 类型的数组 - 尽管 Postgres 文档通常非常出色 - 文档中似乎没有明确讨论这个主题。如果有人能给我指点有关如何在 Postgres 中操作复合类型数组的权威讨论,我将不胜感激。
除此之外,在使用此类数组时是否有任何意想不到的问题?
你需要方括号 ARRAY
:
ARRAY[ROW(1,1)::dow_id,ROW(1,2)::dow_id]
警告:复合类型是一个很棒的特性,但如果过度使用它们会让你的生活更加艰难。一旦你想在 WHERE
或 JOIN
条件下使用复合类型的元素,你就做错了,你会吃亏的。规范化关系数据是有充分理由的。