MySQL索引与事务

MySQL索引与事务

技能目标

  • 理解索引的概念并掌握索引的创建
  • 理解事务的盖帘并掌握事务的操作

索引的概念及分类

1:索引的概念
  • 索引是一种特殊的文件,包含着对数据表中所有记录的引用指针
2:索引的作用
  • 建立索引的目的是加快对表中记录的查找或顺序
(1) 设置了适合的索引之后,数据库利用各种快速的定位技术,可以大大加快查询速度,这也是创建索引的主要元婴
(2) 当表很大时,或者涉及多个表时,使用索引可使查询速度加快成千倍
(3) 可以降低数据库中IO成本并且索引还可以降低数据库的排序成本
(4) 通过建立唯一索引,可以保证数据库表中每一行数据的唯一性
(5) 可以加快表与表中的连接
(6) 使用分组和排序子句进行数据查询时,可以显著减少查询中分组和排序的时间
3:索引的分类
MySQL的索引分为以下几类:
  • 普通索引,这是最基本的索引类型,而且没有唯一性的限制
  • 唯一性索引,这与前面的普通索引基本相同唯一不同在于索引的列所有值只能出现一次,不允许有空值
  • 主键索引,主键索引是一种唯一性的索引,但它必须指定“PRIMARY KEY”。
  • 全文索引,索引类型为FULLTEXT,全文索引可以在CHAR VARCHAR或者TEXT类型的列上创建
  • 单列多列索引,索引是单列上创建的索引,也可以是在多列上创建的索引

索引详细信息

显示参数 描述
Table 表的名称
Non_unique 索引值的唯一性,0表示唯一性,1表示非唯一
Key_name 索引的名称
Seq_in_index 索引中的序列号从1开始
Column_name 列名称

实验

1:创建索引的方法
创建普通索引的命令格式
ceate index<索引的名字>no tablename(列的列表)
  • 准备了一个数据库(学员信息)里面有里面创建了(班级学员信息表)
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| 学员信息           |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)
mysql> use 学院信息;
mysql> create table 班级学员信息(学号 int,名字 varchar(10),分数 int,爱好 varchar(10)); 
mysql> select * from 班级学员信息;
+--------+--------+--------+--------+
| 学号   | 名字   | 分数   | 爱好   |
+--------+--------+--------+--------+
|      1 | 张三   |     88 | 1      |
|      2 | 李四   |     88 | 2      |
|      3 | 王五   |     88 | 1      |
+--------+--------+--------+--------+
3 rows in set (0.00 sec)

mysql> create index name_index on 班级学员信息(学号); #创建普通索引实例
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0
mysql> show index from 班级学员信息; #查看索引信息
+--------------------+------------+------------+--------------+-------------+---------
--+-------------+----------+--------+------+------------+---------+---------------+
| Table              | Non_unique | Key_name   | Seq_in_index | Column_name | Collatio
n | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------------------+------------+------------+--------------+-------------+---------
--+-------------+----------+--------+------+------------+---------+---------------+
| 班级学员信息       |          1 | name_index |            1 | 学号        | A       
  |           3 |     NULL | NULL   | YES  | BTREE      |         |               |
+--------------------+------------+------------+--------------+-------------+---------
--+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.00 sec)
  • 上图key_name对应的是索引名字(名字为name_index),Non_unique对应值是1表示不是唯一索引
创建唯一索引的命令格式
create unique index<索引的名字>on tablename(列的列表)
  • 该索引比普通索引多了一个unique关键字,下面对名字创建唯一性索引
mysql> create unique index name_unique_index on 班级学员信息(名字);
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0
mysql> show index from 班级学员信息;
+--------------------+------------+-------------------+--------------+-------------+-----------+-------------+----------+--
------+------+------------+---------+---------------+
| Table              | Non_unique | Key_name          | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | P
acked | Null | Index_type | Comment | Index_comment |
+--------------------+------------+-------------------+--------------+-------------+-----------+-------------+----------+--
------+------+------------+---------+---------------+
| 班级学员信息       |          0 | name_unique_index |            1 | 名字        | A         |           3 |     NULL | N
ULL   | YES  | BTREE      |         |               |
+--------------------+------------+-------------------+--------------+-------------+-----------+-------------+----------+--
------+------+------------+---------+---------------+
1 row in set (0.00 sec)
  • 上图名为name_unique_index的索引已创建,他的Non_unique为0,表示唯一性索引
创建主键索引有两种方式
1):在创建表的同时创建主键,2):在已经创建的表中没有指定主键,然后修改表加入主键,主键索引会自动创建
创建主键索引的命令格式
1):创建表格的同时指定主键
create table tablename([...],primary key(列的列表));
mysql> show tables;                    #在学员信息里面有三个表现在我重新创建一个新表在创建新编的同时定义主键
+------------------------+
| Tables_in_学员信息     |
+------------------------+
| 学生爱好               |
| 爱好                   |
| 班级学员信息           |
+------------------------+
3 rows in set (0.00 sec)

