多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
# MySQL 约束 > 原文: [http://zetcode.com/databases/mysqltutorial/constraints/](http://zetcode.com/databases/mysqltutorial/constraints/) 在 MySQL 教程的这一部分中,我们将处理约束。 约束放在列或表上。 它们限制了可以插入表中的数据。 我们有以下限制: * 非空 * 唯一 * 主键 * 外键 * 枚举 * 组 其他数据库也具有`CHECK`约束,该约束为有效数据设置了条件。 MySQL 解析了这个约束,但是没有强制执行。 ### 非空约束 具有`NOT NULL`约束的列不能具有`NULL`值。 ```sql 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`约束的列。 ```sql 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`约束确保所有数据在列中都是唯一的。 ```sql mysql> CREATE TABLE Brands(Id INTEGER, BrandName VARCHAR(30) UNIQUE); Query OK, 0 rows affected (0.08 sec) ``` 在这里,我们创建一个表`Brands`。 `BrandName`列设置为`UNIQUE`。 不能有两个名称相同的品牌。 ```sql 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 错误,重复项`"Pepsi"`。 只能有一个百事可乐品牌。 注意,`PRIMARY KEY`约束自动在其上定义了`UNIQUE`约束。 ### 主键 `PRIMARY KEY`约束唯一地标识数据库表中的每个记录。 这是唯一键的特例。 主键不能为`NULL`,唯一键可以为。 可以有更多`UNIQUE`列,但是表中只有一个主键。 在设计数据库表时,主键很重要。 主键是唯一的 ID。 我们使用它们来引用表行。 在表之间创建关系时,主键成为其他表中的外键。 ```sql mysql> DROP TABLE Brands; mysql> CREATE TABLE Brands(Id INTEGER PRIMARY KEY, BrandName VARCHAR(30) UNIQUE); ``` `Brands`表的`Id`列成为主键。 ```sql 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`。 ```sql mysql> CREATE TABLE Authors(AuthorId INTEGER PRIMARY KEY, Name VARCHAR(70)) -> type=InnoDB; ``` 在这里,我们创建`Authors`表。 在 MySQL 中,引用表和被引用表必须是 InnoDB 或 BDB 存储引擎。 在 MyISAM 存储引擎中,将解析外键,但不会强制使用外键。 ```sql 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`是一个字符串对象,其值是从允许值列表中选择的。 在创建表时,它们在列规范中显式枚举。 ```sql mysql> CREATE TABLE Shops(Id INTEGER, Name VARCHAR(55), -> Quality ENUM('High', 'Average', 'Low')); ``` 我们有一个`Shops`表。 该表具有定义的`Id`,`Name`和`Quality`列。 `Quality`列是`ENUM`。 它允许具有三个指定值之一:`High`,`Average`或`Low`。 ```sql 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`可以具有零个或多个值。 每个值都必须从允许值列表中选择。 ```sql mysql> CREATE TABLE Students(Id INTEGER, Name VARCHAR(55), -> Certificates SET('A1', 'A2', 'B1', 'C1')); ``` 我们有一个`Students`表。 在此表中,我们有一个`Certificates`列。 每个学生可以拥有 0、1 个或多个这些证书。 这与`ENUM`约束不同,在`ENUM`约束中,允许值列表中只能有一个不同的值。 ```sql 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 | +------+------+--------------+ ``` 保罗有两个证书,珍妮有三个,马克有四个,但是只有两个被认可,因此只有前两个被写到了表中。 证书用逗号分隔。 不允许有空格。 在 MySQL 教程的这一部分中,我们介绍了 MySQL 支持的约束。