PostgreSQL 中的无方向关系失败
Directionless relationship failing in PostgreSQL
我正在尝试在 PostgreSQL 中为我的 3 个对象创建双向关系 table。这个想法源于以下问题 https://dba.stackexchange.com/questions/48568/how-to-relate-two-rows-in-the-same-table 我也想在其中存储行之间的关系及其反转。
对于我的数据库中的上下文:对象 1 包含(也与许多对象相关)对象 2。反过来,这些 object2 也与许多 object3 相关。一对多关系(对象 1 到对象 2)和多对多关系(对象 2 到对象 3)
每个对象都在其他 table 中分配了一个 UUID,其中包含有关它们的信息。基于它们的 UUID,我希望能够查询它们并获取关联的对象 UUID。这反过来会向我展示关联,并通过知道 UUID 指导我应该查看哪个对象的位置、信息等。
请注意 - 一个盒子可能有 10 个插槽。因此,为盒子分配的一个 UUID 将出现在我的 UUID1 列中 10 次!!这是必须的!
我的下一步是尝试使用此查询创建无方向的关系:
CREATE TABLE bridge_x
(uuid1 UUID NOT NULL REFERENCES temp (uuid1), uuid2 UUID NOT NULL REFERENCES temp (uuid2),
PRIMARY KEY(uuid1, uuid2),
CONSTRAINT temp_temp_directionless
FOREIGN KEY (uuid2, uuid1)
REFERENCES bridge_x (uuid1, uuid2)
);
有没有其他方法可以存储所有提到的信息并能够查询 UUID 以查看对象之间的关系?
桥 table 中需要一个复合主键。一个例子,使用一夫多妻制的婚姻:
CREATE TABLE person
(person_id INTEGER NOT NULL PRIMARY KEY
, name varchar NOT NULL
);
CREATE TABLE marriage
( person1 INTEGER NOT NULL
, person2 INTEGER NOT NULL
, comment varchar
, CONSTRAINT marriage_1 FOREIGN KEY (person1) REFERENCES person(person_id)
, CONSTRAINT marriage_2 FOREIGN KEY (person2) REFERENCES person(person_id)
, CONSTRAINT order_in_court CHECK (person1 < person2)
, CONSTRAINT polygamy_allowed UNIQUE (person1,person2)
);
INSERT INTO person(person_id,name) values (1,'Bob'),(2,'Alice'),(3,'Charles');
INSERT INTO marriage(person1,person2, comment) VALUES(1,2, 'Crypto marriage!') ; -- Ok
INSERT INTO marriage(person1,person2, comment) VALUES(2,1, 'Not twice!' ) ; -- Should fail
INSERT INTO marriage(person1,person2, comment) VALUES(3,3, 'No you dont...' ) ; -- Should fail
INSERT INTO marriage(person1,person2, comment) VALUES(2,3, 'OMG she did it again.' ) ; -- Should fail (does not)
INSERT INTO marriage(person1,person2, comment) VALUES(3,4, 'Non existant persons are not allowed to marry !' ) ; -- Should fail
SELECT p1.name, p2.name, m.comment
FROM marriage m
JOIN person p1 ON m.person1 = p1.person_id
JOIN person p2 ON m.person2 = p2.person_id
;
结果:
CREATE TABLE
CREATE TABLE
INSERT 0 3
INSERT 0 1
ERROR: new row for relation "marriage" violates check constraint "order_in_court"
DETAIL: Failing row contains (2, 1, Not twice!).
ERROR: new row for relation "marriage" violates check constraint "order_in_court"
DETAIL: Failing row contains (3, 3, No you dont...).
INSERT 0 1
ERROR: insert or update on table "marriage" violates foreign key constraint "marriage_2"
DETAIL: Key (person2)=(4) is not present in table "person".
name | name | comment
-------+---------+-----------------------
Bob | Alice | Crypto marriage!
Alice | Charles | OMG she did it again.
(2 rows)
我正在尝试在 PostgreSQL 中为我的 3 个对象创建双向关系 table。这个想法源于以下问题 https://dba.stackexchange.com/questions/48568/how-to-relate-two-rows-in-the-same-table 我也想在其中存储行之间的关系及其反转。
对于我的数据库中的上下文:对象 1 包含(也与许多对象相关)对象 2。反过来,这些 object2 也与许多 object3 相关。一对多关系(对象 1 到对象 2)和多对多关系(对象 2 到对象 3)
每个对象都在其他 table 中分配了一个 UUID,其中包含有关它们的信息。基于它们的 UUID,我希望能够查询它们并获取关联的对象 UUID。这反过来会向我展示关联,并通过知道 UUID 指导我应该查看哪个对象的位置、信息等。
请注意 - 一个盒子可能有 10 个插槽。因此,为盒子分配的一个 UUID 将出现在我的 UUID1 列中 10 次!!这是必须的!
我的下一步是尝试使用此查询创建无方向的关系:
CREATE TABLE bridge_x
(uuid1 UUID NOT NULL REFERENCES temp (uuid1), uuid2 UUID NOT NULL REFERENCES temp (uuid2),
PRIMARY KEY(uuid1, uuid2),
CONSTRAINT temp_temp_directionless
FOREIGN KEY (uuid2, uuid1)
REFERENCES bridge_x (uuid1, uuid2)
);
有没有其他方法可以存储所有提到的信息并能够查询 UUID 以查看对象之间的关系?
桥 table 中需要一个复合主键。一个例子,使用一夫多妻制的婚姻:
CREATE TABLE person
(person_id INTEGER NOT NULL PRIMARY KEY
, name varchar NOT NULL
);
CREATE TABLE marriage
( person1 INTEGER NOT NULL
, person2 INTEGER NOT NULL
, comment varchar
, CONSTRAINT marriage_1 FOREIGN KEY (person1) REFERENCES person(person_id)
, CONSTRAINT marriage_2 FOREIGN KEY (person2) REFERENCES person(person_id)
, CONSTRAINT order_in_court CHECK (person1 < person2)
, CONSTRAINT polygamy_allowed UNIQUE (person1,person2)
);
INSERT INTO person(person_id,name) values (1,'Bob'),(2,'Alice'),(3,'Charles');
INSERT INTO marriage(person1,person2, comment) VALUES(1,2, 'Crypto marriage!') ; -- Ok
INSERT INTO marriage(person1,person2, comment) VALUES(2,1, 'Not twice!' ) ; -- Should fail
INSERT INTO marriage(person1,person2, comment) VALUES(3,3, 'No you dont...' ) ; -- Should fail
INSERT INTO marriage(person1,person2, comment) VALUES(2,3, 'OMG she did it again.' ) ; -- Should fail (does not)
INSERT INTO marriage(person1,person2, comment) VALUES(3,4, 'Non existant persons are not allowed to marry !' ) ; -- Should fail
SELECT p1.name, p2.name, m.comment
FROM marriage m
JOIN person p1 ON m.person1 = p1.person_id
JOIN person p2 ON m.person2 = p2.person_id
;
结果:
CREATE TABLE
CREATE TABLE
INSERT 0 3
INSERT 0 1
ERROR: new row for relation "marriage" violates check constraint "order_in_court"
DETAIL: Failing row contains (2, 1, Not twice!).
ERROR: new row for relation "marriage" violates check constraint "order_in_court"
DETAIL: Failing row contains (3, 3, No you dont...).
INSERT 0 1
ERROR: insert or update on table "marriage" violates foreign key constraint "marriage_2"
DETAIL: Key (person2)=(4) is not present in table "person".
name | name | comment
-------+---------+-----------------------
Bob | Alice | Crypto marriage!
Alice | Charles | OMG she did it again.
(2 rows)