mysql> create table 学生兴趣 (编号 int(4)primary key, 爱好 varchar(10));
Query OK, 0 rows affected (0.01 sec)

mysql> desc 学生兴趣;               #创建了主键的表看一下两者区别创建主键的表Key里面多一个PRI
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| 编号   | int(4)      | NO   | PRI | NULL    |       |
| 爱好   | varchar(10) | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> desc 爱好;                #原有的表没有创建主键的表没有创建主键的表Key里面是空的
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| 编号   | int(4)      | YES  |     | NULL    |       |
| 爱好   | varchar(10) | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
2):创建表格之后没有创建主键修改该表格后加入主键格式主键索引会自动创建:
alter table tablename add primary key(列的列表);
mysql> create table 学生爱好 (编号 int(4), 爱好 varchar(10));
Query OK, 0 rows affected (0.01 sec)

mysql> desc 学生爱好;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| 编号   | int(4)      | YES  |     | NULL    |       |
| 爱好   | varchar(10) | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> alter table 学生爱好 add constraint pk_id primary key 学生爱好 (编号); 
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc 学生爱好;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| 编号   | int(4)      | NO   | PRI | NULL    |       |
| 爱好   | varchar(10) | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
创建多列索引只需要在创建索引的时候制定多列即可命令格式为
create index duolie_index on 班级学员信息(学号,名字);
mysql> create index duolie_index on 班级学员信息(学号,名字);
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> show index from 班级学员信息;
+--------------------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table              | Non_unique | Key_name     | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------------------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| 班级学员信息       |          1 | duolie_index |            1 | 学号        | A         |           3 |     NULL | NULL   | YES  | BTREE      |         |               |
| 班级学员信息       |          1 | duolie_index |            2 | 名字        | A         |           3 |     NULL | NULL   | YES  | BTREE      |         |               |
+--------------------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
2 rows in set (0.00 sec)

mysql> alter table 班级学员信息 drop column 学号; #删除多列索引中其中一个索引
Query OK, 0 rows affected (0.04 sec)
Records: 0  Duplicates: 0  Warnings: 0
不需要索引时删除命令(大写为固定格式再mysql中不区分大小写)
  • DROP INDEX index_name ON table_name; #大写为固定格式index_name为索引名称table_name为删除哪张表格中的索引
  • ALTER TABLE table_name DROP INDEX index_name #删除那张表格的哪一个索引
  • ALTER TABLE table_name DORP PRIMARY KEY; #删除主键
查看索引放法
  • SHOW KEY FROM table_name
  • SHOW INDEX FROM table_name #在后面加上\G竖向显示索引信息即为:SHOW INDEX FROM table_name\G

主键和外键
(1) 主键
  • 数据表中每行记录都必须是唯一的,而不允许出现完全相同的记录,通过定义主键,可以保证记录(实体)的唯一性
  • 键,即是关键字,他是关系模型中非常重要的一个元素
  • 如果一个属性能有唯一的标识,没有多余的属性,那么这个属性集称为候选键
  • 从表中的主键是主表中的外键且数值唯一不能为空
(2)外键
  • 一个关系数据库通常包含多个表,通过外键可以使这些表关起来
  • 主表中的外键是从表中的主键且数值唯一不能为空
实验
下面有两张表上面一个是主表编号是主键爱好是外键下面一个是从表编号是主键
mysql> select * from 六年级二班学生数据表;
+--------+--------+--------+--------+
| 编号   | 姓名   | 学分   | 爱好   |
+--------+--------+--------+--------+
|      1 | 张三   |     80 |      1 |
|      2 | 李四   |     81 |      2 |
|      3 | 王五   |     81 |      3 |
|      4 | 赵六   |     99 |      2 |
+--------+--------+--------+--------+
4 rows in set (0.00 sec)

mysql> select * from 六年级二班兴趣爱好表;
+--------+-----------+
| 编号   | 爱好      |
+--------+-----------+
|      1 | 看书      |
|      2 | 玩游戏    |
|      3 | 游玩      |
|      4 | 打球      |
+--------+-----------+
4 rows in set (0.00 sec)
把上面两张表关联查询编号、姓名、学分、爱好,用一张表的形式去显示实际这张表不存在的
mysql> select i.编号,i.姓名,i.学分,h.爱好 from 六年级二班学生数据表 i join 六年级二班兴趣爱好表 h on i.爱好=
+--------+--------+--------+-----------+
| 编号   | 姓名   | 学分   | 爱好      |
+--------+--------+--------+-----------+
|      1 | 张三   |     80 | 看书      |
|      2 | 李四   |     81 | 玩游戏    |
|      4 | 赵六   |     99 | 玩游戏    |
|      3 | 王五   |     81 | 游玩      |
+--------+--------+--------+-----------+
4 rows in set (0.00 sec)

MySQL 数据库事务

