Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database 如何在多个列之间实施唯一约束?_Database_Postgresql - Fatal编程技术网

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。
:(