2

这是以一对一关系的方式链接两个表的正确代码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
4

2 回答 2

4

您的示例有许多问题,首先是您正在链接两个不相关的自动递增 id。这是一场等待发生的噩梦。如果发生任何事情使这两个 id 不同步,那么您就死定了。

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

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

EmployeeIdINT 非空

你的外键是

ALTER TABLE 工资添加外键 (EmployeeId) REFERENCES 员工 (id) ON DELETE CASCADE ON UPDATE CASCADE

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

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

对于这种类型的关系,重要的是要注意:

  1. 您无法在没有有效 EmployeeId 的工资中插入一行
  2. 您无法在具有重复 EmployeeId 的工资中插入一行
  3. 当您删除工资记录时,员工记录保持不变。
  4. 删除员工记录会导致删除它所引用的工资记录(如果您不想要这种行为,请将 ON DELETE CASCADE 更改为其他内容)
  5. 在薪水表为空并被删除之前,您无法删除员工表。
于 2013-02-22T17:29:24.693 回答
0

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

由于薪水很大程度上取决于员工的属性,因此我会考虑将其放在员工表本身中(除非您有一些未与我们分享的额外知识,这会造成问题)。


多种方法可以在不同的表之间实施一对一。

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

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

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

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

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

为了获得虚拟行,需要在将外键约束添加到架构之前插入它们,否则您将面临先有鸡还是先有蛋的情况。

这种工作水平是否真的有必要是有争议的,特别是当您可以按照建议将数据组合到一个表中来执行一对一时:-)

于 2013-01-12T11:17:28.677 回答