MySQL 主键是否需要“NOT NULL”约束?

MySQL 主键是否需要“NOT NULL”约束?

MySQL 中,主键是非常重要的概念。它描述了表中的一列,其值唯一并用于标识表中的每行数据。这是一个常见的数据库概念,每个 DBMS 都有自己的实现方式。本文将探讨 MySQL 中主键约束的一个争议问题:是否需要将主键列设置为“NOT NULL”?

阅读更多:MySQL 教程

主键约束

在 MySQL 中,主键定义用于标识每行数据并确保其唯一性。主键列不能包含 NULL 值,否则该行数据将无法标识并违反唯一性约束,因为 NULL 不等于任何值。在表定义中,可以指定主键使用 PRIMARY KEY 约束。例如:

CREATE TABLE employees (
  id INT PRIMARY KEY,
  name VARCHAR(50)
);
SQL

在上面的示例中,id 列定义为主键。MySQL 明确要求主键列设置为“NOT NULL”,因此如果使用以下方式创建表,则会引发错误:

CREATE TABLE employees (
  id INT PRIMARY KEY NULL,
  name VARCHAR(50)
);
SQL

因为 NULL 值不满足主键的唯一性约束。

主键的目的

主键的目的是为了快速搜索和定位表中的行。如果主键列不唯一,则查询将返回多个行,需要在结果中查找特定行(如果存在)。如果主键列可以为 NULL,则无法将每行数据标识为唯一值。

例如,假设我们有一个名为 customers 的表,其中包含数据如下:

id name email
1 John Smith john@example.com
2 Jane Doe jane@example.com
3 Joe Bloggs joe@example.com
4 NULL jane@example.com
5 NULL joe@example.com

如果我们想查找 email 为 “jane@example.com” 的客户,我们可能会使用以下查询语句:

SELECT * FROM customers WHERE email = 'jane@example.com';
SQL

此查询将返回两个行:id 为 2 和 4 的行。但是我们真正想要的是 id 为 2 的行。如果 id 列定义为主键,则查询仅返回匹配的行(id 为 2)。

CREATE TABLE customers (
  id INT PRIMARY KEY,
  name VARCHAR(50),
  email VARCHAR(100)
);
SQL

NOT NULL 与主键

由于主键已经自动要求不包含 NULL 值,因此将列定义为“NOT NULL”似乎没有必要。在某些情况下,让主键列接受 NULL 值可能会更有意义。

例如,在订单表中,我们可能有以下列:

  • order_id:订单 ID,主键。
  • customer_id:关联的客户 ID。
  • created_at:订单创建时间。
  • updated_at:订单更新时间。
  • deleted_at:订单删除时间。如果订单未删除,则为空。

在这种情况下,让 order_id 列接受 NULL 值是有意义的,因为我们可能需要注册一个 “不存在” 的订单(即订单未创建)。此外,如果该订单已被删除,则 order_id 仍为 NULL,即使它以前有值。

因此,这种情况下的表定义将如下所示:

CREATE TABLE orders (
  order_id INT UNSIGNED NULL PRIMARY KEY,
  customer_id INT UNSIGNED NOT NULL,
  created_at TIMESTAMP NOT NULL,
  updated_at TIMESTAMP NOT NULL,
  deleted_at TIMESTAMP NULL
);
SQL

在上面的示例中,让 order_id 列接受 NULL 值允许我们轻松地表示订单的创建和删除状态。

但是,让主键列接受 NULL 值有一些副作用。例如,如果我们运行以下命令:

SELECT * FROM orders如果我们运行以下命令:

```sql
SELECT * FROM orders
WHERE order_id IS NULL;
SQL

该查询将返回所有未创建的订单行。但是,由于我们使用了 order_id 列作为主键,这种情况将永远不会发生。因此,如果我们要运行此查询,则需要使用其他列作为主键,并将 order_id 列设置为只接受非 NULL 值。

总之,是否需要让主键列接受 NULL 值取决于业务需求。如果唯一标识每行数据的主键不能接受 NULL 值,则应将其定义为“NOT NULL”。否则,如果列可以接受 NULL 值并且有意义,则应该让它们接受 NULL 值。

总结

MySQL 中的主键指定了表中唯一标识每行数据的列。默认情况下,MySQL 要求主键列不接受 NULL 值。但是,在某些情况下,让主键列接受 NULL 值可能是有意义的,这取决于业务需求。在这种情况下,最好使用其他列作为主键,并将允许接受 NULL 值的列设置为“NOT NULL”。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程

登录

注册