我目前遇到类似的问题。我正在尝试创建一个表来存储有关父亲的信息。
假设所有父亲都有两个儿子,所有父亲将永远有两个孩子,不多也不少。
Father_Table
father_id | son1_id | son2_id | father_text_info
--------------------------------------------------------------
13 | 8 | 11 | "some info..."
Son_Table
son_id | name
----------------------------
8 | Moris
我没有简单地将Son_Table信息添加到Father_Table中,因为Son_Table还会与其他表进行交互。
我的问题是,我如何创建TABLE以确保如果在Father_Table上已经存在son1_id或son2_id,那么它就不能在Father_Table上输入?
我已经尝试了以下内容:
CREATE TABLE father_table (
father_id serial PRIMARY KEY,
son1_id integer NOT NULL,
son2_id integer NOT NULL,
FOREIGN KEY (son1_id) REFERENCES Son_Table (son_id),
FOREIGN KEY (son2_id) REFERENCES Son_Table (son_id),
UNIQUE (son1_id, son2_id),
UNIQUE (son2_id, son1_id),
UNIQUE (son1_id),
UNIQUE (son2_id)
)
但是仍然允许以下带有重复Son_Table Id的输入:
father_id | son1_id | son2_id | father_text_info
--------------------------------------------------------------
13 | 8 | 11 | "some info..."
--------------------------------------------------------------
14 | 11 | 8 | "other info..."
答案 0 :(得分:0)
评论是对的。正常就是答案。即使使用PostgreSQL的高级功能,如果不对表进行规范化(或使用触发器创建标准化跟踪),我也无法找到使这种方法变得简单的方法。
问题是你可以轻松挑出最小和最大儿子ID。但是,如果没有非常可怕的性能问题,您无法覆盖设置操作中的所有情况。
将father_to_son_id分解为单独的表,或者使用触发器维护这样的表。然后一个简单的独特索引就可以了。
答案 1 :(得分:0)
尽管我同意其他人son1_id
,son2_id
是糟糕的设计,但这是一个禁止重复的索引:
create extension intarray;
create unique index idx_two_sons on father_table (sort(ARRAY[son1_id, son2_id]));
如果将其与仅UNIQUE
上的son1_id
约束和son2_id
上的{{1}}约束相结合,它应该可以执行您想要的操作。