1.1 什么是約束
約束字面意思就是限制,比如我們每一個人的身份證號都是唯一的,不可能出現兩個人,身份證是一樣的,那么這里的唯一性我們就稱之為一種約束,再比如:我們每個人都是有性別的,或男或女或其他,不可能出現一個人他沒有性別,那么這里的不能為空同樣也是一種約束。在數據庫中也有很多約束,數據庫的數據必須要滿足約束才可正確插入,否則就會報錯,下面我們具體學習約束的內容
1.2主鍵約束
1.2.1 主鍵約束
主鍵約束(PRIMARY KEY),簡稱主鍵,該約束的作用是定義一個主鍵來唯一確定表中每一行數據的標識符,我們把它拆解開來說:
- 使用了主鍵的字段的值,必須是唯一的,不能重復
- 主鍵的列,不能包含NULL值
- 每個表最多只能有一個主鍵。
1.2.2 添加主鍵約束
創建表時,聲明主鍵,示例代碼如下:
CREATE TABLE People(
id int PRIMARY KEY,
name VARCHAR(30),
age INT
);
創建完成后,我們看一下People表的表結構,如下:
MySQL> desc People;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int | NO | PRI | NULL | |
| name | varchar(30) | YES | | NULL | |
| age | int | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.01 sec)
mysql>
這里我們發現id字段在NULL列的值為NO,在KEY列有個PRI鍵,這個就表示該字段為主鍵,下面我們試一下,如果我們插入數據時,主鍵字段為空,報什么錯,報錯如下:
mysql> insert into People(id,name,age) values(NULL,"張三",'20');
ERROR 1048 (23000): Column 'id' cannot be null
mysql>
從上面的報錯我們可以看出主鍵不能為空,為空就會報上面的錯,下面我們再來驗證一下主鍵id字段不能重復,代碼如下:
mysql> insert into People(id,name,age) values(1,"張三",'20');
Query OK, 1 row affected (0.01 sec)
mysql> insert into People(id,name,age) values(1,"張三",'20');
ERROR 1062 (23000): Duplicate entry '1' for key 'people.PRIMARY'
mysql>
我們最開始插入了一條數據,然后我們又插入了一遍,發現報錯了,提示id的值重復了,主鍵是不能重復的。
1.2.3 聯合主鍵
我們上面的主鍵為id,即只需要一個字段就可以標識數據的唯一性,有的時候我們的表需要兩個及以上的字段組合起來,才能確定一條記錄的唯一性,舉個例子,假如我們要設計一張統計一個地區學生信息的表,一個地區有多個學校,每個學校都有自己的編號,而每個學校的學生有自己的學校,當我們想要確定這個地區的某個學生時候,單單使用學號是無法確定的,因為有多個學校,學號肯定有重復的,此時我們就需要學校和學生學號兩個字段才能準確確定一個學生,這個時候就需要將這兩個字段設置成聯合主鍵。聯合主鍵還是一個主鍵,只不過這個主鍵是由多個字段共同確定的。
示例代碼如下:
CREATE TABLE AreaStuInfo(
sch_no INT,
stu_no INT,
name VARCHAR(30),
CONSTRAINT pk_sch_stu_id PRIMARY KEY (sch_no,stu_no)
);
這個時候,我們再查詢一下表結構,結果如下:
mysql> DESC AreaStuInfo;
+--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| sch_no | int | NO | PRI | NULL | |
| stu_no | int | NO | PRI | NULL | |
| name | varchar(30) | YES | | NULL | |
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.01 sec)
從上面的結果我們發現,sch_no和stu_no兩個字段的KEY列的值都有PRI,也就意味著sch_no和stu_no兩者的值一樣,就會觸發約束,報錯,但是如果僅僅是這兩個列的某一個列的值一樣,它是不會報錯。
1.2.4 刪除主鍵約束
當我們不需要主鍵約束的時候,我們可使用如下的代碼,將某一張的主鍵刪除,語法如下:
ALTER TABLE 表名 DROP PRIMARY KEY;
示例代碼如下:
mysql> DESC AreaStuInfo;
+--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| sch_no | int | NO | PRI | NULL | |
| stu_no | int | NO | PRI | NULL | |
| name | varchar(30) | YES | | NULL | |
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.01 sec)
mysql> ALTER TABLE AreaStuInfo DROP PRIMARY KEY;
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> DESC AreaStuInfo;
+--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| sch_no | int | NO | | NULL | |
| stu_no | int | NO | | NULL | |
| name | varchar(30) | YES | | NULL | |
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.01 sec)
mysql>
1.2.5 自動增長列
我們有的時候,希望表的某一個字段的值是自動增長的,比如編號,從1開始,依次+1,在數據庫中,我們可以使用auto_increment自動增長列關鍵字來實現,數據庫會自動生成該字段的值默認開始的值是1,我們也可以修改起始值,語法如下:
ALTER TABLE 表名 AUTO_INCREMENT=值
此外值得注意的是,如果一個字段是自動增長的列,那么該字段的數據類型必須是整型且必須是主鍵,下面我們看一個示例:
CREATE TABLE `People` (
`id` int PRIMARY KEY AUTO_INCREMENT,
`name` varchar(30) DEFAULT NULL,
`age` int DEFAULT NULL
);
我們看一下表結構:
mysql> desc People;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| name | varchar(30) | YES | | NULL | |
| age | int | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
我們有自動增長列的表中插入數據的時候,可以不為id字段設置值,也可以為其設置成null,示例代碼如下:
mysql> insert into People(name,age) values("王二",20);
Query OK, 1 row affected (0.01 sec)
mysql> insert into People(id,name,age) values(Null,"李四",20);
Query OK, 1 row affected (0.00 sec)
mysql> select * from People;
+----+--------+------+
| id | name | age |
+----+--------+------+
| 1 | 王二 | 20 |
| 2 | 李四 | 20 |
+----+--------+------+
2 rows in set (0.00 sec)
mysql>
從上面的示例上我們可以看出,我們即使沒有指定id字段的值,也是不會報錯的,數據庫會自動為其生成值。
1.3 非空約束
所謂非空的約束,其實很簡單,如果那個字段的值添加了非空的約束,那么這個字段的值就不能為NULL,如果是NULL,就會報錯,示例代碼如下:
mysql> desc People;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| name | varchar(30) | YES | | NULL | |
| age | int | YES | | NULL | |
| sex | char(30) | NO | | NULL | |
+-------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
mysql> insert into People(name,age,sex) values('張三',29,NULL);
ERROR 1048 (23000): Column 'sex' cannot be null
mysql>
我們從通過查詢People的表結構發現,sex字段不能為空,當我們在插入數據的時候,如果把該字段插入一個空值,那么就會報錯。添加非空約束的語法如下,只需要在需要添加的字段后面,增加NOT NULL即可。示例代碼如下:
CREATE TABLE `People` (
`id` int PRIMARY KEY AUTO_INCREMENT,
`name` varchar(30) DEFAULT NULL,
`age` int DEFAULT NULL,
`sex` CHAR(30) NOT NULL
);
1.4 唯一約束
唯一約束也很簡單,就是字面意思,如果一個字段被添加了唯一約束,那么該字段的值就只能是唯一的,不可重復的,添加唯一約束方式也很簡單,直接在數據類型的后面加上UNIQUE關鍵字即可,示例代碼如下:
CREATE TABLE `Person` (
`id` int PRIMARY KEY AUTO_INCREMENT,
`name` varchar(30) UNIQUE,
`age` int
);
以我們這里的Person表為例,所有數據的名字都不能重復,如果重復則會報錯,示例如下:
mysql> desc person;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| name | varchar(30) | YES | UNI | NULL | |
| age | int | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
mysql> insert into person(name,age) values("張三",20);
Query OK, 1 row affected (0.00 sec)
mysql> insert into person(name,age) values("張三",20);
ERROR 1062 (23000): Duplicate entry '張三' for key 'person.name'
mysql>
但是這個唯一約束對一個值例外,就是NULL,在MySQL中,NULL與任意一個值都不相等,連和它自己都不相等,多以如果名稱這一列有多條記錄,但是它的值是空的,也是不會報錯的。
1.5 結尾
本期的內容就到這里了,如有不足之處還請大家多多指正,歡迎大家留言、關注、轉發、收藏,謝謝。