咱们在 MySQL 入门篇主要介绍了基本的 SQL 命令、数据类型和函数,在局部以上知识后,你就能够进行 MySQL 的开发工做了,可是若是要成为一个合格的开发人员,你还要具有一些更高级的技能,下面咱们就来探讨一下 MySQL 都须要哪些高级的技能mysql
数据库最核心的一点就是用来存储数据,数据存储就避免不了和磁盘打交道。那么数据以哪一种方式进行存储,如何存储是存储的关键所在。因此存储引擎就至关因而数据存储的发动机,来驱动数据在磁盘层面进行存储。算法
MySQL 的架构能够按照三层模式来理解sql
存储引擎也是 MySQL 的组建,它是一种软件,它所能作的和支持的功能主要有数据库
MySQL 默认支持多种存储引擎,来适用不一样数据库应用,用户能够根据须要选择合适的存储引擎,下面是 MySQL 支持的存储引擎缓存
默认状况下,若是建立表不指定存储引擎,会使用默认的存储引擎,若是要修改默认的存储引擎,那么就能够在参数文件中设置 default-table-type
,可以查看当前的存储引擎安全
show variables like 'table_type';
复制代码
奇怪,为何没有了呢?网上求证一下,在 5.5.3 取消了这个参数数据结构
能够经过下面两种方法查询当前数据库支持的存储引擎架构
show engines \g
复制代码
在建立新表的时候,能够经过增长 ENGINE
关键字设置新建表的存储引擎。并发
create table cxuan002(id int(10),name varchar(20)) engine = MyISAM;
复制代码
上图咱们指定了 MyISAM
的存储引擎。函数
若是你不知道表的存储引擎怎么办?你能够经过 show create table
来查看
若是不指定存储引擎的话,从MySQL 5.1 版本以后,MySQL 的默认内置存储引擎已是 InnoDB了。建一张表看一下
如上图所示,咱们没有指定默认的存储引擎,下面查看一下表
能够看到,默认的存储引擎是 InnoDB
。
若是你的存储引擎想要更换,可使用
alter table cxuan003 engine = myisam;
复制代码
来更换,更换完成后回显示 0 rows affected ,但其实已经操做成功
咱们使用 show create table
查看一下表的 sql 就知道
下面会介绍几个经常使用的存储引擎以及它的基本特性,这些存储引擎是 **MyISAM、InnoDB、MEMORY 和 MERGE **
在 5.1 版本以前,MyISAM 是 MySQL 的默认存储引擎,MyISAM 并发性比较差,使用的场景比较少,主要特色是
不支持事务
操做,ACID 的特性也就不存在了,这一设计是为了性能和效率考虑的。
不支持外键
操做,若是强行增长外键,MySQL 不会报错,只不过外键不起做用。
MyISAM 默认的锁粒度是表级锁
,因此并发性能比较差,加锁比较快,锁冲突比较少,不太容易发生死锁的状况。
MyISAM 会在磁盘上存储三个文件,文件名和表名相同,扩展名分别是 .frm(存储表定义)
、.MYD(MYData,存储数据)
、MYI(MyIndex,存储索引)
。这里须要特别注意的是 MyISAM 只缓存索引文件
,并不缓存数据文件。
MyISAM 支持的索引类型有 全局索引(Full-Text)
、B-Tree 索引
、R-Tree 索引
Full-Text 索引:它的出现是为了解决针对文本的模糊查询效率较低的问题。
B-Tree 索引:全部的索引节点都按照平衡树的数据结构来存储,全部的索引数据节点都在叶节点
R-Tree索引:它的存储方式和 B-Tree 索引有一些区别,主要设计用于存储空间和多维数据的字段作索引,目前的 MySQL 版本仅支持 geometry 类型的字段做索引,相对于 BTREE,RTREE 的优点在于范围查找。
数据库所在主机若是宕机,MyISAM 的数据文件容易损坏,并且难以恢复。
增删改查性能方面:SELECT 性能较高,适用于查询较多的状况
自从 MySQL 5.1 以后,默认的存储引擎变成了 InnoDB 存储引擎,相对于 MyISAM,InnoDB 存储引擎有了较大的改变,它的主要特色是
可重复读(repetable-read)
、经过MVCC(并发版本控制)
来实现的。可以解决脏读
和不可重复读
的问题。行级锁
,并发性能比较好,会发生死锁的状况。.frm文件存储表结构
定义,可是不一样的是,InnoDB 的表数据与索引数据是存储在一块儿的,都位于 B+ 数的叶子节点上,而 MyISAM 的表数据和索引数据是分开的。MEMORY 存储引擎使用存在内存中的内容来建立表。每一个 MEMORY 表实际只对应一个磁盘文件,格式是 .frm
。 MEMORY 类型的表访问速度很快,由于其数据是存放在内存中。默认使用 HASH 索引
。
MERGE 存储引擎是一组 MyISAM 表的组合,MERGE 表自己没有数据,对 MERGE 类型的表进行查询、更新、删除的操做,其实是对内部的 MyISAM 表进行的。MERGE 表在磁盘上保留两个文件,一个是 .frm
文件存储表定义、一个是 .MRG
文件存储 MERGE 表的组成等。
在实际开发过程当中,咱们每每会根据应用特色选择合适的存储引擎。
咱们会常常碰见的一个问题就是,在建表时如何选择合适的数据类型,一般选择合适的数据类型可以提升性能、减小没必要要的麻烦,下面咱们就来一块儿探讨一下,如何选择合适的数据类型。
char 和 varchar 是咱们常常要用到的两个存储字符串的数据类型,char 通常存储定长的字符串,它属于固定长度的字符类型,好比下面
值 | char(5) | 存储字节 |
---|---|---|
'' | ' ' | 5个字节 |
'cx' | 'cx ' | 5个字节 |
'cxuan' | 'cxuan' | 5个字节 |
'cxuan007' | 'cxuan' | 5个字节 |
能够看到,无论你的值写的是什么,一旦指定了 char 字符的长度,若是你的字符串长度不够指定字符的长度的话,那么就用空格来填补,若是超过字符串长度的话,只存储指定字符长度的字符。
这里注意一点:若是 MySQL 使用了非
严格模式
的话,上面表格最后一行是能够存储的。若是 MySQL 使用了严格模式
的话,那么表格上面最后一行存储会报错。
若是使用了 varchar 字符类型,咱们来看一下例子
值 | varchar(5) | 存储字节 |
---|---|---|
'' | '' | 1个字节 |
'cx' | 'cx ' | 3个字节 |
'cxuan' | 'cxuan' | 6个字节 |
'cxuan007' | 'cxuan' | 6个字节 |
能够看到,若是使用 varchar 的话,那么存储的字节将根据实际的值进行存储。你可能会疑惑为何 varchar 的长度是 5 ,可是却须要存储 3 个字节或者 6 个字节,这是由于使用 varchar 数据类型进行存储时,默认会在最后增长一个字符串长度,占用1个字节(若是列声明的长度超过255,则使用两个字节)。varchar 不会填充空余的字符串。
通常使用 char 来存储定长的字符串,好比身份证号、手机号、邮箱等;使用 varchar 来存储不定长的字符串。因为 char 长度是固定的,因此它的处理速度要比 VARCHAR 快不少,可是缺点是浪费存储空间,可是随着 MySQL 版本的不断演进,varchar 数据类型的性能也在不断改进和提升,因此在许多应用中,VARCHAR 类型更多的被使用。
在 MySQL 中,不一样的存储引擎对 CHAR 和 VARCHAR 的使用原则也有不一样
通常在保存较少的文本的时候,咱们会选择 CHAR 和 VARCHAR,在保存大数据量的文本时,咱们每每选择 TEXT 和 BLOB;TEXT 和 BLOB 的主要差异是 BLOB 可以保存二进制数据
;而 TEXT 只能保存字符数据
,TEXT 往下细分有
BLOB 往下细分有
三种,它们最主要的区别就是存储文本长度不一样和存储字节不一样,用户应该根据实际状况选择知足需求的最小存储类型,下面主要对 BLOB 和 TEXT 存在一些问题进行介绍
TEXT 和 BLOB 在删除数据后会存在一些性能上的问题,为了提升性能,建议使用 OPTIMIZE TABLE
功能对表进行碎片整理。
也可使用合成索引来提升文本字段(BLOB 和 TEXT)的查询性能。合成索引就是根据大文本(BLOB 和 TEXT)字段的内容创建一个散列值,把这个值存在对应列中,这样就可以根据散列值查找到对应的数据行。通常使用散列算法好比 md5() 和 SHA1() ,若是散列算法生成的字符串带有尾部空格,就不要把它们存在 CHAR 和 VARCHAR 中,下面咱们就来看一下这种使用方式
首先建立一张表,表中记录 blob 字段和 hash 值
向 cxuan005 中插入数据,其中 hash 值做为 info 的散列值。
而后再插入两条数据
插入一条 info 为 cxuan005 的数据
若是想要查询 info 为 cxuan005 的数据,能够经过查询 hash 列来进行查询
这是合成索引的例子,若是要对 BLOB 进行模糊查询的话,就要使用前缀索引。
其余优化 BLOB 和 TEXT 的方式:
浮点数指的就是含有小数的值,浮点数插入到指定列中超过指定精度后,浮点数会四舍五入,MySQL 中的浮点数指的就是 float
和 double
,定点数指的是 decimal
,定点数可以更加精确的保存和显示数据。下面经过一个示例讲解一下浮点数精确性问题
首先建立一个表 cxuan006 ,只为了测试浮点数问题,因此这里咱们选择的数据类型是 float
而后分别插入两条数据
而后执行查询,能够看到查询出来的两条数据执行的舍入不一样
为了清晰的看清楚浮点数与定点数的精度问题,再来看一个例子
先修改 cxuan006 的两个字段为相同的长度和小数位数
而后插入两条数据
执行查询操做,能够发现,浮点数相较于定点数来讲,会产生偏差
在 MySQL 中,用来表示日期类型的有 DATE、TIME、DATETIME、TIMESTAMP,在
这篇文中介绍过了日期类型的区别,咱们这里就再也不阐述了。下面主要介绍一下选择
下面来认识一下 MySQL 字符集,简单来讲字符集就是一套文字符号和编码、比较规则的集合。1960 年美国标准化组织 ANSI 发布了第一个计算机字符集,就是著名的 ASCII(American Standard Code for Information Interchange)
。自从 ASCII 编码后,每一个国家、国际组织都研究了一套本身的字符集,好比 ISO-8859-1
、GBK
等。
可是每一个国家都使用本身的字符集为移植性带来了很大的困难。因此,为了统一字符编码,国际标准化组织(ISO)
指定了统一的字符标准 - Unicode 编码,它容纳了几乎全部的字符编码。下面是一些常见的字符编码
字符集 | 是否认长 | 编码方式 |
---|---|---|
ASCII | 是 | 单字节 7 位编码 |
ISO-8859-1 | 是 | 单字节 8 位编码 |
GBK | 是 | 双字节编码 |
UTF-8 | 否 | 1 - 4 字节编码 |
UTF-16 | 否 | 2 字节或 4 字节编码 |
UTF-32 | 是 | 4 字节编码 |
对数据库来讲,字符集是很重要的,由于数据库存储的数据大多数都是各类文字,字符集对数据库的存储、性能、系统的移植来讲都很是重要。
MySQL 支持多种字符集,可使用 show character set;
来查看全部可用的字符集
或者使用
select character_set_name, default_collate_name, description, maxlen from information_schema.character_sets;
复制代码
来查看。
使用 information_schema.character_set
来查看字符集和校对规则。