我认为答案是错误的,因为外键没有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
。有什么用?
答案 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
表,id
,name
,age
和parent_id
,其中parent_id
是外键,同桌。您不需要将Person
表格标准化为Parent
和Child
表格,这些都是过度的。
Person
| id | name | age | parent_id |
|----|-------|-----|-----------|
| 1 | Tom | 50 | null |
| 2 | Billy | 15 | 1 |
像这样。
我想要保持一致性,但 parent_id
需要至少有1个空值。一个“阿尔法男性”行。
CASCADE ON UPDATE
,它也不会正确地传播编辑。虽然主键(通常)禁止在生产中进行编辑,但它仍然是一个不容忽视的限制。因此,我将答案改为: - 你应该避免这种做法,除非你对生产系统有非常严格的控制(并且可以保证没有人会实现编辑PK的控制)。我没有在MySQL之外测试它。
答案 2 :(得分:6)
答案 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 值)来表示不相关的含义:此投标只能以其全部价值使用。
流行的关系数据库管理系统可以顺利支持这个用例。
外卖:
插入记录时,外键引用被验证为在插入之后,而不是在插入之前。
当用一条语句插入多条记录时,插入记录的顺序很重要。单独检查每个记录的约束。
某些其他数据模式,例如那些涉及遍历两个或多个表的记录级别的循环依赖的数据模式,根本不能完全插入,或者至少不能在启用所有外键的情况下插入,并且它们必须是使用插入和更新的组合(如果确实有必要)建立。