目录
一、索引
1、索引的概念
2、索引的作用
3、索引的副作用
4、创建索引的原则依据
二、索引的分类
1、普通索引
1.直接创建索引
2.修改方式创建索引
3.创建表的时候指定索引
2、唯一索引
1.直接创建唯一索引
2.修改表方式创建索引
3.创建表的时候指定索引
3、主键索引
1.创建表的时候指定索引
2.修改表方式创建索引
4、组合索引(单列索引与多列索引)
创建表名时创建索引
5、全文索引(FULLTEXT)
1.直接创建索引
2.修改方式创建
3.创建表的时候指定索引
4.使用全文索引查询
6、查看索引
7、删除索引
1.直接删除索引
2.修改表方式删除索引
3.删除主键索引
三、事务
1、事务的概念:
2、事务的特点(ACID):
1.原子性
2.一致性
3.隔离性
4.持久性
总结:
一、索引
1、索引的概念
- 是一个排序的列表,存储着索引值和这个值所对应的物理地址。
- 无须对整个表进行扫描,通过物理地址就可以找所需要的数据
- 是表中一列或着若干列值排序的方法
- 需要额外的磁盘空间
- 索引就好比是一本书的目录,可以根据目录中的页码快速找到所需要的内容
- 建立索引的目的就是加快对表中记录的快速查找或排序
优点:
缺点:
小总结:
2、索引的作用
- 设置了合适的索引之后,数据库利用各种快速定位技术,能够大大加快速度,这是创建索引的最主要的原因
- 当表很大或查询涉及到多个表时,可以成千上万倍地提高查询速度
- 可以降低数据库的I/O成本,并且还可以降低数据库的排序成本
- 通过创建唯一性索引保证数据表数据的唯一性
- 可以加快表与表之间的连接
- 在使用分组和排序时,可大大减少分组和排序时间
3、索引的副作用
- 索引需要占用额外的磁盘空间
对于MyISAM引擎而言,索引文件和数据文件是分离的,索引文件用于报讯数据记录的地址。而InnoDB引擎的表数据文件本身就是索引文件。当表很大或查询设计到多表时,可以成千上万倍地提高查询速度。
- 在插入和修改数据时要花费更多的时间,因为索引也要随之变动。
4、创建索引的原则依据
优点:
- 经常出现在where子句中的字段,特别是大表的字段,应该建立索引
- 索引应该建在选择性高的字段上
- 索引应该建在小字段上,对于大的文本字段甚至超长字段,不要建索引
缺点:
- 表的主键、外键必须有索引
- 记录数超过300行的表应该有索引
- 经常与其他表进行连接的表,在连接字段上应该建立索引
- 唯一性太差的字段不适合建立索引
- 更新太频繁地字段不适合创建索引
二、索引的分类
1、普通索引
- 最基本的索引方式,没有唯一性之类的限制
- 创建普通索引的方式
create index 索引名 on 表名 (列名); ###index索引
###直接创建索引
alter table 表名 add index 索引名 (列名);
###修改方式创建索引
create table 表名 (字段1 数据类型,字段2 数据类型, ... index 索引名(列名));
###创建表的时候指定索引
###创建索引名,建议以"_index"为结尾
先创建数据库及数据表
mysql> create database kgc;
use kgc
show tables;
Empty set (0.00 sec)
create table kysw (id int(6),name char(8) not null,cardid varchar(18),phone varchar(11),address char(40),remark text);
Query OK, 0 rows affected (0.01 sec)
mysql> insert into kysw values(1,'Jordon',123456,111111,'chicago','he is NBA superstar');
Query OK, 1 row affected (0.00 sec)
mysql> insert into kysw values(2,'James',1234567,222222,'akron','he is NBA superstar');
Query OK, 1 row affected (0.00 sec)
mysql> insert into kysw values(3,'kobe',12345678,333333,'los angeles','he is NBA superstar');
Query OK, 1 row affected (0.00 sec)
mysql> insert into kysw values(4,'yaoming',123456789,444444,'china','he is NBA super center forward');
Query OK, 1 row affected (0.00 sec)
mysql> insert into kysw values(5,'curry',987654,555555,'america','he is NBA super scorer');
Query OK, 1 row affected (0.00 sec)
mysql> insert into kysw values(6,'oneal',9876543,666666,'america','he is NBA super center forward');
Query OK, 1 row affected (0.00 sec)
mysql> insert into kysw values(7,'wade',98765432,777777,'america','he is NBA super scorer');
Query OK, 1 row affected (0.00 sec)
mysql> insert into kysw values(8,'durante',987654321,888888,'america','he is NBA super scorer');
Query OK, 1 row affected (0.00 sec)
mysql> select * from kysw;
+------+---------+-----------+--------+-------------+--------------------------------+
| id | name | cardid | phone | address | remark |
+------+---------+-----------+--------+-------------+--------------------------------+
| 1 | Jordon | 123456 | 111111 | chicago | he is NBA superstar |
| 2 | James | 1234567 | 222222 | akron | he is NBA superstar |
| 3 | kobe | 12345678 | 333333 | los angeles | he is NBA superstar |
| 4 | yaoming | 123456789 | 444444 | china | he is NBA super center forward |
| 5 | curry | 987654 | 555555 | america | he is NBA super scorer |
| 6 | oneal | 9876543 | 666666 | america | he is NBA super center forward |
| 7 | wade | 98765432 | 777777 | america | he is NBA super scorer |
| 8 | durante | 987654321 | 888888 | america | he is NBA super scorer |
+------+---------+-----------+--------+-------------+--------------------------------+
8 rows in set (0.00 sec)
mysql> desc kysw;
+---------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| id | int(6) | YES | | NULL | |
| name | char(8) | NO | | NULL | |
| cardid | varchar(18) | YES | | NULL | |
| phone | varchar(11) | YES | | NULL | |
| address | char(40) | YES | | NULL | |
| remark | text | YES | | NULL | |
+---------+-------------+------+-----+---------+-------+
6 rows in set (0.00 sec)
1.直接创建索引
create index 索引名 on 表名 (列名); ###index索引
###直接创建索引
mysql> create index address_index on kysw(address); ###地址为索引
Query OK, 0 rows affected (0.01 sec)
mysql> show create table kysw;
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| kysw | CREATE TABLE "kysw" (
"id" int(6) DEFAULT NULL,
"name" char(8) NOT NULL,
"cardid" varchar(18) DEFAULT NULL,
"phone" varchar(11) DEFAULT NULL,
"address" char(40) DEFAULT NULL,
"remark" text,
KEY "address_index" ("address")
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
2.修改方式创建索引
alter table 表名 add index 索引名 (列名);
###修改方式创建索引
mysql> alter table kysw add index phone_index (phone); ###修改方式创建索引
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table kysw; ###查看
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| kysw | CREATE TABLE "kysw" (
"id" int(6) DEFAULT NULL,
"name" char(8) NOT NULL,
"cardid" varchar(18) DEFAULT NULL,
"phone" varchar(11) DEFAULT NULL,
"address" char(40) DEFAULT NULL,
"remark" text,
KEY "address_index" ("address"),
KEY "phone_index" ("phone")
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
3.创建表的时候指定索引
create table 表名 (字段1 数据类型,字段2 数据类型, ... index 索引名(列名));
###创建表的时候指定索引
mysql> create table test01(id int(3) not null,name varchar(6),cardid char(20) not null,index name_index(name));
Query OK, 0 rows affected (0.00 sec)
mysql> show create table test01;
+--------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+--------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| test01 | CREATE TABLE "test01" (
"id" int(3) NOT NULL,
"name" varchar(6) DEFAULT NULL,
"cardid" char(20) NOT NULL,
KEY "name_index" ("name")
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+--------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
2、唯一索引
- 与普通索引类似,单区别是唯一索引列的每个值都唯一
- 唯一索引允许有空值(注意和主键不同),如果是用组合索引创建,则列值的组合必须唯一,添加唯一键将自动创建唯一索引
1.直接创建唯一索引
●直接创建唯一索引
CREATE UNIQUE INDEX 索引名 ON 表名(列名);
mysql> create unique index name_index on kysw(name);
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table kysw;
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| kysw | CREATE TABLE "kysw" (
"id" int(6) DEFAULT NULL,
"name" char(8) NOT NULL,
"cardid" varchar(18) DEFAULT NULL,
"phone" varchar(11) DEFAULT NULL,
"address" char(40) DEFAULT NULL,
"remark" text,
UNIQUE KEY "name_index" ("name"),
KEY "address_index" ("address"),
KEY "phone_index" ("phone")
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
2.修改表方式创建索引
ALTER TABLE 表名 ADD UNIQUE 索引名 (列名);
mysql> alter table kysw add unique cardid_index (cardid);
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table kysw;
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| kysw | CREATE TABLE "kysw" (
"id" int(6) DEFAULT NULL,
"name" char(8) NOT NULL,
"cardid" varchar(18) DEFAULT NULL,
"phone" varchar(11) DEFAULT NULL,
"address" char(40) DEFAULT NULL,
"remark" text,
UNIQUE KEY "name_index" ("name"),
UNIQUE KEY "cardid_index" ("cardid"),
KEY "address_index" ("address"),
KEY "phone_index" ("phone")
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
3.创建表的时候指定索引
CREATE TABLE 表名 (字段1 数据类型,字段2 数据类型[,...],UNIQUE 索引名 (列名));
mysql> create table test02 (id int,name char(6),unique id_index (id));
Query OK, 0 rows affected (0.00 sec)
mysql> show create table test02;
+--------+---------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+--------+---------------------------------------------------------------------------------------------------------------------------------------------------------+
| test02 | CREATE TABLE "test02" (
"id" int(11) DEFAULT NULL,
"name" char(6) DEFAULT NULL,
UNIQUE KEY "id_index" ("id")
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+--------+---------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
3、主键索引
- 是一种特殊的唯一索引,必须指定为“PRIMARY KEY”。
- 一个表只能有一个主键,不允许有空值。添加主键将自动创建主键索引。
1.创建表的时候指定索引
CREATE TABLE 表名 ([...],PRIMARY KEY (列名));
mysql> create table test03 (id int,name char(6),primary key(id));
Query OK, 0 rows affected (0.01 sec)
mysql> show create table test03;
+--------+-------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+--------+-------------------------------------------------------------------------------------------------------------------------------------------+
| test03 | CREATE TABLE "test03" (
"id" int(11) NOT NULL,
"name" char(6) DEFAULT NULL,
PRIMARY KEY ("id")
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+--------+-------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
2.修改表方式创建索引
ALTER TABLE 表名 ADD PRIMARY KEY (列名);
4、组合索引(单列索引与多列索引)
- 可以是单列上创建的索引,也可以是在多列上创建的索引。
- 需要满足最左原则,因为select语句的 where条件是依次从左往右执行的,所以在使用select 语句查询时where条件使用的字段顺序必须和组合索引中的排序一致,否则索引将不会生效。
创建表名时创建索引
CREATE TABLE 表名 (列名1 数据类型,列名2 数据类型,列名3 数据类型,INDEX 索引名 (列名1,列名2,列名3));
mysql> create table test04 (id int not null,name varchar(10),cardid char(20),index index_test04(name,id));
Query OK, 0 rows affected (0.01 sec)
mysql> show create table test04;
+--------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+--------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| test04 | CREATE TABLE "test04" (
"id" int(11) NOT NULL,
"name" varchar(10) DEFAULT NULL,
"cardid" char(20) DEFAULT NULL,
KEY "index_test04" ("name","id")
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+--------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
小结:
组合索引创建的字段顺序是其触发索引的查询顺序
注意:#####*********######
例如:
对以上的表进行select
select id,name from test04; #会触发组合索引
但是
select name,id from test04; #按照索引从左到右检索的顺序,则不会触发组合索引
5、全文索引(FULLTEXT)
- 适合在进行模糊查询的时候使用,可用于在一篇文章中检索文本信息。
1.直接创建索引
###格式:
CREATE FULLTEXT INDEX 索引名 ON 表名 (列名);
mysql> create fulltext index remark_index on kysw (remark);
Query OK, 0 rows affected, 1 warning (0.07 sec)
Records: 0 Duplicates: 0 Warnings: 1
mysql> show create table kysw;
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| kysw | CREATE TABLE "kysw" (
"id" int(6) DEFAULT NULL,
"name" char(8) NOT NULL,
"cardid" varchar(18) DEFAULT NULL,
"phone" varchar(11) DEFAULT NULL,
"address" char(40) DEFAULT NULL,
"remark" text,
UNIQUE KEY "name_index" ("name"),
UNIQUE KEY "cardid_index" ("cardid"),
KEY "address_index" ("address"),
KEY "phone_index" ("phone"),
FULLTEXT KEY "remark_index" ("remark")
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)
mysql> select * from kysw where remark='he is NBA super scorer';
+------+---------+-----------+--------+---------+------------------------+
| id | name | cardid | phone | address | remark |
+------+---------+-----------+--------+---------+------------------------+
| 5 | curry | 987654 | 555555 | america | he is NBA super scorer |
| 8 | durante | 987654321 | 888888 | america | he is NBA super scorer |
| 7 | wade | 98765432 | 777777 | america | he is NBA super scorer |
+------+---------+-----------+--------+---------+------------------------+
3 rows in set (0.01 sec)
2.修改方式创建
ALTER TABLE 表名 ADD FULLTEXT 索引名 (列名);
mysql> select * from test04;
+----+------+--------+
| id | name | cardid |
+----+------+--------+
| 1 | lb | 111111 |
| 2 | gy | 222222 |
| 3 | zf | 333333 |
+----+------+--------+
3 rows in set (0.00 sec)
mysql> alter table test04 add fulltext name_index (name);
Query OK, 0 rows affected, 1 warning (0.05 sec)
Records: 0 Duplicates: 0 Warnings: 1
mysql> select name from test04;
+------+
| name |
+------+
| gy |
| lb |
| zf |
+------+
3 rows in set (0.00 sec)
3.创建表的时候指定索引
CREATE TABLE 表名 (字段1 数据类型[,...],FULLTEXT 索引名 (列名));
mysql> create table test03(id int not null,name char(6),fulltext name_index (name));
Query OK, 0 rows affected (0.58 sec)
4.使用全文索引查询
SELECT * FROM 表名 WHERE MATCH(列名) AGAINST('查询内容');
例:select * from kysw where match(remark) against(' he is NBA super scorer ');
or select * from kysw where remark=' he is NBA super scorer ';
6、查看索引
show index from 表名;
show index from 表名\G; 竖向显示表索引信息
show keys from 表名;
show keys from 表名\G;
各字段的含义如下:
Table 表的名称
Non_unique 如果索引内容唯一,则为 0;如果可以不唯一,则为 1。
Key_name 索引的名称。
Seq_in_index 索引中的列序号,从 1 开始。 limit 2,3
Column_name 列名称。
Collation 列以什么方式存储在索引中。在 MySQL 中,有值‘A’(升序)或 NULL(无分类)。
Cardinality 索引中唯一值数目的估计值。
Sub_part 如果列只是被部分地编入索引,则为被编入索引的字符的数目(zhangsan)。如果整列被编入索引,则为 NULL
Packed 指示关键字如何被压缩。如果没有被压缩,则为 NULL。
Null 如果列含有 NULL,则含有 YES。如果没有,则该列含有 NO。
Index_type 用过的索引方法(BTREE, FULLTEXT, HASH, RTREE)。
Comment 备注。
mysql> show index from kysw; ###这两个相等
mysql> show keys from kysw;
mysql> show index from kysw\G ###竖向显示表索引信息
小结:
索引分为:
① 普通索引 :针对所有字段,没有特殊的需求/规则
② 唯一索引 : 针对唯一性的字段,仅允许出现一次空值
③ 组合索引 (多列/多字段组合形式的索引)
④ 全文索引(varchar char text)MySQL为了优化对文本内容搜索的一种机制
⑤ 主键索引 :针对唯一性字段、且不可为空,同时一张表只允许包含一个主键索引
创建索引:
① 在创建表的时候,直接指定index
② alter修改表结构的时候,进行add 添加index
③ 直接创建索引index
PS:主键索引——》直接创建主键即可
7、删除索引
1.直接删除索引
DROP INDEX 索引名 ON 表名;
例:drop index name_index on kysw; ###删除name索引
show create table kysw;
2.修改表方式删除索引
ALTER TABLE 表名 DROP INDEX 索引名;
例:alter table kysw drop index cardid_index;
show create table kysw;
3.删除主键索引
ALTER TABLE 表名 DROP PRIMARY KEY;
例:alter table test03 drop primary key;
三、事务
1、事务的概念:
- MySQL 事务主要用于处理操作量大,复杂度高的数据
- 事务是一种机制、一个操作序列,包含了一组数据库操作命令,并且把所有的命令作为一个整体一起向系统提交或撤销操作请求,即这一组数据库命令要么都执行,要么都不执行。
- 事务是一个不可分割的工作逻辑单元,在数据库系统上执行并发操作时,事务是最小的控制单元。
- 事务适用于多用户同时操作的数据库系统的场景,如银行、保险公司及证券交易系统等等。
- 事务是通过事务的整体性以保证数据的一致性。
说白了,所谓事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。
MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中, 要删除一个人员,即需要删除人员的基本资料,又需要删除和该人员相关的信息,如信箱, 文章等等。这样,这些数据库操作语句就构成一个事务!
2、事务的特点(ACID):
1.原子性
- 指事务是一个不可再分割的工作单位,事务中的操作要么都发生,要么都不发生。
事务是一个完整的操作,事务的各元素是不可分的。
事务中的所有元素必须作为一个整体提交或回滚。
如果事务中的任何元素失败,则整个事务将失败。
2.一致性
- 指在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。
当事务完成时,数据必须处于一致状态。
在事务开始前,数据库中存储的数据处于一致状态。
在正在进行的事务中,数据可能处于不一致的状态。
当事务成功完成时,数据必须再次回到已知的一致状态。
3.隔离性
- 指在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。
对数据进行修改的所有并发事务是彼此隔离的,表明事务必须是独立的,它不应以任何方式依赖于或影响其他事务。
修改数据的事务可在另一个使用相同数据的事务开始之前访问这些数据,或者在另一个使用相同数据的事务结束之后访问这些数据。
4.持久性
- 在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。
指不管系统是否发生故障,事务处理的结果都是永久的。
一旦事务被提交,事务的效果会被永久地保留在数据库中。
总结:
MySQL 的优化 哪些字段/场景适合创建索引,哪些不适合
1、小字段
2、唯一性强的字段
3、更新不频繁,但查询率很高的字段
4、表记录超过300+行
5、主键、外键、唯一键组合索引创建的字段顺序是其触发索引的查询顺序
select id,name from test3; #会触发组合索引
而:
select name,id from test3; #按照索引从左到右检索的顺序,则不会触发组合索引
索引分为:
① 普通索引 :针对所有字段,没有特殊的需求/规则
② 唯一索引 : 针对唯一性的字段,仅允许出现一次空值
③ 组合索引 (多列/多字段组合形式的索引)
④ 全文索引(varchar char text)MySQL为了优化对文本内容搜索的一种机制
⑤ 主键索引 :针对唯一性字段、且不可为空,同时一张表只允许包含一个主键索引创建索引:
① 在创建表的时候,直接指定index
② alter修改表结构的时候,进行add 添加index
③ 直接创建索引index
PS:主键索引——》直接创建主键即可