Database 如何在多个列之间实施唯一约束?
我目前有一个类似的问题。我正在尝试创建一个表来存储有关父亲的信息 假设所有的父亲都有两个儿子,所有的父亲都会有两个孩子,不多也不少Database 如何在多个列之间实施唯一约束?,database,postgresql,Database,Postgresql,我目前有一个类似的问题。我正在尝试创建一个表来存储有关父亲的信息 假设所有的父亲都有两个儿子,所有的父亲都会有两个孩子,不多也不少 Father_Table father_id | son1_id | son2_id | father_text_info -------------------------------------------------------------- 13 | 8 | 11 |
Father_Table
father_id | son1_id | son2_id | father_text_info
--------------------------------------------------------------
13 | 8 | 11 | "some info..."
Son_Table
son_id | name
----------------------------
8 | Moris
我并没有简单地将子表信息添加到父表中,因为子表将与其他表交互
我的问题是,如果父表中已经存在son1\u id或son2\u id,如何创建表以确保不能在父表中输入它
我已经尝试了以下方法:
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_表Id的输入:
father_id | son1_id | son2_id | father_text_info
--------------------------------------------------------------
13 | 8 | 11 | "some info..."
--------------------------------------------------------------
14 | 11 | 8 | "other info..."
评论是正确的。正常化是答案。即使有了PostgreSQL的高级功能,我也无法找到一种不规范表(或创建一个带有触发器的规范化跟踪表)的方法来实现这一点 问题是您可以轻松地选择最小和最大子ID。但是,如果没有非常可怕的性能问题,就无法涵盖集合操作中的所有情况
可以将父子id作为单独的表进行拆分,也可以使用触发器维护这样的表。然后一个简单的唯一索引就可以了。评论是正确的。正常化是答案。即使有了PostgreSQL的高级功能,我也无法找到一种不规范表(或创建一个带有触发器的规范化跟踪表)的方法来实现这一点 问题是您可以轻松地选择最小和最大子ID。但是,如果没有非常可怕的性能问题,就无法涵盖集合操作中的所有情况
可以将父子id作为单独的表进行拆分,也可以使用触发器维护这样的表。然后一个简单的唯一索引就可以了。我同意这里的其他人的观点,
son1\u id
,son2\u id
是一个糟糕的设计,这里有一个禁止重复的索引:
create extension intarray;
create unique index idx_two_sons on father_table (sort(ARRAY[son1_id, son2_id]));
如果你把它与一个对son1\u id的约束和另一个对son2\u id的约束结合起来,它应该做你想做的事。正如我在这里同意的那样,
son1\u id
,son2\u id
是一个糟糕的设计,这里有一个禁止重复的索引:
create extension intarray;
create unique index idx_two_sons on father_table (sort(ARRAY[son1_id, son2_id]));
如果将其与仅对
son1\u id
的UNIQUE
约束和仅对son2\u id
的另一个约束相结合,它应该可以实现您想要的功能。首先,您的模式是错误的,并且是非规范化的。第二,如果一把枪对着你的头,你必须使用这个模式,那么使用触发器serial
就是PostgreSQL语法。请删除[mysql]标记。一个方法是颠倒逻辑,始终保留两行。互惠通常是这样的。我肯定有兴趣更好地理解我将如何/为什么正常化。我的想法是,假设关于父子关系的上述条件,在单个父亲和两个儿子之间存在一对一的关系(如果没有两个唯一的FK son_ID,将永远不会插入父子表行)。如果我必须更新关于特定儿子的信息,我只需更新son_表。如果我必须找到哪两个儿子属于一个父亲,我只需从父亲表中选择son1_Id,son2_Id,其中父亲Id=14。如果我删除sonid8,我也会从FatherTable中删除,其中s1_id=8或s2_id=8。如果我为父子创建一个包含父子id和相应的父子id的连接表,那么我就能够在父子id列上实现唯一的约束,这样就不会有两个父亲与同一个儿子相关。但不幸的是,这个表仍然允许我为一个给定的父亲id插入2个以上的子id。:(
首先,您的模式是错误的和非规范化的。其次,如果一把枪对着您的头,您必须使用该模式,那么使用触发器串行是PostgreSQL语法。请删除[mysql]标记。一个想法是颠倒逻辑,始终有两行。交互作用通常是这样。我肯定有兴趣更好地理解如何/为什么我会正常化。我的想法是,假设上述父子关系的条件,一个父亲和两个儿子之间存在一对一的关系(如果没有两个唯一的FK son_ID,将永远不会插入父表行)。如果我必须更新关于某个特定儿子的信息,我只需更新son_表。如果我必须找到哪两个儿子属于某个父亲,我只需从父_表中选择son1_Id,son2_Id,其中父_Id=14。如果我删除sonid8,我还将从父表中删除,其中s1_Id=8或s2_Id=8。如果我为父_Id=8创建连接表ich将保存父亲id和相应的儿子id,然后我可以在儿子id列上实现一个唯一的约束,这样就不会有两个父亲与同一个儿子相关。但不幸的是,该表仍然允许我为给定的父亲id插入两个以上的儿子id。:(