外键是否可以引用同一个表中的主键?

时间:2013-09-08 05:20:46

标签: sql foreign-keys primary-key

我认为答案是错误的,因为外键没有uniqueness属性。

但是有些人说可以在自己加入桌子的情况下。 我是SQL的新手。如果是真的请解释如何以及为什么?

Employee table
| e_id | e_name  | e_sala  |  d_id  |
|----  |-------  |-----    |--------|
|  1   |   Tom   |  50K    |    A   |
|  2   | Billy   |  15K    |    A   |
|  3   | Bucky   |  15K    |    B   |


department table
| d_id | d_name  |
|----  |-------  |
|  A   |   XXX   | 
|  B   |   YYY   | 

现在,d_id是外键,所以它如何成为主键。并解释一下join。有什么用?

6 个答案:

答案 0 :(得分:63)

我认为这个问题有点令人困惑。

如果你的意思是“外键可以在同一张桌子上引用'主键吗?”,答案肯定是肯定的,因为有人回复了。例如,在员工表中,员工的行可能有一列用于存储经理的员工编号,其中经理也是员工,因此在表中会有一行,就像任何其他员工的一行一样。

如果你的意思是“可以列(或列集)是主键还是同一个表中的外键?”,在我看来,答案是否定的;这看起来毫无意义。但是,以下定义在SQL Server中成功!

create table t1(c1 int not null primary key foreign key references t1(c1))

但我认为除非有人提出一个实际的例子,否则有这样一个约束是毫无意义的。

AmanS,在您的示例中,d_id在任何情况下都不能成为Employee表中的主键。一个表只能有一个主键。我希望这能清除你的怀疑。 d_id是/可以是仅在department表中的主键。

答案 1 :(得分:16)

当然,为什么不呢?假设您有Person表,idnameageparent_id,其中parent_id是外键,同桌。您不需要将Person表格标准化为ParentChild表格,这些都是过度的。

Person
| id |  name | age | parent_id |
|----|-------|-----|-----------|
|  1 |   Tom |  50 |      null |
|  2 | Billy |  15 |         1 |

像这样。

我想要保持一致性,但parent_id需要至少有1个空值。一个“阿尔法男性”行。

编辑:正如评论所示,Sam找到了一个不这样做的好理由。在MySQL中,当您尝试对主键进行编辑时,即使您指定CASCADE ON UPDATE,它也不会正确地传播编辑。虽然主键(通常)禁止在生产中进行编辑,但它仍然是一个不容忽视的限制。因此,我将答案改为: - 你应该避免这种做法,除非你对生产系统有非常严格的控制(并且可以保证没有人会实现编辑PK的控制)。我没有在MySQL之外测试它。

答案 2 :(得分:6)

例如:n类别的子类别.Below表主键 id 由外键 sub_category_id

引用

enter image description here

答案 3 :(得分:1)

在同一个表中使用其他行的ID作为外键的一个很好的例子是嵌套列表。

删除具有子项的行(即,引用父项id的行),也有子项(即引用子项ID)将删除一连串行。

这将节省很多痛苦(以及许多与孤儿有关的代码 - 即涉及不存在的ID的行)。

答案 4 :(得分:0)

这可能是一个很好的解释示例

CREATE TABLE employees (
id INTEGER NOT NULL PRIMARY KEY,
managerId INTEGER REFERENCES employees(id), 
name VARCHAR(30) NOT NULL
);

INSERT INTO employees(id, managerId, name) VALUES(1, NULL, 'John');
INSERT INTO employees(id, managerId, name) VALUES(2, 1, 'Mike');

-说明: -在这个例子中。 约翰是麦克的经理。迈克没有管理任何人。 -Mike是唯一不管理任何人的员工。

答案 5 :(得分:0)

其他答案已经给出了足够清晰的示例,说明一条记录引用了同一表中的另一条记录。

在同一个表中引用本身的记录甚至有有效的用例。例如,当付款不是销售的确切价值时,接受许多投标的销售点系统可能需要知道使用哪个投标进行找零。多份同一份标书,另一些为国内现金,另一些标书,不得有任何形式的变更。

所有这一切都可以用一个单一的属性来优雅地表示,该属性是一个引用同一表主键的外键,其值有时与同一记录的相应主键匹配。在此示例中,可能需要缺少值(也称为 NULL 值)来表示不相关的含义:此投标只能以其全部价值使用。

流行的关系数据库管理系统可以顺利支持这个用例。

外卖:

  1. 插入记录时,外键引用被验证为在插入之后,而不是在插入之前

  2. 当用一条语句插入多条记录时,插入记录的顺序很重要。单独检查每个记录的约束。

  3. 某些其他数据模式,例如那些涉及遍历两个或多个表的记录级别的循环依赖的数据模式,根本不能完全插入,或者至少不能在启用所有外键的情况下插入,并且它们必须是使用插入和更新的组合(如果确实有必要)建立。