索引
在關係數據庫中,索引是對數據庫表中指定字段的一種存儲結構。索引也是一張表,表中存儲着索引的字段值和該值所在的物理位置。索引的作用相當於圖書的目錄,可以根據目錄中的頁碼快速找到所需的內容。
索引設計原則
1)要注意,索引也是要佔用磁盤空間的,所以並不是越多越好。
2)過多的索引會影響INSERT,DELETE,UPDATE等語句的執行效率。
3)數據過少不建議建立索引。
4)對於唯一性約束,應使用對應的唯一性索引。
5)儘量不對區分度低的字段建立索引。例如:枚舉類型的性別字段只有男女,起不到優化效果。
6)建議在創建表的時候創建索引。若表中有大量記錄,那麼將列建爲索引後,表中所有記錄都將會修改。
7)不經常查詢的字段,不建議創建索引。
使用流程
1.首先使用查詢語句,通過索引字段查找記錄
2.數據庫根據索引找到指定列的值。
3.然後通過指針找到包含該值的行。
爲什麼要建立索引?
如果不使用索引,MySQL必須從表中的第一條記錄開始,對整張表進行遍歷,直到找出相關的記錄。表中記錄越多,查詢數據所花費的時間越多,缺乏靈活性。
如果使用了索引,數據庫能快速地通過索引去查找對應條件的記錄,不必遍歷數據表,有效地節省查詢時間。
索引優缺
優點:
1.加快表與表之間的連接。
2.大大加快數據的查詢速度。
3.所有的數據類型都可以被索引。
缺點:
1.索引的創建和維護也是需要時間的,並且隨着數據的增加而增加。
2.每一條索引的記錄都會佔用一定的磁盤空間。
3.對錶中數據的增刪改查,索引也會修改。
索引類型
類型 | 作用 |
---|---|
普通索引 | 基本索引方式,無特別說明 |
唯一性索引 | 數據唯一,允許有null |
主鍵索引 | 表中只有一個主鍵,數據唯一,不允許有null |
複合索引 | 可以包含兩個或多個列的索引方式 |
根據不同的環境選擇對應的索引類型即可。
創建索引語法
以普通索引爲例,在創建表的時候創建索引
create table 表名(
字段定義…
index 索引名稱(字段));
以普通索引爲例,將表修改爲索引
alter table 表名 add index 索引名稱(字段);
可以使用key代替index,並且索引名稱可以省略,不加索引名默認以字段名作爲索引名。
普通索引
沒啥要注意的,最基礎的索引方式。
創建一個表,並且建立普通索引,索引列爲id
mysql> create table test1(id int,name varchar(5),age tinyint,index index_id(id));
查看錶結構,在key下的MUL就代表着普通索引
mysql> desc test1;
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| id | int(11) | YES | MUL | NULL | |
| name | varchar(5) | YES | | NULL | |
| age | tinyint(4) | YES | | NULL | |
+-------+------------+------+-----+---------+-------+
查看索引信息
mysql> show index from test1\G
*************************** 1. row ***************************
Table: test1
Non_unique: 1
Key_name: index_id
Seq_in_index: 1
Column_name: id
Collation: A
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
Expression: NULL
1 row in set (0.00 sec)
往表中添加一些數據,用於測試
mysql> insert into test1 values(1,'張三',21),(2,'李四',22),(3,'王五',23),(4,'趙六',24);
通過explain模擬執行sql查詢語句,先不通過索引,查詢姓名爲趙六的記錄。
mysql> explain select * from test1 where name='趙六'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: test1
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 4
filtered: 25.00
Extra: Using where
1 row in set, 1 warning (0.00 sec)
type:ALL項表示全表掃描,rows: 4表示行數。因爲趙六是表中最後一條記錄,所以查詢遍歷了整張表。
接下來通過索引列id對姓名爲趙六的字段進行查詢。
mysql> explain select * from test1 where id=4\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: test1
partitions: NULL
type: ref
possible_keys: index_id
key: index_id
key_len: 5
ref: const
rows: 1
filtered: 100.00
Extra: NULL
1 row in set, 1 warning (0.00 sec)
rows: 1表示只檢索了一行便將記錄查找出來了,高下立判。
唯一索引
在唯一索引中,索引列中數據唯一,不能出現重複的值,用來約束內容,允許有null值。
語法:
create table 表名(
字段定義…
unique key 索引名(字段名));
唯一索引常用在值不能重複的字段,身份證號,手機號等等。
創建一個表,並且建立唯一性索引,索引列爲手機號。
mysql> create table test2(id int,name varchar(5),phone int,unique key unique_key_phone(phone));
查看錶結構,key下爲UNI的表示爲唯一性索引
mysql> desc test2;
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(5) | YES | | NULL | |
| phone | int(11) | YES | UNI | NULL | |
+-------+------------+------+-----+---------+-------+
插入數據,並測試特性
mysql> insert into test2 values(1,'張三',1111111111);
mysql> insert into test2 values(2,'李四',null); #可以爲null
mysql> insert into test2 values(3,'王五',1111111111); #值必須唯一
ERROR 1062 (23000): Duplicate entry '1111111111' for key 'unique_key_phone'
查看錶數據
mysql> select * from test2;
+------+--------+------------+
| id | name | phone |
+------+--------+------------+
| 2 | 李四 | NULL |
| 1 | 張三 | 1111111111 |
+------+--------+------------+
主鍵索引
主鍵索引也就是設置主鍵,每個表最多隻能有一個主鍵。主鍵列值必須唯一,並且不允許有空值。
語法:
create table 表名(字段 primary key);
或者
create table 表名(
字段定義…
primary key 索引名稱(字段));
創建一個表,並且設置爲主鍵索引,索引列爲id
mysql> create table test3(id int primary key,name varchar(5),age tinyint);
查看錶結構,key下爲PRI的爲主鍵索引列
mysql> desc test3;
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | varchar(5) | YES | | NULL | |
| age | tinyint(4) | YES | | NULL | |
+-------+------------+------+-----+---------+-------+
插入數據,並測試特性
mysql> insert into test3 values(1,'張三',23);
mysql> insert into test3 values(null,'張三',23); #不能爲null
ERROR 1048 (23000): Column 'id' cannot be null
mysql> insert into test3 values(1,'張三',23); #值不能重複
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
查看錶數據
mysql> select * from test3;
+----+--------+------+
| id | name | age |
+----+--------+------+
| 1 | 張三 | 23 |
+----+--------+------+
複合索引
複合索引可以包含兩個或多個列。
沒有特定語法,可以爲表創建雙索引
創建一個表,並設置爲複合主鍵,索引列爲id,name
mysql> create table test4 (id int,name varchar(5),age tinyint,primary key(id,name));
複合主鍵特性和主鍵有些不同,只需要有一個字段不重複即可。
mysql> insert into test4 values(1,'張三',21);
mysql> insert into test4 values(1,'李四',21);
mysql> insert into test4 values(1,'張三',21); #主鍵列全重複
ERROR 1062 (23000): Duplicate entry '1-張三' for key 'PRIMARY'
查看錶數據
mysql> select * from test4;
+----+--------+------+
| id | name | age |
+----+--------+------+
| 1 | 張三 | 21 |
| 1 | 李四 | 21 |
+----+--------+------+