本章我们将介绍约束,约束放在列或表上。 它们限制了可以插入表中的数据。
我们有以下限制:
- 非空
- 唯一
- 主键
- 外键
- 枚举
- SET
其他数据库也具有 CHECK 约束,该约束为有效数据设置了条件。 MySQL 解析了这个约束,但是没有强制执行。
非空约束
具有NOT NULL
约束的列不能具有 NULL 值。
mysql> CREATE TABLE People(Id INTEGER, LastName TEXT NOT NULL,
-> FirstName TEXT NOT NULL, City VARCHAR(55));
Query OK, 0 rows affected (0.07 sec)
我们创建两个具有NOT NULL
约束的列。
mysql> INSERT INTO People VALUES(1, 'Hanks', 'Robert', 'New York');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO People VALUES(1, NULL, 'Marianne', 'Chicago');
ERROR 1048 (23000): Column 'LastName' cannot be null
第一个SELECT
语句执行成功,第二个失败。 SQL 错误说,LastName
列不能为空。
唯一约束
UNIQUE
约束确保所有数据在列中都是唯一的。
mysql> CREATE TABLE Brands(Id INTEGER, BrandName VARCHAR(30) UNIQUE);
Query OK, 0 rows affected (0.08 sec)
在这里,我们创建一个表Brands
。 BrandName
列设置为UNIQUE
。 不能有两个名称相同的品牌。
mysql> INSERT INTO Brands VALUES(1, 'Coca Cola');
Query OK, 1 row affected (0.03 sec)
mysql> INSERT INTO Brands VALUES(2, 'Pepsi');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO Brands VALUES(3, 'Pepsi');
ERROR 1062 (23000): Duplicate entry 'Pepsi' for key 'BrandName'
对于键“ BrandName”,我们收到一个 SQL 错误 Duplicate 项“ Pepsi”。 只能有一个百事可乐品牌。
注意,PRIMARY KEY
约束自动在其上定义了UNIQUE
约束。
主键
PRIMARY KEY
约束唯一地标识数据库表中的每个记录。 这是唯一键的特例。 主键不能为NULL
,唯一键可以为。 可以有更多UNIQUE
列,但是表中只有一个主键。 在设计数据库表时,主键很重要。 主键是唯一的 ID。 我们使用它们来引用表行。 在表之间创建关系时,主键成为其他表中的外键。
mysql> DROP TABLE Brands;
mysql> CREATE TABLE Brands(Id INTEGER PRIMARY KEY, BrandName VARCHAR(30) UNIQUE);
Brands
表的 Id 列成为主键。
mysql> DESCRIBE Brands;
+-----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| Id | int(11) | NO | PRI | NULL | |
| BrandName | varchar(30) | YES | UNI | NULL | |
+-----------+-------------+------+-----+---------+-------+
DESCRIBE
语句显示有关表中各列的信息。 我们可以看到 Id 列定义了PRIMARY KEY
,BrandName
设置了UNIQUE
约束。 在处理特定表时,主键用于唯一标识表中的行。 唯一键强制列中的所有数据都不重复。
外键
一个表中的FOREIGN KEY
指向另一表中的PRIMARY KEY
。 它是两个表之间的引用约束。 外键标识一个(引用)表中的一列或一组列,该列或表引用另一(引用)表中的一列或一组列。
我们将在两个表上显示此约束:Authors
和Books
。
mysql> CREATE TABLE Authors(AuthorId INTEGER PRIMARY KEY, Name VARCHAR(70))
-> type=InnoDB;
在这里,我们创建 Authors 表。 在 MySQL 中,引用表和被引用表必须是 InnoDB 或 BDB 存储引擎。 在 MyISAM 存储引擎中,将解析外键,但不会强制使用外键。
mysql> CREATE TABLE Books(BookId INTEGER PRIMARY KEY, Title VARCHAR(50),
-> AuthorId INTEGER, FOREIGN KEY(AuthorId) REFERENCES Authors(AuthorId))
-> type=InnoDB;
我们创建Books
表。 在这里,我们有一个AuthorId
列名,它用作外键。 它引用Authors
表的主键。
在我们的示例中,外键强制执行意味着什么? 我们无法使用Authors
本书中没有的AuthorId
在Books
表中插入一行。
ENUM
约束
ENUM
是一个字符串对象,其值是从允许值列表中选择的。 在创建表时,它们在列规范中显式枚举。
mysql> CREATE TABLE Shops(Id INTEGER, Name VARCHAR(55),
-> Quality ENUM('High', 'Average', 'Low'));
我们有一个Shops
表。 该表具有定义的Id
,Name
和Quality
列。 Quality
列是ENUM
。 它允许具有三个指定值之一:High
,Average
或Low
。
mysql> INSERT INTO Shops VALUES(1, 'Boneys', 'High');
mysql> INSERT INTO Shops VALUES(2, 'AC River', 'Average');
mysql> INSERT INTO Shops VALUES(3, 'AT 34', '**');
mysql> SELECT * FROM Shops;
+------+----------+---------+
| Id | Name | Quality |
+------+----------+---------+
| 1 | Boneys | High |
| 2 | AC River | Average |
| 3 | AT 34 | |
+------+----------+---------+
在前两个语句中,我们插入了两行。 在第三种情况下,该值在ENUM
中不可用。 在这种情况下,将插入一个空字符串。
SET
约束
SET
可以具有零个或多个值。 每个值都必须从允许值列表中选择。
mysql> CREATE TABLE Students(Id INTEGER, Name VARCHAR(55),
-> Certificates SET('A1', 'A2', 'B1', 'C1'));
我们有一个Students
表。 在此表中,我们有一个“证书”列。 每个学生可以拥有 0、1 个或多个这些证书。 这与ENUM
约束不同,在ENUM
约束中,允许值列表中只能有一个不同的值。
mysql> INSERT INTO Students VALUES(1, 'Paul', 'A1,B1');
mysql> INSERT INTO Students VALUES(2, 'Jane', 'A1,B1,A2');
mysql> INSERT INTO Students VALUES(3, 'Mark', 'A1,A2,D1,D2');
mysql> SELECT * FROM Students;
+------+------+--------------+
| Id | Name | Certificates |
+------+------+--------------+
| 1 | Paul | A1,B1 |
| 2 | Jane | A1,A2,B1 |
| 3 | Mark | A1,A2 |
+------+------+--------------+
保罗有两个证书,珍妮有三个,马克有四个,但是只有两个被认可,因此只有前两个被写到了桌子上。 证书用逗号分隔。 不允许有空格。