数据库的索引
索引的概念
索引的作用
索引适合在什么情况下使用呢?
索引的分类和创建
创建一个表
mysql> select * from member;
+------+----------+--------+-------+---------+--------+
| id | name | cardid | phone | address | remark |
+------+----------+--------+-------+---------+--------+
| 1 | zhansgan | 123 | 1111 | 南京 | nan |
| 3 | lisi | 124 | 3333 | 北京 | nan |
| 2 | wangwu | 125 | 2222 | 北京 | nan |
| 4 | zhaoliu | 126 | 4444 | 上海 | nv |
| 5 | zhanglei | 127 | 5555 | 杭州 | nv |
+------+----------+--------+-------+---------+--------+
5 rows in set (0.00 sec)
普通索引
- 直接创建索引
mysql> create index phone_index on member (phone); //create index 索引名 on 表名 (列名); Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> show create table member; //查看表结构或索引信息 | member | CREATE TABLE "member" ( "id" int(10) DEFAULT NULL, "name" varchar(10) DEFAULT NULL, "cardid" varchar(18) DEFAULT NULL, "phone" varchar(11) DEFAULT NULL, "address" varchar(50) DEFAULT NULL, "remark" text, KEY "phone_index" ("phone") //这是我们设置的普通索引 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 | mysql> desc member; //查看字段属性 +---------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+-------------+------+-----+---------+-------+ | id | int(10) | YES | | NULL | | | name | varchar(10) | YES | | NULL | | | cardid | varchar(18) | YES | | NULL | | | phone | varchar(11) | YES | MUL | NULL | | | address | varchar(50) | YES | | NULL | | | remark | text | YES | | NULL | | +---------+-------------+------+-----+---------+-------+ 6 rows in set (0.00 sec)
- 修改表结构方式创建索引
mysql> alter table member add index id_index (id); //alter table 表名 add index 索引名 (列名); Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> show create table member; | member | CREATE TABLE "member" ( "id" int(10) DEFAULT NULL, "name" varchar(10) DEFAULT NULL, "cardid" varchar(18) DEFAULT NULL, "phone" varchar(11) DEFAULT NULL, "address" varchar(50) DEFAULT NULL, "remark" text, KEY "phone_index" ("phone"), KEY "id_index" ("id") //这是我们用修改表结构方式创建的索引 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 | mysql> desc member; +---------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+-------------+------+-----+---------+-------+ | id | int(10) | YES | MUL | NULL | | | name | varchar(10) | YES | | NULL | | | cardid | varchar(18) | YES | | NULL | | | phone | varchar(11) | YES | MUL | NULL | | | address | varchar(50) | YES | | NULL | | | remark | text | YES | | NULL | | +---------+-------------+------+-----+---------+-------+ 6 rows in set (0.00 sec)
- 在创建表的时候直接指定索引
mysql> create table test(id int(4) not null,name varchar(10) not null,cardid varchar(18) not null,index id_index (id)); //在最后指定id为索引 mysql> show create table test; | test | CREATE TABLE "test" ( "id" int(4) NOT NULL, "name" varchar(10) NOT NULL, "cardid" varchar(18) NOT NULL, KEY "id_index" ("id") //能看到我们设置的普通索引 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 | mysql> desc test; +--------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+ | id | int(4) | NO | MUL | NULL | | | name | varchar(10) | NO | | NULL | | | cardid | varchar(18) | NO | | NULL | | +--------+-------------+------+-----+---------+-------+ 3 rows in set (0.00 sec)
唯一性索引
-
唯一性索引普通索引的区别是唯一性索引的每个值都是唯一,如果列中有相同的记录就不能设置成索引,唯一性索引允许有空值,添加唯一键将自动创建唯一性索引
-
直接创建唯一性索引
mysql> select * from member; +------+----------+--------+-------+---------+--------+ | id | name | cardid | phone | address | remark | +------+----------+--------+-------+---------+--------+ | 1 | zhansgan | 123 | 1111 | 南京 | nan | | 3 | lisi | 124 | 3333 | 北京 | nan | | 2 | wangwu | 125 | 2222 | 北京 | nan | | 4 | zhaoliu | 126 | 4444 | 上海 | nv | | 5 | zhanglei | 127 | 5555 | 杭州 | nv | +------+----------+--------+-------+---------+--------+ 5 rows in set (0.00 sec) mysql> create unique index address_index on member (address); ERROR 1062 (23000): Duplicate entry '北京' for key 'address_index' //因为address中有记录重复,所以不能设置成唯一性索引 mysql> create unique index name_index on member (name); //create unique index 索引名 on 表名 (列名); Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> show create table member; | member | CREATE TABLE "member" ( "id" int(10) DEFAULT NULL, "name" varchar(10) DEFAULT NULL, "cardid" varchar(18) DEFAULT NULL, "phone" varchar(11) DEFAULT NULL, "address" varchar(50) DEFAULT NULL, "remark" text, UNIQUE KEY "name_index" ("name") //这个就是我们设置的唯一性索引,跟设置唯一键是同一个字段,只是多了一个索引名 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 | mysql> desc member; +---------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+-------------+------+-----+---------+-------+ | id | int(10) | YES | | NULL | | | name | varchar(10) | YES | UNI | NULL | | | cardid | varchar(18) | YES | | NULL | | | phone | varchar(11) | YES | | NULL | | | address | varchar(50) | YES | | NULL | | | remark | text | YES | | NULL | | +---------+-------------+------+-----+---------+-------+ 6 rows in set (0.00 sec)
- 修改表结构方式创建唯一索引
mysql> alter table member add unique cardid_index (cardid); Query OK, 0 rows affected (0.02 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> show create table member; | member | CREATE TABLE "member" ( "id" int(10) DEFAULT NULL, "name" varchar(10) DEFAULT NULL, "cardid" varchar(18) DEFAULT NULL, "phone" varchar(11) DEFAULT NULL, "address" varchar(50) DEFAULT NULL, "remark" text, UNIQUE KEY "name_index" ("name"), UNIQUE KEY "cardid_index" ("cardid") //这是修改表结构创建的唯一性索引 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 | mysql> desc member; +---------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+-------------+------+-----+---------+-------+ | id | int(10) | YES | | NULL | | | name | varchar(10) | YES | UNI | NULL | | | cardid | varchar(18) | YES | UNI | NULL | | | phone | varchar(11) | YES | | NULL | | | address | varchar(50) | YES | | NULL | | | remark | text | YES | | NULL | | +---------+-------------+------+-----+---------+-------+ 6 rows in set (0.00 sec)
- 创建表的时候指定唯一性索引
mysql> create table test2 (id int,name varchar(20),unique id_index (id)); Query OK, 0 rows affected (0.01 sec) mysql> show create table test2; | test2 | CREATE TABLE "test2" ( "id" int(11) DEFAULT NULL, "name" varchar(20) DEFAULT NULL, UNIQUE KEY "id_index" ("id") //这是指定出案件的唯一性索引 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 | mysql> desc test2; +-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | id | int(11) | YES | UNI | NULL | | | name | varchar(20) | YES | | NULL | | +-------+-------------+------+-----+---------+-------+ 2 rows in set (0.00 sec)
主键索引
mysql> create table test1 (id int primary key,name varchar(20)); Query OK, 0 rows affected (0.36 sec) mysql> desc test1; +-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | name | varchar(20) | YES | | NULL | | +-------+-------------+------+-----+---------+-------+ 2 rows in set (0.00 sec) mysql> show create table test1; | test1 | CREATE TABLE "test1" ( "id" int(11) NOT NULL, "name" varchar(20) DEFAULT NULL, PRIMARY KEY ("id") //这就是我们创建的主键索引 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
- 修改表结构创建索引
mysql> alter table test1 add primary key (id); Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> desc test1; +-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | name | varchar(20) | YES | | NULL | | +-------+-------------+------+-----+---------+-------+ 2 rows in set (0.00 sec) mysql> show create table test1; | test1 | CREATE TABLE "test1" ( "id" int(11) NOT NULL, "name" varchar(20) DEFAULT NULL, PRIMARY KEY ("id") ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
组合索引
mysql> create table test3 (id int not null,name varchar(20),cardid varchar(20),index index_test3 (id,name)); //最后设置index 组合索引名 (多个列名);
Query OK, 0 rows affected (0.33 sec)
mysql> show create table test3;
| test3 | CREATE TABLE "test3" (
"id" int(11) NOT NULL,
"name" varchar(20) DEFAULT NULL,
"cardid" varchar(20) DEFAULT NULL,
KEY "index_test3" ("id","name") //这就是设置的组合索引
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
mysql> show create table test3;
| test3 | CREATE TABLE "test3" (
"id" int(11) NOT NULL,
"name" varchar(20) DEFAULT NULL,
"cardid" varchar(20) DEFAULT NULL,
KEY "index_test3" ("id","name")
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
全文索引
mysql> create fulltext index remark_index on member (remark); //create fulltext index 索引名 on 表名 (列名);
Query OK, 0 rows affected, 1 warning (0.48 sec)
Records: 0 Duplicates: 0 Warnings: 1
mysql> show create table member;
| member | CREATE TABLE "member" (
"id" int(10) DEFAULT NULL,
"name" varchar(10) DEFAULT NULL,
"cardid" varchar(18) DEFAULT NULL,
"phone" varchar(11) DEFAULT NULL,
"address" varchar(50) DEFAULT NULL,
"remark" text,
FULLTEXT KEY "remark_index" ("remark") //这就是创建的全文索引字段
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
mysql> desc member;
+---------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| id | int(10) | YES | | NULL | |
| name | varchar(10) | YES | | NULL | |
| cardid | varchar(18) | YES | | NULL | |
| phone | varchar(11) | YES | | NULL | |
| address | varchar(50) | YES | | NULL | |
| remark | text | YES | MUL | NULL | |
+---------+-------------+------+-----+---------+-------+
6 rows in set (0.00 sec)
mysql> alter table member add fulltext remark_index (remark);
Query OK, 0 rows affected (0.49 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table member;
| member | CREATE TABLE "member" (
"id" int(10) DEFAULT NULL,
"name" varchar(10) DEFAULT NULL,
"cardid" varchar(18) DEFAULT NULL,
"phone" varchar(11) DEFAULT NULL,
"address" varchar(50) DEFAULT NULL,
"remark" text,
FULLTEXT KEY "remark_index" ("remark") //这就是修改表结构添加的全文索引
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
mysql> desc member;
+---------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| id | int(10) | YES | | NULL | |
| name | varchar(10) | YES | | NULL | |
| cardid | varchar(18) | YES | | NULL | |
| phone | varchar(11) | YES | | NULL | |
| address | varchar(50) | YES | | NULL | |
| remark | text | YES | MUL | NULL | |
+---------+-------------+------+-----+---------+-------+
6 rows in set (0.00 sec)
mysql> create table test4 (id int(4),name varchar(20),address varchar(40),remark text,fulltext remark_index (remark));
Query OK, 0 rows affected (0.28 sec)
mysql> show create table test4;
| test4 | CREATE TABLE "test4" (
"id" int(4) DEFAULT NULL,
"name" varchar(20) DEFAULT NULL,
"address" varchar(40) DEFAULT NULL,
"remark" text,
FULLTEXT KEY "remark_index" ("remark") //创建表时创建的全文索引
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
mysql> desc test4;
+---------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| id | int(4) | YES | | NULL | |
| name | varchar(20) | YES | | NULL | |
| address | varchar(40) | YES | | NULL | |
| remark | text | YES | MUL | NULL | |
+---------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
mysql> select * from test4;
+------+----------+----------+--------+
| id | name | address | remark |
+------+----------+----------+--------+
| 1 | zhangsan | shanghai | NULL |
| 3 | wangwu | anhui | novip |
| 2 | lisi | shanghai | vip |
+------+----------+----------+--------+
3 rows in set (0.00 sec)
mysql> select * from test4 where match(remark) against('vip') //match指定列名,against指定内容
-> ;
+------+------+----------+--------+
| id | name | address | remark |
+------+------+----------+--------+
| 2 | lisi | shanghai | vip |
+------+------+----------+--------+
1 row in set (0.01 sec)
查看索引
mysql> show index from test4\G
*************************** 1. row ***************************
Table: test4 //表名
Non_unique: 1 //是否索引内容唯一,唯一为0,不唯一为1
Key_name: remark_index //索引名
Seq_in_index: 1 //索引中列序号,从一开始表示第二列,跟数组下标一样
Column_name: remark //列名称
Collation: NULL //列以什么方式存储在索引中。在 MySQL 中,有值‘A’(升序)或 NULL(无分类)
Cardinality: 3 //索引中唯一值数目的估计值
Sub_part: NULL //如果列只是被部分地编入索引,则为被编入索引的字符的数目(zhangsan)。如果整列被编入索引,则为 NULL
Packed: NULL //指定关键字如何被压缩,null表示没有被压缩
Null: YES //如果列含有 NULL,则含有 YES。如果没有,则该列含有 NO
Index_type: FULLTEXT //用过的索引方法
Comment: //备注
Index_comment: //索引备注
1 row in set (0.00 sec)
mysql> show keys from test3\G
*************************** 1. row ***************************
Table: test3
Non_unique: 1
Key_name: index_test3
Seq_in_index: 1
Column_name: id
Collation: A
Cardinality: 1
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
*************************** 2. row ***************************
Table: test3
Non_unique: 1
Key_name: index_test3
Seq_in_index: 2
Column_name: name
Collation: A
Cardinality: 1
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
Index_comment:
2 rows in set (0.00 sec)
删除索引
mysql> drop index remark_index on test4; //drop index 索引名 on 表名
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc test4;
+---------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| id | int(4) | YES | | NULL | |
| name | varchar(20) | YES | | NULL | |
| address | varchar(40) | YES | | NULL | |
| remark | text | YES | | NULL | |
+---------+-------------+------+-----+---------+-------+
4 rows in set (0.01 sec)
mysql> show create table test4;
| test4 | CREATE TABLE "test4" (
"id" int(4) DEFAULT NULL,
"name" varchar(20) DEFAULT NULL,
"address" varchar(40) DEFAULT NULL,
"remark" text
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
mysql> desc test3;
+--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| id | int(11) | NO | MUL | NULL | |
| name | varchar(20) | YES | | NULL | |
| cardid | varchar(20) | YES | | NULL | |
+--------+-------------+------+-----+---------+-------+
mysql> alter table test3 drop index index_test3;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc test3;
+--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| id | int(11) | NO | | NULL | |
| name | varchar(20) | YES | | NULL | |
| cardid | varchar(20) | YES | | NULL | |
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> show create table test3;
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------+
| test3 | CREATE TABLE "test3" (
"id" int(11) NOT NULL,
"name" varchar(20) DEFAULT NULL,
"cardid" varchar(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> desc test3;
+--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| id | int(6) | NO | PRI | NULL | |
| name | varchar(20) | YES | | NULL | |
| cardid | varchar(20) | YES | | NULL | |
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> alter table test3 drop primary key;
Query OK, 1 row affected (0.02 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> show create table test3;
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
| test3 | CREATE TABLE "test3" (
"id" int(6) NOT NULL,
"name" varchar(20) DEFAULT NULL,
"cardid" varchar(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)