在 PostgreSQL 中创建双向关系 table

Creating a 2-way relationship in PostgreSQL table

我有 3 个 table 代表房子、房间和抽屉的 UUID、名称、位置和信息(这是一个示例,因为我的工作很敏感)。

因此,例如 1 所房子将有多个房间(一对多),而多个房间将包含多个抽屉(多对多)。

这个想法是,将创建一个关联 table,其中 table 中行的每个 UUID 将与另一个 table 中相应的 UUID 相关联。 例如,如果我查询 ID1 代表的房子,它将 return 以下内容:

SELECT * FROM house where 'ID_1='1';

| ID_1|ID_2  |
| ----| -----|
| 1   | 201  |
| 1   | 254  |
| 1   | 268  |

到目前为止,我已经创建了关联 table 的临时版本,说明我需要它如何在真实 table 中表示。但是,现在我需要一个函数来自动为从临时关联 table 到真实关联 table 的所有行正确填写 ID。例如:

INSERT INTO associations (id_1, id_2) VALUES
('1','201'),
('201','1')

我需要它是无方向的,这样当我查询 id_1 我也会在结果 id_2 中得到它的链接

假设您要获得单向关系的查询如下所示:

SELECT room_uuid AS left_uuid, house_the_room_is_in_uuid AS right_uuid
FROM rooms
WHERE house_the_room_is_in_uuid IS NOT NULL
AND is_active

要获得反向关系,只需将列表按其他顺序排列即可;查询的其余部分不需要更改,无论它多么复杂:

SELECT house_the_room_is_in_uuid AS left_uuid, room_uuid AS right_uuid
FROM rooms
WHERE house_the_room_is_in_uuid IS NOT NULL
AND is_active

这两个都将作为插入到具有两个 UUID 列的 table 中的查询有效:

CREATE TABLE my_lookup_table (left_uuid UUID, right_uuid UUID);

INSERT INTO my_lookup_table (left_uuid, right_uuid)
SELECT ... -- either of the above

要合并它们,请依次将每个插入相同的 table,或者使用 UNION 创建一个包含两组行的结果集:

SELECT room_uuid AS left_uuid, house_the_room_is_in_uuid AS right_uuid
FROM rooms
WHERE is_in_house_uuid IS NOT NULL
AND is_active

UNION

SELECT house_the_room_is_in_uuid AS left_uuid, room_uuid AS right_uuid
FROM rooms
WHERE is_in_house_uuid IS NOT NULL
AND is_active

联合所需的全部是查询具有相同数量和类型的列。名称(如果相关的话)来自第一个查询,但我发现如果您在两者中都包含别名,则它更具可读性。

因为 UNION 的结果本身只是一个两列的结果集,所以它可以像以前一样与相同的 INSERT 语句一起使用。这将允许您插入到 table 中,即使它有 a self-referencing foreign key constraint as discussed here:

ALTER TABLE my_lookup_table ADD CONSTRAINT 
    my_lookup_table_combinations_must_be_unique
    UNIQUE (left_uuid, right_uuid);

ALTER TABLE my_lookup_table ADD CONSTRAINT 
    my_lookup_table_must_have_rows_both_ways_around
    FOREIGN KEY (right_uuid, left_uuid)
    REFERENCES my_lookup_table (left_uuid, right_uuid);

如果您尝试仅插入一组行,这会失败,但是对于 UNION,在 statement/transaction 的末尾,每一行都在 table双向,所以约束得到满足。