數據的完整性約束(2)
三、索引
在關係數據庫中,索引是一種單獨的、物理的對數據庫表中一列或多列的值進行排序的儲存結構,它是某個表中一列或若干列值的集合和相應的指向表中物理標識這些頁的邏輯指針清單。
是不是很晦澀,簡單點,就像是每本書中的目錄。
在數據庫中查詢某條數據,指定查詢以後,數據庫是從第一條數據開始遍歷的,如果需要的數據在第1000條,就會一直遍歷,直到找到這一條數據。這樣,效率就會大打折扣,索引就是爲了解決這個問題。
1.普通索引
(1)在已經創建的表中,爲其某個字段創建索引
語法格式
create index 索引名 on 表名(字段名[(長度)]);
示例
首先我先創建表stu
mysql> create table stu(
-> id int,
-> name varchar(50),
-> age int
-> );
Query OK, 0 rows affected (0.03 sec)
在表中給id字段創建索引
mysql> create index stu_id on stu(id);
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
查看錶的具體信息,可以看到id字段普通索引創建成功
mysql> show create table stu\G
*************************** 1. row ***************************
Table: stu
Create Table: CREATE TABLE `stu` (
`id` int DEFAULT NULL,
`name` varchar(50) DEFAULT NULL,
`age` int DEFAULT NULL,
KEY `stu_id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
mysql> desc stu;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int | YES | MUL | NULL | |
| name | varchar(50) | YES | | NULL | |
| age | int | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
(2)創建表時創建索引
語法格式
create table 表名 (字段名 數據類型,...,index [索引名] (字段名[(長度)]));
示例
在創建表時爲name字段創建索引,索引名爲“stu_name”
mysql> create table student(
-> id int,
-> name varchar(50),
-> age int,
-> index stu_name (name)
-> );
Query OK, 0 rows affected (0.03 sec)
查看錶的具體信息,可以看到name字段普通索引創建成功
mysql> show create table student\G
*************************** 1. row ***************************
Table: student
Create Table: CREATE TABLE `student` (
`id` int DEFAULT NULL,
`name` varchar(50) DEFAULT NULL,
`age` int DEFAULT NULL,
KEY `stu_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
mysql> desc student;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int | YES | | NULL | |
| name | varchar(50) | YES | MUL | NULL | |
| age | int | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
2.唯一索引
普通索引允許被索引的數據列包含重複的值,唯一索引可以保證數據的唯一性
(1)在已經創建的表中,爲其某個字段創建索引
語法格式,用法與普通索引一致
create unique index 索引名 on 表名 (字段名[(長度)]);
(2)創建表時創建索引
語法格式,用法與普通索引一致
create table 表名 (字段名 數據類型,...,unique index [索引名] (字段名[(長度)]));
3.查看索引
語法格式
show index from 表名;
4.刪除索引
(1)第一種方式
alter table 表名 drop index 索引名;
示例,刪除stu表id字段的索引
mysql> alter table stu drop index stu_id;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
查看錶的具體信息,stu表id字段的索引,成功刪除
mysql> show create table stu\G
*************************** 1. row ***************************
Table: stu
Create Table: CREATE TABLE `stu` (
`id` int DEFAULT NULL,
`name` varchar(50) DEFAULT NULL,
`age` int DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
mysql> desc stu;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int | YES | | NULL | |
| name | varchar(50) | YES | | NULL | |
| age | int | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
(2)第二種方式
drop index 索引名 on 表名;
示例,刪除student表中,name 字段的索引
mysql> drop index stu_name on student;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
查看錶的具體信息,可以看到name字段普通索引刪除成功
mysql> show create table stu\G
*************************** 1. row ***************************
Table: stu
Create Table: CREATE TABLE `stu` (
`id` int DEFAULT NULL,
`name` varchar(50) DEFAULT NULL,
`age` int DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
mysql> desc stu;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int | YES | | NULL | |
| name | varchar(50) | YES | | NULL | |
| age | int | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
四、引用完整性
引用完整性是對實體之間關係的描述,是定義外關鍵字與主關鍵字之間的引用規則,也就是外鍵約束。
如果要刪除被引用的對象,也要刪除引用它的所有對象,或把引用值設置爲空。
外鍵指引用另一個表中的一列或多列,被引用的列應該具有主鍵約束或者唯一約束。
外鍵用於加強兩個表,數據之間的連接。
1.添加外鍵約束
語法格式
alter table 表名 add foreign key (外鍵字段名) references 主表表名(主鍵字段名);
示例
將具有唯一性約束字段age的stu表作爲主表,將student表作爲從表,爲student表age字段添加外鍵約束
mysql> desc stu;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int | YES | | NULL | |
| name | varchar(50) | YES | | NULL | |
| age | int | YES | UNI | NULL | |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
添加外鍵約束
mysql> alter table student add foreign key(age) references stu(age);
Query OK, 0 rows affected (0.05 sec)
Records: 0 Duplicates: 0 Warnings: 0
查看student表具體信息,如下,外鍵約束添加成功,‘student_ibfk_1’爲外鍵約束名
mysql> show create table student\G
*************************** 1. row ***************************
Table: student
Create Table: CREATE TABLE `student` (
`id` int DEFAULT NULL,
`name` varchar(50) DEFAULT NULL,
`age` int DEFAULT NULL,
KEY `age` (`age`),
CONSTRAINT `student_ibfk_1` FOREIGN KEY (`age`) REFERENCES `stu` (`age`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
創建表時添加外鍵約束
首先創建一個含有主鍵的表student2
mysql> create table student2(
-> stu_id int primary key,
-> stu_name varchar(50)
-> );
創建表student3時添加外鍵約束
mysql> create table student3(
-> id int,
-> name varchar(50),
-> stu_id int,
-> foreign key(stu_id) references student2(stu_id)
-> );
Query OK, 0 rows affected (0.03 sec)
查看錶的具體信息,如下,外鍵約束創建成功
mysql> show create table student\G
*************************** 1. row ***************************
Table: student
Create Table: CREATE TABLE `student` (
`id` int DEFAULT NULL,
`name` varchar(50) DEFAULT NULL,
`age` int DEFAULT NULL,
KEY `age` (`age`),
CONSTRAINT `student_ibfk_1` FOREIGN KEY (`age`) REFERENCES `stu` (`age`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
2.刪除外鍵約束
即解除兩個表之間的關聯關係。
alter table 表名 drop foreign key 外鍵名;
示例,刪除student表外鍵約束
mysql> alter table student drop foreign key student_ibfk_1;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
如上,外鍵約束刪除成功
mysql> show create table student\G
*************************** 1. row ***************************
Table: student
Create Table: CREATE TABLE `student` (
`id` int DEFAULT NULL,
`name` varchar(50) DEFAULT NULL,
`age` int DEFAULT NULL,
KEY `age` (`age`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
但是主鍵還沒有徹底刪除!
採用desc語句看一下表結構,可以看到age字段的key值仍然有值
mysql> desc student;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int | YES | | NULL | |
| name | varchar(50) | YES | | NULL | |
| age | int | YES | MUL | NULL | |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
這是因爲MySQL在創建外鍵後會自動建一個同名的索引。
因此,採用上面語句只能刪除外鍵約束,無法徹底刪除外鍵。
所以,我們需要將同名索引也刪除,纔可以將外鍵徹底刪除
首先,我們需要使用show index from語句查看索引,如下。
mysql> show index from student;
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| student | 1 | age | 1 | age | A | 0 | NULL | NULL | YES | BTREE | | | YES | NULL |
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
1 row in set (0.01 sec)
我們再使用刪除索引的語句將索引刪除
mysql> alter table student drop index age;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
再次使用desc語句查看錶結構,key列裏的MUl消失了
mysql> desc student;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int | YES | | NULL | |
| name | varchar(50) | YES | | NULL | |
| age | int | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
這樣主鍵就徹底刪除了!