在MySQL中创建一对一的关系

时间:2013-01-12 11:15:39

标签: mysql mysql-workbench

这是以MySQL中的一对一关系的方式链接两个表的正确代码吗?

Table1

CREATE TABLE employees (id INT PRIMARY KEY AUTO_INCREMENT,FullName VARCHAR(50))

Table2

CREATE TABLE salary (id INT PRIMARY KEY AUTO_INCREMENT,SalaryNumber VARCHAR(6))

ALTER TABLE salary
ADD FOREIGN KEY (id) REFERENCES employees (id)
ON DELETE CASCADE
ON UPDATE CASCADE

2 个答案:

答案 0 :(得分:4)

您的示例存在许多问题,首先是您要链接两个不相关的自动递增ID。这是一场等待发生的噩梦。如果发生任何事情导致这两个ID不同步,那么你就死在了水中。

在您的示例中,“员工”记录将被视为父记录,“薪资”记录依赖于该记录(即 - 您可能拥有没有相应薪资记录的员工记录,但您不希望与员工无关的工资记录。

外键约束属于子表,如MySql文档中所述。因此,“薪水”表中您需要的是一个如下所示的列:

EmployeeId INT NOT NULL

你的外键是

ALTER TABLE薪水 ADD FOREIGN KEY(EmployeeId)REFERENCES员工(id) ON DELETE CASCADE ON UPDATE CASCADE

此时,您仍然具有多对一关系,因为没有什么可以阻止您使用相同的EmployeeId将多个条目插入到工资表中。

要使这种关系一对一,您必须在salary.EmployeeId列上创建唯一索引。

有了这种关系,重要的是要注意:

  1. 您无法在没有有效EmployeeId的工资中插入行
  2. 您无法在具有重复的EmployeeId
  3. 的薪水中插入行
  4. 删除工资记录时,员工记录保持不变。
  5. 删除员工记录会导致删除它引用的工资记录(如果您不想要这种行为,请将ON DELETE CASCADE更改为其他内容)
  6. 在工资表为空并丢弃之前,您无法删除员工表。

答案 1 :(得分:0)

不,那是一对多的关系。您可以将任意数量的工资行(包括无)链接到单个员工行。

由于薪水非常依赖于员工的属性,我会考虑将其放在员工表中(除非你有一些额外的知识,你没有与我们分享这使得这个有问题的)。


方法可以跨越不同的表强制执行一对一。

例如,你可以使用触发器来阻止重复,虽然有些人对触发器不利,但这仍然不会阻止出现一对零的映射。

或者,您可以在两个表中使用带有虚拟行的双向外键(彼此指向),以允许您一次插入一个表中。

这样做的方法是在指向虚拟工资行的员工中插入一行。

然后插入指向新插入员工的工资行。

然后将employee行更新为pint到新插入的工资行。当然,所有这些都应该作为单个事务发生,以保持应用程序级别的引用完整性。

为了获取虚拟行,在将外键约束添加到模式之前,需要将它们插入,否则就会出现鸡与蛋的情况。

这项工作水平是否真正必要是值得商榷的,特别是当您可以简单地通过将数据组合成单个表时强制执行一对一建议: - )