何谓存储引擎 :
MySQL中的数据用各种不同的技术存储在文件(或者内存)中。这些技术中都使用着不同的存储机制、索引技巧、锁定水平并且最终提供广泛的不同的功能和能力。通过选择不同的技术,能够各自在不同方面提高对数据增删改查操作的效率,从而改善你的应用整体功能。
这些不同的技术以及配套的相关功能在MySQL中被称作存储引擎(也称作表类型)。MySQL默认配置了许多不同的存储引擎,可以预先设置或者在MySQL服务器中启用。在项目中可根据需求选择适用于服务器、数据库和表格的存储引擎,以便在对数据进行增删改查时提供最大的灵活性。
修改数据库引擎 :
show variables like "default_tmp_storage_engine"; || show engines; 查看数据库使用的默认存储引擎
方式一 : 修改mysql配置文件 /etc/mysql/mysql.conf.d/mysqld.cnf
在[mysqld]后面添加 default-storage-engine=InnoDB
重启mysql服务
方式二 : 建表时指定数据库引擎
create table mytbl( id int primary key, name varchar(50) )type=MyISAM;
方式三 : 建表后更改数据库引擎
alter table table_name type = InnoDB;
查看数据库引擎是否更改成功: show table status from table_name; || show create table table_name;
储存引擎分类 :
MyISAM
特点:不支持事务,也不支持行级锁和外键;主机宕机后,MyISAM表易损坏,灾难恢复性不佳(可以配合锁,实现操作系统下的复制备份、迁移)
引擎在创建表的时候,会创建三个文件,一个是.frm文件用于存储表的定义,一个是.MYD文件用于存储表的数据,另一个是.MYI文件,存储的是索引。
MyISAM索引用的 B+ tree索引结构 来储存数据,MyISAM索引的指针指向的是键值的地址,地址存储的是数据。索引和实际数据是分开存储的,不过是用索引指向了实际的数据(非聚集索引).
还使用一种表格锁定的机制,来优化多个并发的读写操作,其代价是你需要经常运行OPTIMIZE TABLE命令,来恢复被更新机制所浪费的空间。
优势:拥有较高的插入、查询速度,访问速度快
劣势: 由于不支持事务操作,当表损坏后无法自动恢复
解决: mysql下的bin目录中有mysqlcheck.exe是专门修复myisam表损坏的,命令行执行,mysqlcheck -r database tablename -uroot -ppassword -h127.0.0.1 -P3306
使用场景:
- 查询密集型的表。MyISAM存储引擎在筛选大量数据时非常迅速,这是它最突出的优点。
-
对事务完整性没有要求,即不需要支持事务和支持外键的表设计,但是并不代表有事务操作的项目不能用MyIsam存储引擎,可以在service层进行根据自己的业务需求进行相应的控制。
-
需要 对表进行加锁的场景。
- 需要使用到大量查询数据select、插入数据insert为主的应用
- 需要做很多count的计算的。如一些日志,调查的业务表。
InnoDB
特点:具有提交、回滚和崩溃恢复能力的事务安全,支持行级锁和外键约束,灾难恢复性好,支持热备份。
与MyISAM一样也是使用 B+tree索引结构,但InnoDB的索引文件本身就是数据文件,即B+Tree的数据域存储的就是实际的数据(聚集索引)
缺点:写的处理效率差,占用更多的磁盘空间以保留数据和索引。
使用场景:
- insert、update更新密集的表。InnoDB存储引擎特别适合处理多重并发的更新请求。
- 要求可靠性高和支持事务。InnoDB存储引擎是支持事务的标准MySQL存储引擎。
- 自动灾难恢复。与其它存储引擎不同,InnoDB表能够自动从灾难中恢复。
- 需要支持外键约束。MySQL支持外键的存储引擎只有InnoDB。
- 支持自动增加列AUTO_INCREMENT属性。
- 一般来说,如果需要事务支持,并且有较高的并发读取频率,InnoDB是不错的选择。
MEMORY(HEAP)
特点:
- 使用内存来存储表和数据,每个MEMORY表实际对应一个磁盘文件,访问速度非常快,默认使用hash索引。
- 不支持事务和外键。
- MEMORY表的每个表可以有多达32个索引,每个索引16列,以及500字节的最大键长度
- MEMORY存储引擎执行HASH和BTREE缩影
- 可以在一个MEMORY表中有非唯一键值
- MEMORY表使用一个固定的记录长度格式
- MEMORY不支持BLOB或TEXT列
- MEMORY支持AUTO_INCREMENT列和对可包含NULL值的列的索引
- MEMORY表在所由客户端之间共享(就像其他任何非TEMPORARY表)
- MEMORY表内存被存储在内存中,内存是MEMORY表和服务器在查询处理时的空闲中,创建的内部表共享
- 当不再需要MEMORY表的内容时,要释放被MEMORY表使用的内存,应该执行
DELETE FROM
或TRUNCATE TABLE
,或者删除整个表(使用DROP TABLE)
缺点:
- 服务一旦关闭,表中的数据就会丢失掉。
- 使用表级锁,虽然内存访问快,但如果频繁的读写,表级锁会成为瓶颈。
- 只支持固定大小的行。Varchar类型的字段会存储为固定长度的Char类型,浪费空间。
- 不支持TEXT、BLOB字段。当有些查询需要使用到临时表(使用的也是MEMORY存储引擎)时,如果表中有TEXT、BLOB字段,那么会转换为基于磁盘的MyISAM表,严重降低性能
使用场景:
- 那些内容变化不频繁的代码表,或者作为统计操作的中间结果表,便于高效地堆中间结果进行分析并得到最终的统计结果。
- 目标数据比较小,而且非常频繁的进行访问,在内存中存放数据,如果太大的数据会造成内存溢出。可以通过参数max_heap_table_size控制Memory表的大小,限制Memory表的最大的大小。
- 数据是临时的,而且必须立即可用得到,那么就可以放在内存中(服务器日志)。
- 可用于缓存会被频繁访问的、可以重构的数据、计算结果、统计值、中间结果。
存储数据特性:要求存储的数据是数据长度不变的格式,比如,Blob和Text类型的数据不可用(长度不固定的)。
注意: Memory同时支持散列索引和B树索引,B树索引可以使用部分查询和通配查询,也可以使用<,>和>=等操作符,散列索引相等的比较快,但是对于范围查询比较慢。
MyISAM与InnoDB之比较 :
- InnoDB可借助事务日志(Transaction Log)来恢复程序崩溃(crash),或者非预期结束所造成的数据错误;而MyISAM遇到错误,必须完整扫描后才能重建索引,或者修正未写入硬盘的错误。
- InnoDB的修复时间,大略都是固定的,但MyISAM的修复时间,则与数据量的多少成正比。相对而言,随着数据量的增加,InnoDB会有较佳的稳定性。
- MyISAM必须依靠操作系统来管理读取&写入的缓存,而InnoDB是有自己的读写缓存管理机制。InnoDB不会将被修改的数据立即交给操作系统,在某些情况,InnoDB的数据访问会比MyISAM更高效率。
- InnoDB支持事务&行级锁&外键&全文索引,而MyISAM不支持事务&行级锁&外键&全文索引
- InnoDB不保存表的总行数,使用select count(*) from table 会遍历整个表;MyISAM保存着表的总行数,执行select count(*) from table会直接取出总行数。
MySQL存储引擎MyISAM与InnoDB如何选择
1)InnoDB支持事务,MyISAM不支持。
2)MyISAM适合查询以及插入为主的应用,InnoDB适合频繁修改以及涉及到安全性较高的应用。
3)InnoDB支持外键,MyISAM不支持。
4)从MySQL5.5.5以后,InnoDB是默认引擎。
5)InnoDB不支持FULLTEXT类型的索引。
6)InnoDB中不保存表的总行数,select count(*) from table时,InnoDB需要扫描整个表计算有多少行,但MyISAM只需简单读出保存好的总行数即可。注:当count(*)语句包含where条件时MyISAM也需扫描整个表。
7)对于自增长的字段,InnoDB中必须包含只有该字段的索引,但是在MyISAM表中可以和其他字段一起建立联合索引。
8)清空整个表时,InnoDB是一行一行的删除,效率非常慢。MyISAM则会重建表。
9)InnoDB支持行锁(某些情况下还是锁整表,如 update table set a=1 where user like ‘%lee%’
现在一般都是选用InnoDB了,主要是MyISAM的全表锁,读写串行问题,并发效率锁表,效率低,MyISAM对于读写密集型应用一般是不会去选用的。
总结:
1. MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持。
2. MyISAM类型的表强调的是性能,其执行速度比InnoDB类型更快,但是不提供事务支持,而InnoDB提供事务支持已经外部键等高级数据库功能。
存储过程
我们常用的操作数据库语言SQL语句在执行的时候需要要先编译,然后执行,而存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给定参数(如果该存储过程带有参数)来调用执行它。
一个存储过程是一个可编程的函数,它在数据库中创建并保存。它可以有SQL语句和一些特殊的控制结构组成。当希望在不同的应用程序或平台上执行相同的函数,或者封装特定功能时,存储过程是非常有用的。数据库中的存储过程可以看做是对编程中面向对象方法的模拟。它允许控制数据的访问方式。
优点:
(1).存储过程增强了SQL语言的功能和灵活性。存储过程可以用流控制语句编写,有很强的灵活性,可以完成复杂的判断和较复杂的运算。
(2).存储过程允许标准组件是编程。存储过程被创建后,可以在程序中被多次调用,而不必重新编写该存储过程的SQL语句。而且数据库专业人员可以随时对存储过程进行修改,对应用程序源代码毫无影响。
(3).存储过程能实现较快的执行速度。如果某一操作包含大量的Transaction-SQL代码或分别被多次执行,那么存储过程要比批处理的执行速度快很多。因为存储过程是预编译的。在首次运行一个存储过程时查询,优化器对其进行分析优化,并且给出最终被存储在系统表中的执行计划。而批处理的Transaction-SQL语句在每次运行时都要进行编译和优化,速度相对要慢一些。
(4).存储过程能过减少网络流量。针对同一个数据库对象的操作(如查询、修改),如果这一操作所涉及的Transaction-SQL语句被组织程存储过程,那么当在客户计算机上调用该存储过程时,网络中传送的只是该调用语句,从而大大增加了网络流量并降低了网络负载。
(5).存储过程可被作为一种安全机制来充分利用。系统管理员通过执行某一存储过程的权限进行限制,能够实现对相应的数据的访问权限的限制,避免了非授权用户对数据的访问,保证了数据的安全。
触发器
触发器的使用场景:满足特定条件触发响应的动作
触发器的优点:比较适用于复杂的业务逻辑。比如,数据库中一条数据发生改变(更新、删除、增加)时,通过触发器让其他多张表发生改变。
触发器的缺点:
1. 增加维护的成本。有些业务逻辑在代码中处理,有些业务逻辑用触发器处理,会使后期维护变得困难
2. 学习成本增加: Mysql和Oracle的触发器的语法格式是不一样的。
触发器的特征:触发事件的操作和触发器里的SQL语句是一个事务操作,具有原子性,要么全部执行,要么都不执行。