这个问题需要一些假设背景。让我们考虑一个 employee 表,它具有列 namedate_of_birthtitle 、 0x25184312 作为 MySQL 使用 1 、 0x25184312 。因为如果任何给定的人的姓名和出生日期与另一个人相同,那么根据定义,他们就是同一个人(除非我们有两个名叫亚伯拉罕·林肯的人出生于 1809 年 2 月 12 日的惊人巧合),我们将放置一个salaryname 上的唯一键,意思是“不要存储同一个人两次”。现在考虑这个数据:

id name        date_of_birth title          salary
 1 John Smith  1960-10-02    President      500,000
 2 Jane Doe    1982-05-05    Accountant      80,000
 3 Jim Johnson NULL          Office Manager  40,000
 4 Tim Smith   1899-04-11    Janitor         95,000

如果我现在尝试运行以下语句,它应该并且将会失败:
INSERT INTO employee (name, date_of_birth, title, salary)
VALUES ('Tim Smith', '1899-04-11', 'Janitor', '95,000')

如果我尝试这个,它会成功:
INSERT INTO employee (name, title, salary)
VALUES ('Jim Johnson', 'Office Manager', '40,000')

现在我的数据将如下所示:
id name        date_of_birth title          salary
 1 John Smith  1960-10-02    President      500,000
 2 Jane Doe    1982-05-05    Accountant      80,000
 3 Jim Johnson NULL          Office Manager  40,000
 4 Tim Smith   1899-04-11    Janitor         95,000
 5 Jim Johnson NULL          Office Manager  40,000

这不是我想要的,但我不能说我完全不同意发生的事情。如果我们谈论数学集合,
{'Tim Smith', '1899-04-11'} = {'Tim Smith', '1899-04-11'} <-- TRUE
{'Tim Smith', '1899-04-11'} = {'Jane Doe', '1982-05-05'} <-- FALSE
{'Tim Smith', '1899-04-11'} = {'Jim Johnson', NULL} <-- UNKNOWN
{'Jim Johnson', NULL} = {'Jim Johnson', NULL} <-- UNKNOWN

我的猜测是 MySQL 会说,“因为我不知道这个表中没有出生日期为 date_of_birth 的 Jim Johnson,我将添加他。”

我的问题是: 即使 NULL 并不总是已知,我如何防止重复? 到目前为止我想出的最好方法是将 date_of_birth 移动到不同的表。然而,这样做的问题是,我可能最终会遇到两个具有相同姓名、头衔和薪水、不同出生日期的收银员,并且无法在没有重复的情况下存储它们。

最佳答案

唯一键 的基本属性是
它必须是唯一的。使该键成为 Nullable 的一部分会破坏此属性。

您的问题有两种可能的解决方案:

  • 一种错误的方法是使用一些魔法日期来表示未知。这只是让你过去
    DBMS“问题”,但没有解决逻辑意义上的问题。
    预计日期未知的两个“约翰史密斯”条目会出现问题
    出生的。这些人是同一个人还是独一无二的个体?
    如果你知道它们是不同的,那么你又回到了同样的老问题——
    您的唯一键不是唯一的。甚至不要考虑分配整个范围的魔法日期
    代表“未知”——这才是真正的 hell 之路。
  • 更好的方法是创建 EmployeeId 属性作为代理键。这只是一个
    您分配给您 知道的个人的任意标识符 是唯一的。这
    标识符通常只是一个整数值。
    然后创建一个 Employee 表来关联 EmployeeId(唯一的,不可为空的
    关键)你认为是依赖属性的,在这种情况下
    姓名和出生日期(其中任何一项都可以为空)。在任何地方使用 EmployeeId 代理键
    以前使用姓名/出生日期。这会向您的系统添加一个新表,但是
    以稳健的方式解决未知值的问题。
  • 关于mysql - 具有 NULL 的唯一键,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4081783/

    10-16 07:37