数据库索引
是一个排序的列表,存储着索引值和这个值所对应的物理地址
无须对整个表进行扫描,通过物理地址就可以找到所需数据
是表中一列或者若干列值排序的方法
需要额外的磁盘空间。
索引的作用
数据库利用各种快速定位技术,能够大大加快查询速率
当表很大或查询涉及到多个表时,可以成千上万倍地提高查询速度
可以降低数据库的IO成本,并且还可以降低数据库的排序成本
通过创建唯一性索引保证数据表数据的唯一性
可以加快表与表之间的连接
在使用分组和排序时,可大大减少分组和排序时间
语法:
create index 索引名 on 表名(字段)
1
示例:
mysql> create index age_index on kgc(age);
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc kgc;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(4) | NO | PRI | NULL | auto_increment |
| name | varchar(10) | NO | | NULL | |
| age | int(5) | NO | MUL | NULL | |
+-------+-------------+------+-----+---------+----------------+
语法:
alter table 表名 add index 索引名 (字段)
示例:
mysql> alter table kgc add index name_index (name);
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc kgc;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(4) | NO | PRI | NULL | auto_increment |
| name | varchar(10) | NO | MUL | NULL | |
| age | int(5) | NO | MUL | NULL | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
语法:
creater table 表名 ( ...,index index_name(字段))
示例:
mysql> create table num (id int,index id_index(id));
Query OK, 0 rows affected (0.01 sec)
mysql> desc num;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | int(11) | YES | MUL | NULL | |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)
列值唯一, 可以允许为空,但只能为空一次
create unique index index_name on table_name(字段);
示例:
mysql> create unique index id_unique on kgc(id);
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
alter table table_name add unique index_name(字段)
示例:
mysql> alter table kgc add unique index_age(age);
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
creater table table_name ( ...,unique index index_name(字段))
示例:
mysql> create table accp (id int(4) not null auto_increment,name varchar(10) not null,age int(4) not null,unique index id_index(id));
Query OK, 0 rows affected (0.02 sec)
creater table table_name ([...],primary key(字段));
alter table table_name add primary key(列的列表);
//示例
mysql> create table qingniao (id int(4) not null auto_increment,name varchar(10) not null,age int(4) not null,primary key(id));
Query OK, 0 rows affected (0.00 sec)
mysql> create table yunjs (id int(4) not null auto_increment,name varchar(10) not null,age int(4) not null,index id_index(id));
Query OK, 0 rows affected (0.00 sec)
mysql> alter table yunjs add primary key(age);
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
主键索引 非空且唯一
唯一索引 可以为空,只能为空一次
除了主键以外的其他字段叫候选键(或候选码)
每张表必须要有主键,自己本身表的外键就是对方表的主键
可以是单列上创建的索引,也可以是在多列上创建的索引
最左原则,从左往右依次执行
创建组合索引的方式
creater table user ( ...,index user(name,age,sex));
MySQL从3.23.23版开始支持全文索引和全文检索
索引类型为FULLTEXT
可以在CHAR、VARCHAR或者TEXT类型的列上创建
方法一: 在已经存在的表上创建全文索引
creater fulltext index index_name on table_name(content,tag);
方法二: 通过SQL语句ALTER TABLE创建全文索引
alter table table_name add fulltext index index_name(content,tag);
表的主键、外键必须有索引
记录数超过300行的表应该有索引
经常与其他表进行连接的表,在连接字段上应该建立索引
唯一性太差的字段不适合建立索引
更新太频繁地字段不适合创建索引
经常出现在where子句中的字段,特别是大表的字段,应该建立索引
索引应该建在选择性高的字段上
索引应该建在小字段上,对于大的文本字段甚至超长字段,不要建索引
查看索引语法
show index from table_ name;
show keys from table_ name;
查看索引的示例
删除索引语法
drop index_ name ON table_ name;
alter table table_ name drop index index_name;
删除索引的示例
mysql> drop index index_puid on mapping;
mysql> alter table mapping drop index gameid;
是一种机制、一个操作序列,包含了一组数据库操作命令,并且把所有的命令作为一个整体一起向系统提交或撤销操作请求,即这一组数据库命令要么都执行,要么都不执行.
是一个不可分割的工作逻辑单元,在数据库系统,上执行并发操作时,事务是最小的控制单元
适用于多用户同时操作的数据库系统的场景,如银行、保险公司及证券交易系统等等.
通过事务的整体性以保证数据的一致性.
事务是一个完整的操作,事务的各元素是不可分的
事务中的所有元素必须作为一个整体提交或回滚
如果事务中的任何元素失败,则整个事务将失败
当事务完成时,数据必须处于一 致状态
在事务开始前,数据库中存储的数据处于一致状态
在正在进行的事务中,数据可能处于不一致的状态
当事务成功完成时,数据必须再次回到已知的一致状态
对数据进行修改的所有并发事务是彼此隔离的,表明事务必须是独立的,它不应以任何方式依赖于或影响其他事务
修改数据的事务可在另-一个使用相同数据的事务开始之前访问这些数据,或者在另一个使用相同数据的事务结束之后访问这些数据
指不管系统是否发生故障,事务处理的结果都是永久的
一旦事务被提交,事务的效果会被永久地保留在数据库中
MySQL事务默认是自动提交的,当SQL 语句提交时事务便自动提交
事务控制语句
begin或start transaction
commit
rollback
savepoint identifier
release savepoint identifier
rollback to identifier
set transaction 设置事务的隔离级别,InnoDB存储引擎提供事物的隔离级别:READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ和SERIALIZABLE
手动对事务进行控制的方法
事务处理命令控制事务
bebin: 开始一个事务
commit: 提交一个事务
rollback: 回滚一个事务
使用set命令进行控制
set autocommit=0: 禁止自动提交.(等同于begin)
set autocommit=1: 开启自动提交. (等同于commit)
2.4: 事务的操作
存储引擎必须是innoadb;只有innoadb才支持事务
mysq|> use kgc;
Database changed
mysql> CREATE TABLE kgc_transaction_test( id int(5)) engine=innodb; //创建数据表
Query OK, 0 rows affected (0.04 sec)
mysq|> select * from kgc_transaction test;
Empty set (0.01 sec)
mysq|> begin; //开始事务
Query OK, 0 rows affected (0.00 sec)
mysql> insert into kgc_transaction_ test value(1);
Query OK, 1 rows affected (0.01 sec)
mysq|> insert into kgc_transaction_ test value(2);
Query OK, 1 rows affected (0.00 sec)
2 rows in set (0.01 sec)
mysql> commit; //提交事务
Query OK, 0 rows affected (0.01 sec)
mysq|> select * from kgc_transaction test;
mysq|> begin; //开始事务
Query OK, 0 rows affected (0.00 s
mysq|> insert into kgc_ transaction_test values(3);
Query OK, 1 rows affected (0.00 sec)
mysq|> rollback; //回滚
Query OK, 0 rows affected (0.00 sec)
mysq|> select * from kgc_transaction_test; //因为回滚所以数据没有插入
+-----+
|id |
+-----+
| 1|
|2
+------+
2 rows in set (0.01 sec)
mysql> insert into tmp(name) values('zhaosi');
Query OK, 1 row affected (0.00 sec)
mysql> savepoint b;
Query OK, 0 rows affected (0.00 sec)
//设置存档点 savepoint a(存档名);
//回滚到存档点 rollback to a;
mysql> create table tmp (name varchar(50) not null);
Query OK, 0 rows affected (0.01 sec)
mysql> insert into tmp select name from kgc;
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from tmp;
+--------+
| name |
+--------+
| lisi |
| wangwu |
| wangwu |
+--------+
3 rows in set (0.00 sec)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into tmp (name) value ('zhangsan');
Query OK, 1 row affected (0.00 sec)
mysql> savepoint a; //设置存档点a
Query OK, 0 rows affected (0.00 sec)
mysql> insert into tmp (name) value ('wanger');
Query OK, 1 row affected (0.00 sec)
mysql> savepoint b; //设置
Query OK, 0 rows affected (0.00 sec)
mysql> select * from tmp;
+----------+
| name |
+----------+
| lisi |
| wangwu |
| wangwu |
| zhangsan |
| wanger |
+----------+
5 rows in set (0.00 sec)
mysql> rollback to b;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from tmp;
+----------+
| name |
+----------+
| lisi |
| wangwu |
| wangwu |
| zhangsan |
| wanger |
+----------+
mysql> rollback to a;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from tmp;
+----------+
| name |
+----------+
| lisi |
| wangwu |
| wangwu |
| zhangsan |
+----------+
mysql> rollback to b;
ERROR 1305 (42000): SAVEPOINT b does not exist //回到倒数第二个存档点,后无法在回到倒数第一个存档点 ,因为存档点保存在内存中,回到存档点a,会把存档点b的内容释放.
mysql> rollback; //提交事务,回到begin位置,事务结束
Query OK, 0 rows affected (0.00 sec)
mysql> insert into tmp (name) value ('wanger'); //重新插入数据,默认提交事务
Query OK, 1 row affected (0.00 sec)
mysql> select * from tmp;
+--------+
| name |
+--------+
| lisi |
| wangwu |
| wangwu |
| wanger |
+--------+
mysql> rollback; //回滚到事务begin之前
Query OK, 0 rows affected (0.00 sec)
mysql> select * from tmp; //说明上一个事务已经自动提交
+--------+
| name |
+--------+
| lisi |
| wangwu |
| wangwu |
| wanger |
+--------+
4 rows in set (0.00 sec)
//上述操作说明rollback回到Begin之前,也是结束事务的一种方式.
总结:
第一范式:确保每列的原子性(强调的是列的原子性,即列不能够再分成其他几列).
如果每列(或者每个属性)都是不可再分的最小数据单元(也称为最小的原子单元),则满足第一范式.
例如:顾客表(姓名、编号、地址、……)其中"地址"列还可以细分为国家、省、市、区等。
第二范式:在第一范式的基础上更进一层,目标是确保表中的每列都和主键相关(一是表必须有一个主键;二是没有包含在主键中的列必须完全依赖于主键,而不能只依赖于主键的部分)
如果一个关系满足第一范式,并且除了主键以外的其它列,都依赖于该主键,则满足第二范式.
例如:订单表(订单编号、产品编号、定购日期、价格、……),"订单编号"为主键,"产品编号"和主键列没有直接的关系,即"产品编号"列不依赖于主键列,应删除该列。
第三范式:在第二范式的基础上更进一层,目标是确保每列都和主键列直接相关,而不是间接相关(另外非主键列必须直接依赖于主键,不能存在传递依赖).
如果一个关系满足第二范式,并且除了主键以外的其它列都不依赖于主键列,则满足第三范式.
为了理解第三范式,需要根据Armstrong公里之一定义传递依赖。假设A、B和C是关系R的三个属性,如果A-〉B且B-〉C,则从这些函数依赖中,可以得出A-〉C,如上所述,
依赖A-〉C是传递依赖。
例如:订单表(订单编号,定购日期,顾客编号,顾客姓名,……),初看该表没有问题,满足第二范式,每列都和主键列"订单编号"相关,再细看你会发现"顾客姓名"和"顾客
编号"相关,"顾客编号"和"订单编号"又相关,最后经过传递依赖,"顾客姓名"也和"订单编号"相关。为了满足第三范式,应去掉"顾客姓名"列,放入客户表中。
视图是一张虚拟的表,数据不存在视图中,视图是真实表的映射数据。例如:水中捞月是典型的视图
利用条件筛选,分组,排序等产生出一个结果集(结果集保存在内存中),并且做成持久化保存(保存映射)
视图占用资源小,真实表中数据产生变化,会影响到视图。
创建视图
create view <视图名称>
create view info_view as select id,name,age from info 条件
多表相连的条件是on
单表相连的条件是where
查询视图
select * from info_view;
select name,age from info_view;
查询多表相连
select info.id,info.name,info.age,info,score,info.addr,hob.hobname from info inner join hob on info.hobby=hob.id; '//从info表和hob表中选择info.id,info.name,info.age,info,score,info.addr,hob.hobname且info表中的hobby=hob表中的id'
'//inner join:内部相连'
创建多表相连查询视图
create view info_hob_view as select info.id,info.name,info.age,info,score,info.addr,hob.hobname from info inner join hob on info.hobby=hob.id; '//将刚刚的多表相连查询创建名为info_hob_view的视图'
select * from info_hob_view; '//查看视图'
安全性高
简化sql操作
可以针对不同用户创建不同的视图(不同权限的用户浏览不同的信息)
存储过程:多用于软件开发方向,
防止代码在网络传输过程中被截获,做了安全性保障。
原始状态:在代码过程中:需要嵌入sql语句,通过连接驱动把sql语句作为参数,传递给MySQL(数据库)进行执行,此时就会有安全风险。
通过存储过程解决安全隐患
存储过程是写在数据库中,并不是程序中。
程序是通过调用存储过程名称去触发sql操作。(类似调用函数)
存储过程优点:代码量优化,传输安全,网络资源优化
MySQL中的数据用各种不同的技术存储在文件中,每一种技术都使用不同的存储机制、索引技巧、锁定水平并最终提供不同的功能和能力,这些不同的技术以及配套的功能在MySQL中称为存储引擎
存储引擎是MySQL 将数据存储在文件系统中的存储方式或者存储格式
MySQL常用的存储引擎
MyISAM
InnoDB
MySQL数据库中的组件,负责执行实际的数据I/O操作
使用特殊存储引擎的主要优点之一在于:
仅需提供特殊应用所需的特性
数据库中的系统开销较小
具有更有效和更高的数据库性能
MySQL系统中,存储引擎处于文件系统之上,在数据保存到数据文件之前会传输到存储引擎,之后按照各个存储引擎的存储格式进行存储
MyISAM不支持事务,也不支持外键
访问速度快
对事务完整性没有要求
MyISAM在磁盘上存储成三个文件
.frm文件存储表定义
数据文件的扩展名为.MYD (MYData)
索引文件的扩展名是.MYI (MYIndex)
MyISAM的特点
优点:ISAM执行读取操作的速度很快
优点:不占用大量的内存和存储资源
缺点:不支持事务处理,也不支持外键
缺点:不能够容错
MyISAM管理非事务表,是lSAM的扩展格式
提供ISAM里所没有的索引和字段管理的大量功能
MyISAM使用一种表格锁定的机制,以优化多个并发的读写操作
MyISAM提供高速存储和检索,以及全文搜索能力,受到web开发的青睐
不支持事务
表级锁定形式,数据在更新时锁定整个表
数据库在读写过程中相互阻塞
会在数据写入的过程阻塞用户数据的读取
也会在数据读取的过程中阻塞用户的数据写入
可通过key_buffer_size来设置缓存索引,提高访问性能,减少磁盘I/O的压力
但缓存只会缓存索引文件,不会缓存数据
釆用 MyISAM存储引擎数据单独写入或读取,速度过程较快且占用资源相对少
MyISAM存储引擎它不支持外键约束,只支持全文索引
公司业务不需要事务的支持
一般单方面读取数据比较多的业务,或单方面写入数据比较多的业务
MyISAM存储引擎数据读写都比较频繁场景不适合
使用读写并发访问相对较低的业务
数据修改相对较少的业务
对数据业务一致性要求不是非常高的业务
服务器硬件资源相对比较差
支持事务:支持4个事务隔离级别
行级锁定,但是全表扫描仍然会是表级锁定
读写阻塞与事务隔离级别相关
具有非常高效的缓存特性:能缓存索引,也能缓存数据
表与主键以簇的方式存储
支持分区、表空间,类似 oracle数据库
支持外键约束,5.5以前不支持全文索引,5.5版本以后支持全文索引
对硬件资源要求还是比较高的场合
业务需要事务的支持
行级锁定对高并发有很好的适应能力,但需确保查询是通过索引来完成
业务数据更新较为频繁的场景,如:论坛,微博等
业务数据一致性要求较高,例如:银行业务
硬件设备内存较大,利用 Innodb较好的缓存能力来提高内存利用率,减少磁盘I/O的压力
需要考虑毎个存儲引擎提供了哪些不同的核心功能及应用场景
支持的字段和数据类型
所有引擎都支持通用的数据类型
但不是所有的引擎都支持其它的字段类型,如二进制对象
锁定类型:不同的存储引擎支持不同级别的锁定
表锁定
行锁定
索引的支持
建立索引在搜索和恢复数据库中的数据的时候能够显著提高性能
不同的存储引擎提供不同的制作索引的技术
有些存储引擎根本不支持索引
事务处理的支持
事务处理功能通过提供在向表中更新和插入信息期间的可靠性
可根据企业业务是否要支持事务选择存储引擎
常用的Myisam与innoadb对比
mark
在企业中选择好合适的存储引擎之后,就可以进行修改了
修改步骤
查看数据库可配置的存储引擎
查看表正在使用的存储引擎
配置存储引擎为所选择的类型
使用 show engines查看系统支持的存储引擎
查看表使用的存储引擎
方法1:show table status from库名 where name='表名';
方法2:show create table 表名; '//常用'
例如:
MySQL > show table status from yibiao where name='wangermazi'\G
'//使用\G代替分号表示垂直显示结果'
示例
mysql> show table status from school where name='kgc';
+------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------+
| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time | Update_time | Check_time | Collation | Checksum | Create_options | Comment |
+------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------+
| kgc | InnoDB | 10 | Dynamic | 3 | 5461 | 16384 | 0 | 49152 | 0 | 5 | 2020-08-18 23:37:34 | NULL | NULL | utf8_general_ci | NULL | | |
+------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------+
mysql> show create table kgc\G; "\G是竖着"
*************************** 1. row ***************************
Table: kgc
Create Table: CREATE TABLE "kgc" (
"id" int(4) NOT NULL AUTO_INCREMENT,
"name" varchar(10) NOT NULL,
"age" int(5) NOT NULL,
PRIMARY KEY ("id"),
UNIQUE KEY "id_unique" ("id"),
UNIQUE KEY "index_age" ("age"),
KEY "id_index" ("id"),
KEY "age_index" ("age"),
KEY "name_index" ("name")
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
共有四种方法
方法一:
alter table 修改;
格式:
alter table table_name engine=引擎;
例如:
mysql> alter table kgc engine=myisam;
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> show create table kgc\G;
*************************** 1. row ***************************
Table: kgc
Create Table: CREATE TABLE "kgc" (
"id" int(4) NOT NULL AUTO_INCREMENT,
"name" varchar(10) NOT NULL,
"age" int(5) NOT NULL,
PRIMARY KEY ("id"),
UNIQUE KEY "id_unique" ("id"),
UNIQUE KEY "index_age" ("age"),
KEY "id_index" ("id"),
KEY "age_index" ("age"),
KEY "name_index" ("name")
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
方法二:
修改my.cnf,指定默认存储引擎并重启服务
格式:
default-storage-engine=InnoDB
例如:
vim my.cnf
default-storage-engine=InnoDB
方法三:
create table 创建表时指定存储引擎
格式:
create table 表名 (字段) engine=引擎
例如:
MySQL> create table kgc(id int)engine=MyISAM;
方法四:5.7版本已经被删除
Mysql_convert_table_format转化存储引擎
格式:
Mysql_convert_table_format --user=root --password=密码 --sock=/tmp/mysql.sock --engine=引擎 库名 表名
例如:
[root@localhost ~]# yum install perl-DBI perl-DBD-MySQL -y
[root@localhost ~]# /usr/local/mysql/bin/mysql_convert_table_format --user=root --password='123' --sock=/tmp/mysql.sock school.kgc
-bash: /usr/local/mysql/bin/mysql_convert_table_format: 没有那个文件或目录