2:事物的概念及特点
事务是一种机制,一个操作序列,包含了一组数据库操作命令,并且把所有命令作为一个整体一起向系统提交或撤销操作请求,即这一组命令要么执行要么撤销。事务是一个不可分割的逻辑单元,在数据库系统上执行并发操作时事务是做小的控制单元。
事务的ACID特性
  • 原子性:事务是一个完整的操作,个元素是不可分的,即原子的
  • 一致性:当事务完成时事务必须处于同一个状态
  • 隔离性:对事物进行修改的所有并发事务是彼此隔离的,每个事物都是单独存在的
  • 持久性:指不管系统是否发生故障,事务处理的结果都是永久的
使用事务命令控制事务
  • begin 表示开始一个事务,后面会有多条数据操作语句执行
  • commit 表示提交事务,对应前面begin操作
  • rollback 表示回滚一个事务,再begin和commit之间如果某一个数据库操作语句出现错误,执行rollback回滚数据回到begin之前的状态

实验

用begin在学院班级息里面六年级二班学生数据表中再添加一个人员
mysql> create database 数据;
Query OK, 1 row affected (0.00 sec)

mysql> use 数据;
Database changed
mysql> use 学院班级信息;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql>insert
    -> into 六年级二班学生数据表 values (5,'田七',2,1); #在表中插入这段信息
Query OK, 1 row affected (0.00 sec)
mysql> select
    -> * from 六年级二班学生数据表;
+--------+--------+--------+--------+
| 编号   | 姓名   | 学分   | 爱好   |
+--------+--------+--------+--------+
|      1 | 张三   |     80 |      1 |
|      2 | 李四   |     81 |      2 |
|      3 | 王五   |     81 |      3 |
|      4 | 赵六   |     99 |      2 |
|      5 | 田七   |      2 |      1 |
+--------+--------+--------+--------+
5 rows in set (0.00 sec)  #查看表中数据有田七这个人员信息
#我们另开一个终端登入数据库再查看表的信息
mysql> select * from 六年级二班学生数据表;
+--------+--------+--------+--------+
| 编号   | 姓名   | 学分   | 爱好   |
+--------+--------+--------+--------+
|      1 | 张三   |     80 |      1 |
|      2 | 李四   |     81 |      2 |
|      3 | 王五   |     81 |      3 |
|      4 | 赵六   |     99 |      2 |
+--------+--------+--------+--------+
4 rows in set (0.00 sec)
#从另一个终端的数据库看不到田七数据因为begin只是开始一个事务并没有提交
#想要提交事务用commit提交 如果怕后面出错可以在这边进行一个留档
mysql> savepoint s1;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into 六年级二班学生数据表 values (6,'黑八',77,4);
Query OK, 1 row affected (0.00 sec)

mysql> savepoint s2;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from 六年级二班学生数据表;
+--------+--------+--------+--------+
| 编号   | 姓名   | 学分   | 爱好   |
+--------+--------+--------+--------+
|      1 | 张三   |     80 |      1 |
|      2 | 李四   |     81 |      2 |
|      3 | 王五   |     81 |      3 |
|      4 | 赵六   |     99 |      2 |
|      5 | 田七   |      2 |      1 |
|      6 | 黑八   |     77 |      4 |
+--------+--------+--------+--------+
6 rows in set (0.00 sec)
#如果再第二个留档中出错了用rollback to savepoint s1;
mysql> rollback to savepoint s1;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from 六年级二班学生数据表;
+--------+--------+--------+--------+
| 编号   | 姓名   | 学分   | 爱好   |
+--------+--------+--------+--------+
|      1 | 张三   |     80 |      1 |
|      2 | 李四   |     81 |      2 |
|      3 | 王五   |     81 |      3 |
|      4 | 赵六   |     99 |      2 |
|      5 | 田七   |      2 |      1 |
+--------+--------+--------+--------+
5 rows in set (0.00 sec)
#此时留档二中的黑八就叫已经不存在了,注:回滚到上一个s1的留档的位置那么从s1下面所有操作的事务全都不存在了
用set sutocommit=0关闭自动提交
mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into 六年级二班学生数据表 values (6,'黑八',77,4);
Query OK, 1 row affected (0.00 sec)

mysql> select * from 六年级二班学生数据表;
+--------+--------+--------+--------+
| 编号   | 姓名   | 学分   | 爱好   |
+--------+--------+--------+--------+
|      1 | 张三   |     80 |      1 |
|      2 | 李四   |     81 |      2 |
|      3 | 王五   |     81 |      3 |
|      4 | 赵六   |     99 |      2 |
|      6 | 黑八   |     77 |      4 |
+--------+--------+--------+--------+
5 rows in set (0.00 sec)
#上表关闭了自动提交功能然后操作事务不会自动提交相当于执行了begin同样在另一个终端登录的时候不会显示出来
#如果set autocommit=1开启自动提交那么以上正在进行的事务自动提交相当于执行了begin语句中的commit

本次实验总结

  • 数据库索引分为:普通索引,唯一索引,主键索引,全文索引,多列索引
  • 数据库索引可以协助快速查询表中数据,但并不是任何字段都是和索引(数据至少不少于1000行才能看出效果)
  • 数据库事物的ACID特性
  • MySQL事务命令有begin、rollback、commit、savrpoint。

猜你喜欢

转载自blog.51cto.com/13645280/2133337