定义
对数据库表的一列或多列的值进行排序的一种数据结构。
优点
加快数据检索速度
缺点
占用物理存储空间(/var/lib/mysql)
当对表中数据更新时,索引需要动态维护,降低数据维护速度
索引示例:
# cursor.executemany(SQL, [data1, data2, data3])
# 以次IO执行多条表记录操作,效率高,节省资源
数据库准备:
在mysql客户端创建一个数据库
CREATE TABLE `student` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(30) DEFAULT NULL,
`age` int unsigned DEFAULT NULL,
`password` char(10) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
用以下python脚本向这个数据库中插入1百万条数据:
import pymysql
import random
alpha = "abcdefghijklmnopqrstuvwxrz";
password = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789,.-+_[]<>"
#
class Studinfo:
# 返回一个三个元素组成的元组(name, age, password)
# name: 4~8字符组成
# age:取值10~20
# password:8个字符长度
@staticmethod
def get_info():
length = random.randint(4, 8)
name = ""
for i in range(length):
index = random.randint(0, len(alpha) - 1)
if i == 0:
name += alpha[index].upper()
else:
name += alpha[index]
pwd = ""
for i in range(8):
index = random.randint(0, len(password) - 1)
pwd += password[index]
age = random.randint(10, 20)
return name, age, pwd
db = pymysql.connect(host='192.168.1.10',
port=3306,
user='dbuser',
password='abcdef12345',
database='student',
charset="utf8mb4")
# 获取游标(操作数据库, 执行sql语句)
cur = db.cursor()
sqlpattern = 'insert into student (name, age,password) values ("%s", %d,"%s");'
for i in range(1000000):
sql = sqlpattern % Studinfo.get_info()
print(sql)
cur.execute(sql)
if i % 100 == 0:
db.commit()
db.commit()
cur.close()
db.close()
执行以上python脚本后,查看数据库中student数据表的数据记录数目:
mysql> select count(*) from student;
+----------+
| count(*) |
+----------+
| 1000000 |
+----------+
1 row in set (0.13 sec)
索引测试:
1、开启运行时间检测:
mysql> show variables like 'profil%';
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| profiling | OFF |
| profiling_history_size | 15 |
+------------------------+-------+
2 rows in set (0.00 sec)
mysql> set profiling=1;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> show variables like 'profil%';
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| profiling | ON |
| profiling_history_size | 15 |
+------------------------+-------+
2 rows in set (0.00 sec)
2、执行没有建立索引时的查询语句,查询需要0.32636350秒:
mysql> select * from student where name='Sqwxbm';
+--------+--------+------+----------+
| id | name | age | password |
+--------+--------+------+----------+
| 900000 | Sqwxbm | 14 | jO,Ak>uv |
+--------+--------+------+----------+
1 row in set (0.36 sec)
mysql> show profiles;
+----------+------------+-------------------------------------------+
| Query_ID | Duration | Query |
+----------+------------+-------------------------------------------+
| 1 | 0.00207250 | show variables like 'profil%' |
| 2 | 0.01848775 | drop index
name on student |
| 3 | 0.33722400 | select * from student where name='Sqwxbm' |
| 4 | 0.32636350 | select * from student where name='Sqwxbm' |
+----------+------------+-------------------------------------------+
4 rows in set, 1 warning (0.00 sec)
3、在name字段创建索引,并进行相同的查询测试,查询时间为0.00046925秒:
mysql> create index idx_name on student(name);
Query OK, 0 rows affected (7.61 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> select * from student where name='Sqwxbm';
+--------+--------+------+----------+
| id | name | age | password |
+--------+--------+------+----------+
| 900000 | Sqwxbm | 14 | jO,Ak>uv |
+--------+--------+------+----------+
1 row in set (0.00 sec)
mysql> show profiles;
+----------+------------+-------------------------------------------+
| Query_ID | Duration | Query |
+----------+------------+-------------------------------------------+
| 1 | 0.00207250 | show variables like 'profil%' |
| 2 | 0.01848775 | drop index
name on student |
| 3 | 0.33722400 | select * from student where name='Sqwxbm' |
| 4 | 0.32636350 | select * from student where name='Sqwxbm' |
| 5 | 7.61299850 | create index idx_name on student(name) |
| 6 | 0.00046925 | select * from student where name='Sqwxbm' |
| 7 | 0.00011975 | show proifles |
+----------+------------+-------------------------------------------+
7 rows in set, 1 warning (0.00 sec)
索引类型
普通(MUL)和唯一(UNI)
使用规则
1、可设置多个字段
2、普通索引:字段值无约束,KEY标志位MUL
3、唯一索引:字段值不允许重复,字段值可为NULL,KEY标志位UNI
4、哪些字段创建索引:经常查询的字段、where条件判断字段、order by排序字段
创建普通索引和唯一索引
1、创建表时
CREATE TABLE 表名(
字段名 数据类型,
字段名 数据类型,
index(字段名),
index(字段名),
unique(字段名)
);
示例:创建一个数据表,由三个字段组成,id为主键、自增;name为普通索引;phone为唯一索引
mysql> create table stu1(
-> id int primary key auto_increment,
-> name varchar(30) not null,
-> phone varchar(11) not null,
-> index(name),
-> unique(phone)
-> )engine=innodb charset=utf8mb4;
Query OK, 0 rows affected (0.06 sec)
mysql> desc stu1;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| name | varchar(30) | NO | MUL | NULL | |
| phone | varchar(11) | NO | UNI | NULL | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
mysql> insert into stu1 (name, phone) values ('zhangsan','13711111111');
Query OK, 1 row affected (0.01 sec)
mysql> insert into stu1 (name, phone) values ('zhangsan','13711111112');
Query OK, 1 row affected (0.01 sec)
mysql> insert into stu1 (name, phone) values ('lisi','13711111112');
ERROR 1062 (23000): Duplicate entry '13711111112' for key 'stu1.phone'
2、已有表中创建索引:
create [unique] index 索引名 on 表名(字段名)
示例:创建一个数据表,由三个字段组成,然后为其name字段添加普通索引,为phone字段添加唯一索引
mysql> create table stu2(
-> id int primary key auto_increment,
-> name varchar(30) not null,
-> phone char(11) not null)engine=innodb charset=utf8mb4;
Query OK, 0 rows affected (0.05 sec)
mysql> desc stu2;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| name | varchar(30) | NO | | NULL | |
| phone | char(11) | NO | | NULL | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
mysql> create index idx_name on stu2(name);
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> create unique index indx_phone on stu2(phone);
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc stu2;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| name | varchar(30) | NO | MUL | NULL | |
| phone | char(11) | NO | UNI | NULL | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)
查看索引:
1、desc 表名; ---> KEY标识为:MUL UNI
mysql> desc stu2;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| name | varchar(30) | NO | MUL | NULL | |
| phone | char(11) | NO | UNI | NULL | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
2、show index from 表名\G;
mysql> show index from stu2\G;
*************************** 1. row ***************************
Table: stu2
Non_unique: 0
Key_name: PRIMARY
Seq_in_index: 1
Column_name: id
Collation: A
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
Expression: NULL
*************************** 2. row ***************************
Table: stu2
Non_unique: 0
Key_name: indx_phone
Seq_in_index: 1
Column_name: phone
Collation: A
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
Expression: NULL
*************************** 3. row ***************************
Table: stu2
Non_unique: 1
Key_name: idx_name
Seq_in_index: 1
Column_name: name
Collation: A
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
Expression: NULL
3 rows in set (0.00 sec)
删除索引:
drop index 索引名 on 表名
示例:删除stu2表上字段name和phone上的索引
mysql> drop index idx_name on stu2;
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> drop index indx_phone on stu2;
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc stu2;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| name | varchar(30) | NO | | NULL | |
| phone | char(11) | NO | | NULL | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
主键(PRI)和自增长(AUTO_INCREMENT)
使用规则
- 一个表只能有一个主键字段
- 所带约束:不允许重复,且不能为空
- KEY标志(primary): PRI
- 通常设置记录编号字段id,能唯一索引一条记录
创建
创建表时添加主键
create table 表名(
字段1 int auto_increment,
....
primary key(字段1)
)auto_increment=起始值; ## 设置自增和起始值
示例:
mysql> create table stu3(
-> id int auto_increment,
-> name varchar(30) not null,
-> primary key(id)
-> )engine=innodb charset=utf8mb4 auto_increment=10000;
Query OK, 0 rows affected (0.04 sec)
mysql> desc stu3 ;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| name | varchar(30) | NO | | NULL | |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
mysql> select * from stu3;
+-------+----------+
| id | name |
+-------+----------+
| 10000 | zhangsan |
| 10001 | lisi |
+-------+----------+
2 rows in set (0.00 sec)
已有表添加主键
alter table 表名 add primay key(id)
示例:
mysql> create table stu4(
-> id int,
-> name varchar(30)
-> )engine=innodb charset=utf8mb4;
Query OK, 0 rows affected (0.04 sec)
mysql> alter table stu4 add primary key(id);
Query OK, 0 rows affected (0.07 sec)
Records: 0 Duplicates: 0 Warnings: 0
已有表操作自增长属性
1、已有表增加自增长属性:alter table 表名 moidfy id int auto_increment;
mysql> create table stu5(
-> id int,
-> name varchar(30)
-> );
Query OK, 0 rows affected (0.03 sec)
mysql> create index idx_id on stu5(id); //在stu5表的id字段上添加索引
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> alter table stu5 modify id int auto_increment; //修改id字段为自增
Query OK, 0 rows affected (0.10 sec)
Records: 0 Duplicates: 0 Warnings: 0
2、已有表重新指定起始值:alter table 表名 auto_increment=20000;
mysql> alter table stu5 auto_increment=20000;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
删除
1、删除自增长属性(modify):alter table 表名 id int;
mysql> create table stu6(
-> id int auto_increment,
-> name varchar(30),
-> primary key(id)
-> )auto_increment=20000;
Query OK, 0 rows affected (0.04 sec)
mysql> alter table stu6 modify id int;
Query OK, 0 rows affected (0.14 sec)
Records: 0 Duplicates: 0 Warnings: 0
2、删除主键索引:alter table 表名 drop primary key;
mysql> alter table stu6 drop primary key;
Query OK, 0 rows affected (0.09 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc stu6;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int | NO | | NULL | |
| name | varchar(30) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)