3

我有两张桌子,一张“主”表和一张“子”表。每个表都有一个名为“ProductNo”的字段,该字段定义为 PRIMARY KEY 和 UNIQUE。是否可以将表'child'中的字段'ProductNo'和表'master'中的相同字段定义为PRIMARY + UNIQUE?

master:
ID | ProductNo

child:
ID | MasterID (FK on master.ID) | ProductNo

Relation >> 1 (master) : n (child) 


example data:
master: 
1 | 1234
2 | 4567

child:
100 | 1 | 3333
101 | 1 | 4444
102 | 2 | 5555
103 | 1 | 1234 <----- NOT ALLOWED! PRODUCT NO ALREADY EXISTING IN TABLE `MASTER`
104 | 2 | 1234 <----- NOT ALLOWED! PRODUCT NO ALREADY EXISTING IN TABLE `MASTER`

如果表“master”中已经存在“ProductNo”,则需要检查插入/更新表“child”。

我该如何定义它?还是我需要为此创建触发器?

TIA 马特

4

5 回答 5

4

不,表之间没有复合 PK 之类的东西。

只是为了数据的一致性,如果 Id 相同,则应从 child 向 master 添加一个 FK。

要解决您的问题,请使用带有如下检查的触发器:

if exists (select 1 from master where prodcutId=new_productId)

会是个好主意

编辑:

实际上最好的想法是只有一个名为 product 的表,它有一个 ID 和一个与自身相关的 masterID 字段。你今天的方式我很确定你有很多重复的数据,并且你在层次结构上被困在 2 个级别。

于 2012-04-27T09:39:32.317 回答
2

(原始答案)您可以声明从主到子的外键,即使该外键指向子的主键。这将是一对零或一的关系,并且并不少见。如果没有在 master 中插入匹配的行,则无法在 child 中存在行,但在 master 中可以存在没有匹配子行的行。因此,您的插入需要按照主然后子的顺序进行。

(根据问题编辑进行编辑)但是,在您的情况下,您所指的列看起来实际上不应该是一表的主键,而是您有一个单独的主键/外键,以及有问题的列需要在两个表中是唯一的,现在您已经将一些示例数据编辑到您的问题中,这一点变得很清楚。在这种情况下,您最好在两个表上都使用触发器,以检查另一个表中是否存在,如果 ProductNo 已经存在,则阻止插入/更新。

于 2012-04-27T09:35:40.663 回答
1

正如@DavidM 所说,可以做到,但您似乎遇到了一些建模问题。首先,如果你有一个自然的主键ProductNo,你为什么要定义一个代理ID?您可能会考虑的另一件事是将这两个表组合成一个表(这对于大多数一对一的情况可能是有意义的)。

于 2012-04-27T10:04:20.110 回答
1

你确定你需要这两张桌子吗?只保留一个,具有 productID 和 parentID。然后 productID 可以是主键并自动递增,而具有除 null 以外的 parentID 的所有内容(f.keyed 到同一个表)都将是子项。

于 2012-04-27T11:26:26.577 回答
0

您可以在子表中添加名为 ProductNo 的列,并向父表添加外键引用。

于 2012-04-27T09:36:20.230 回答