目录
一.数据库索引基础
索引的概念
- 索引是一种特殊的文件,包含着数据表中所有记录的引用指针。即数据库索引相当于一本书的目录,能够加快数据库的查询速度。数据库索引就是为了提高表的搜索效率而对某些字段的值建立起来的目录
索引的作用
- 建立索引的目的是为了加快对表中记录的查找或排序。为表设置索引要付出代价:一是增加了数据库的存储空间,二是在插入和修改数据时要花费比较多的时间(索引也要随之变动)。
- 设置了合适的索引之后,数据利用各种快速的定位技术,可以大大加快数据的查询速度,这是创建索引的最主要的原因
- 当表很大时,或者查询多个表时,使用索引的可以加快查询速度
- 索引也可以降低数据库的I/O成本,并且索引还可以降低数据库的排序成本
- 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性
- 索引可以加快表与表之间的连接
- 在使用分组和排序子句进行数据查询时,可以显著减少查询中分组和排序的时间
索引的分类(MySQL)
- 普通索引,这是最基本的索引类型,而且它没有唯一性之类的限制
- 唯一性索引,这种索引和前面“普通索引”基本相同,但有一个区别:索引列的所有值只能出现一次,即必须唯一
- 主键索引,主键是一种唯一性索引,但是它必须指定为“primary key”。在数据库中表定义主键将自动创建主键索引,主键索引是唯一索引的特定类型
- 全文索引,索引类型为 fulltext,全文索引可以在char、varchar 或者 text 类型的列上创建
- 单索引与多列索引,索引可以是单列上创建的索引,可以是在多列上创建的索引。而且多列索引可以区分其中一列可能相同值的行
创建索引的原则依据
- 表的主键、外键必须有外键。主键具有唯一性,索引值也是唯一的,查询时可以快速定位到数据行。外键一般关联的是另一个表的主键,所以在多表查询的时候也可以快速定位
- 数据量超过300行的表应该有索引。数据量较大时,如果没有索引,需要把表遍历一遍,严重影响数据库的性能
- 经常与其他数据表进行表连接的数据表,在连接字段上应该建立索引
- 唯一性太差的字段不合适建立索引
- 更新太频繁的字段不适合创建索引。在表中进行增、删、改时,索引也应该有相应的操作。字段更新的过于频繁,对于系统的资源占用也会更多
- 经常出现在Where语句的字段,应该建立索引
- 索引应该建在选择性高的字段上。如果很少的字段拥有相同值,即有很多独特值,则选择性很高
- 索引应该建立在小字段上,对于大的文本字段甚至超长字段,不要建立索引
二.创建索引与查看索引
安装MySQL5.6版本,创建
##解压数据包
tar xzvf mysql-5.6.26.tar.gz -C /opt
##下载必要安装包
yum install -y ncurses-devel \
autoconf cmake \
zlib-devel make \
gcc \
gcc-c++ \
make
##配置功能模块
cd /opt/mysql-5.6.26/
cmake \
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci \
-DEXTRA_CHARSETS=all \
-DSYSCONFIDIR=/etc \
-DMYSQL_DATADIR=/home/mysql/ \
-DMYSQL_UNIX_ADDR=/home/mysql/mysql.sock
##编译与安装
make && make install
##覆盖本机的数据库,和前面的配置文件的目录一致
cp support-files/my-default.cnf /etc/my.cnf
##启动脚本
cp support-files/mysql.server /etc/init.d/mysqld
##给予权限
chmod 755 /etc/init.d/mysqld
chkconfig --add /etc/init.d/mysqld
chkconfig mysqld --level 35 on
##设置环境变量,将启动脚本放到系统中
echo "PATH=$PATH:/usr/local/mysql/bin" >> /etc/profile
source /etc/profile
echo $PATH
##添加用户
useradd -s /sbin/nologin mysql
chown -R mysql:mysql /usr/local/mysql/
##初始化数据库,之前必须创建用户
/usr/local/mysql/scripts/mysql_install_db \
--user=mysql \
--ldata=/var/lib/mysql \
--basedir=/usr/local/mysql \
--datadir=/home/mysql
##创建socket文件的软链接
ln -s /var/lib/mysql/mysql.sock /home/mysql/mysql.sock
##修改启动脚本
vim /etc/init.d/mysqld
#指明工作路径
basedir=/usr/local/mysql
#数据存放位置
datadir=/home/mysql
service mysqld start
##mysql服务3306端口
netstat -anpt | grep 3306
##mysql用户创建密码
mysqladmin -u root -p password "abc123"
##进入数据库
mysql -u root -p
##创建数据库和数据表,添加数据记录
mysql> create database company;
Query OK, 1 row affected (0.02 sec)
mysql> use company
Database changed
mysql> create table company.info (岗位名称 char(10) not null,姓名 char(10) not null,年龄 int(3) not null,员工ID int(4) not null primary key, 学历 char(10) not null, 工作年限 int(2) not null, 薪资 int(6) not null);
Query OK, 0 rows affected (0.01 sec)
mysql> describe info;
+--------------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+----------+------+-----+---------+-------+
| 岗位名称 | char(10) | NO | | NULL | |
| 姓名 | char(10) | NO | | NULL | |
| 年龄 | int(3) | NO | | NULL | |
| 员工ID | int(4) | NO | PRI | NULL | |
| 学历 | char(10) | NO | | NULL | |
| 工作年限 | int(2) | NO | | NULL | |
| 薪资 | int(6) | NO | | NULL | |
+--------------+----------+------+-----+---------+-------+
7 rows in set (0.00 sec)
mysql> insert into info values("网络工程师","张三",24,1001,"本科",2,4800);
Query OK, 1 row affected (0.01 sec)
mysql> insert into info values("Linux工程师","李四",22,1002,"专科",1,3800);
Query OK, 1 row affected (0.00 sec)
mysql> insert into info values("Java工程师","王五",27,1003,"本科",5,15000);
Query OK, 1 row affected (0.00 sec)
mysql> insert into info values("云计算工程师","姜文",30,1004,"本科",8,25000);
Query OK, 1 row affected (0.01 sec)
mysql> insert into info values("大数据工程师","蓝凌",35,1005,"专科",10,23000);
Query OK, 1 row affected (0.00 sec)
mysql> select * from info;
+--------------------+--------+--------+----------+--------+--------------+--------+
| 岗位名称 | 姓名 | 年龄 | 员工ID | 学历 | 工作年限 | 薪资 |
+--------------------+--------+--------+----------+--------+--------------+--------+
| 网络工程师 | 张三 | 24 | 1001 | 本科 | 2 | 4800 |
| Linux工程师 | 李四 | 22 | 1002 | 专科 | 1 | 3800 |
| Java工程师 | 王五 | 27 | 1003 | 本科 | 5 | 15000 |
| 云计算工程师 | 姜文 | 30 | 1004 | 本科 | 8 | 25000 |
| 大数据工程师 | 蓝凌 | 35 | 1005 | 专科 | 10 | 23000 |
+--------------------+--------+--------+----------+--------+--------------+--------+
5 rows in set (0.00 sec)
mysql>
创建索引、查看索引
- 创建普通索引
- 创建唯一性索引
- 创建主键索引,有两种方式
一种是创建表的同时指定主键,主键索引会自动创建(primary key)
另一种是,创建表没有指定主键,然后修改表加入主键,主键索引会自动创建()
- 创建全文索引,在MySQL中使用全文索引,目前只有使用MyISAM类型表的时候有效(MyISAM为默认表类型)。全文索引可以建立在TEXT、CHAR、VARCHAR类型的字段或者字段组合上
- 创建多列索引
删除索引
mysql> show index from info;
+-------+------------+------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| info | 0 | PRIMARY | 1 | 员工ID | A | 5 | NULL | NULL | | BTREE | | |
| info | 0 | name_info | 1 | 姓名 | A | 5 | NULL | NULL | | BTREE | | |
| info | 1 | age_info | 1 | 年龄 | A | 5 | NULL | NULL | | BTREE | | |
| info | 1 | name_age_ID_info | 1 | 姓名 | A | 5 | NULL | NULL | | BTREE | | |
| info | 1 | name_age_ID_info | 2 | 年龄 | A | 5 | NULL | NULL | | BTREE | | |
| info | 1 | name_age_ID_info | 3 | 员工ID | A | 5 | NULL | NULL | | BTREE | | |
| info | 1 | work_info | 1 | 岗位名称 | NULL | 5 | NULL | NULL | | FULLTEXT | | |
+-------+------------+------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
7 rows in set (0.00 sec)
mysql> drop index name_age_ID_info on info; #######删除特定索引
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show index from info;
+-------+------------+-----------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+-----------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| info | 0 | PRIMARY | 1 | 员工ID | A | 5 | NULL | NULL | | BTREE | | |
| info | 0 | name_info | 1 | 姓名 | A | 5 | NULL | NULL | | BTREE | | |
| info | 1 | age_info | 1 | 年龄 | A | 5 | NULL | NULL | | BTREE | | |
| info | 1 | work_info | 1 | 岗位名称 | NULL | 5 | NULL | NULL | | FULLTEXT | | |
+-------+------------+-----------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
4 rows in set (0.00 sec)
mysql>
-
竖向显示索引
mysql> show index from info\G;
*************************** 1. row ***************************
Table: info
Non_unique: 0
Key_name: PRIMARY
Seq_in_index: 1
Column_name: 员工ID
Collation: A
Cardinality: 5
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
三.MySQL事务的概念以及特点
事务的概念
- 事务是一种机制、一个操作序列,包含了一组数据库操作命令,并且把所有的命令作为一个整体一起向系统提交或撤销操作请求,即一组数据库命令要么都执行,要么都不执行
- 事务一个不可分割的工作逻辑单元,在数据库系统上执行并发操作时,事务是最小的控制单元。
- 事务适用于用户同时操作数据库系统,通过事务的整体性以保证数据的一致性。
- 事务是保证了一组操作的平稳性和可预测的技术
事务的ACID特性
- 原子性:事务是一个完整的操作,各个元素是不可分的,即原子的。事务中的所有元素必须作为一个整体提交或者回滚。如果事务中的任何元素失败,则整个事务失败
- 一致性:当事务完成时,数据必须处于一致性;在事务开始之前,数据库中存储的数据处于一致性;在事务进行中时,数据可能处于不一致的状态;当事务成功完成时,数据必须再次回到已知的一致状态。
- 隔离性:在数据进行修改的所有并发事务是彼此隔离的,这表明事务必须是独立的,它不应以任何方式依赖或影响其他事务。
- 持久性:指的是不管系统是否发生故障,事务处理的结果都是永久的。一旦事务被提交,事务的效果会被永久地保留在数据库中
四.MySQL操作事务
MySQL事务
- 默认情况下,MySQL的事务是自动提交的。之前我们用SQL语句操作数据库时,一条语句执行后,系统会自动执行事务提交。当需要一组语句作为一个事务提交时,需要手动对事务进行控制。手动控制事务两种方法,一种使用事务命令控制,另一种是使用set设置事务的处理方式
使用事务命令控制事务
- MySQL中使用命令控制事务的3个命令
- begin:表示事务的开始,后面会有多条数据库操作语句执行
- commit:表示提交一个事务,对应前面的begin操作,他们之间的数据库操作语句一起完成
- rollback:表示回滚一个事务,在begin和commit之间,如果某一个数据库操作语句出现错误,执行rollback回滚,数据库回到begin之前的状态,也就是操作语句都没执行
- 具体操作
- 使用begin开始事务,插入两条语句
- 直接回滚,在查看logs表内数据
- 使用commit提交数据,然后回滚
- 使用savepoint定点回滚
使用set设置控制事务
- MySQL默认是自动提交事务,也可以修改为不自动提交事务
set autocommit=0 ##禁止自动提交
set autocommit=1 ##开启自动提交
- 当我们把autocommit的值改为0时,则需要手动提交,即用commit提交,回滚使用rollback