表须要使用何种数据类型,是须要根据应用来判断的。虽然应用设计的时候须要考虑字段的长度留有必定的冗余,可是不推荐让不少字段都留有大量的冗余,这样即浪费存储也浪费内存。咱们可使用PROCEDURE ANALYSE()对当前已有应用的表类型的判断,该函数能够对数据表中的列的数据类型提出优化建议,能够根据应用的实际状况酌情考虑是否实施优化。
语法:
SELECT * FROM tbl_name PROCEDURE ANALYSE();
SELECT * FROM tbl_name PROCEDURE ANALYSE(16,256);
输出的每一列信息都会对数据表中的列的数据类型提出优化建议。第二个例子告诉PROCEDURE ANALYSE()不要为那些包含的值多于16 个或者256 字节的ENUM 类型提出建议。若是没有这样的限制,输出信息可能很长;ENUM 定义一般很难阅读。
在对字段类型进行优化时,能够根据统计信息并结合应用的实际状况对其进行优化。
经过拆分提升表的访问效率:
这里咱们所说的拆分,主要是针对Myisam 类型的表,拆分的方法能够分红两种状况:
1. 纵向拆分:
纵向拆分是只按照应用访问的频度,将表中常常访问的字段和不常常访问的字段拆分红两个表,常常访问的字段尽可能是定长的,这样能够有效的提升表的查询和更新的效率。
2. 横向拆分:
横向拆分是指按照应用的状况,有目的的将数据横向拆分红几个表或者经过分区分到多个分区中,这样能够有效的避免Myisam 表的读取和更新致使的锁问题。
逆规范化:
数据库德规范化设计强调数据的独立性,数据应该尽量少地冗余,由于存在过多的冗余数据,这就意味着要占用了更多的物理空间,同时也对数据的维护和一致性检查带来了问题。
可是对于查询操做不少的应用,一次查询可能须要访问多表进行,若是经过冗余纪录在相同表中,更新的代价增长很少,可是查询操做效率能够有明显提升,这种状况就能够考虑经过冗余数据来提升效率。
使用冗余统计表:
使用create temporary table 语法,它是基于session 的表,表的数据保存在内存里面,当session 断掉后,表天然消除。对于大表的统计分析,若是统计的数据量不大,利用insert。。。select 将数据移到临时表中比直接在大表上作统计要效率更高。
选择更合适的表类型:
一、若是应用出现比较严重的锁冲突,请考虑是否更改存储引擎到innodb,行锁机制能够有效的减小锁冲突的出现。
二、若是应用查询操做不少,且对事务完整性要求不严格,则能够考虑使用Myisam存储引擎。更多存储引擎选择的原则,请参考开发篇的相关章节。
选择mysql 存储引擎
mysql的存储引擎包括:MyISAM、InnoDB、BDB、MEMORY、MERGE、EXAMPLE、NDB Cluster、ARCHIVE、CSV、BLACKHOLE、FEDERATED等,其中InnoDB和BDB提供事务安全表,其余存储引擎都是非事务安全表。
最常使用的2 种存储引擎:
1. Myisam存储引擎。每一个MyISAM在磁盘上存储成三个文件, 文件名都和表名相同,扩展名分别是.frm(存储表定义)、.MYD (MYData,存储数据)、.MYI (MYIndex,存储索引)。数据文件和索引文件能够放置在不一样的目录,平均分布io,得到更快的速度。
2. InnoDB 存储引擎提供了具备提交、回滚和崩溃恢复能力的事务安全。可是对比Myisam的存储引擎,InnoDB 写的处理效率差一些而且会占用更多的磁盘空间以保留数据和索引。
注: MySQL以前是MyISAM为默认存储引擎,5.5后是InnoDB为默认存储引擎。
如何选择合适的存储引擎:
1) MyISAM:MySQL 插件式存储引擎,它是在Web、数据仓储和其余应用环境下最常使用的存储引擎之一.
2) InnoDB:用于事务处理应用程序,具备众多特性,包括ACID 事务支持。
3) Memory:将全部数据保存在RAM 中,在须要快速查找引用和其余相似数据的环境下,可提供极快的访问。
4) Merge:容许MySQL DBA 或开发人员将一系列等同的MyISAM 表以逻辑方式组合在一块儿,并做为1 个对象引用它们。对于诸如数据仓储等VLDB 环境十分适合。
选择合适的数据类型
选择原则-根据选定的存储引擎,肯定如何选择合适的数据类型.
1) MyISAM 数据存储引擎和数据列: MyISAM数据表,最好使用固定长度的数据列代替可变长度的数据列。
2) MEMORY存储引擎和数据列: MEMORY数据表目前都使用固定长度的数据行存储,所以不管使用CHAR或VARCHAR列都没有关系。二者都是做为CHAR类型处理的。
3) InnoDB 存储引擎和数据列: 建议使用VARCHAR类型. 对于InnoDB数据表,内部的行存储格式没有区分固定长度和可变长度列(全部数据行都使用指向数据列值的头指针),所以在本质上,使用固定长度的CHAR列不必定比使用可变长度VARCHAR列简单。于是,主要的性能因素是数据行使用的存储总量。因为CHAR平均占用的空间多于VARCHAR,所以使用VARCHAR来最小化须要处理的数据行的存储总量和磁盘I/O是比较好的。
1. CHAR 和VARCHAR
它们类型相似,但它们保存和检索的方式不一样。
值 |
CHAR(4) |
存储需求 |
VARCHAR(4) |
存储需求 |
'' |
' ' |
4 个字节 |
'' |
1 个字节 |
'ab' |
'ab ' |
4 个字节 |
'ab ' |
3 个字节 |
'abcd' |
'abcd' |
4 个字节 |
'abcd' |
5个字节 |
'abcdefgh' |
'abcd' |
4 个字节 |
'abcd' |
5个字节 |
请注意上表中最后一行的值只适用不使用严格模式时;若是MySQL 运行在严格模式,超过列长度的值不但不保存,而且会出现错误。
从CHAR(4)和VARCHAR(4)列检索的值并不老是相同,由于从CHAR 列检索时会删除尾部的空格,而Varchar类型检索时会保存尾部空格。
2. TEXT和BLOB
在使用text 和blob 字段类型时要注意如下几点,以便更好的发挥数据库的性能.
1. BLOB和TEXT值会引发本身的一些问题,特别是执行了大量的删除或更新操做的时候。删除这种值会在数据表中留下很大的"空洞",之后填入这些"空洞"的记录可能长度不一样,为了提升性能,建议按期使用OPTIMIZE TABLE 功能对这类表进行碎片整理.
2. 使用合成的(synthetic)索引。合成的索引列在某些时候是有用的。一种办法是根据其它的列的内容创建一个散列值,并把这个值存储在单独的数据列中。接下来你就能够经过检索散列值找到数据行了。可是,咱们要注意这种技术只能用于精确匹配的查询(散列值对于相似<或>=等范围搜索操做符是没有用处的)。咱们可使用MD5()函数生成散
列值,也可使用SHA1()或CRC32(),或者使用本身的应用程序逻辑来计算散列值。请记住数值型散列值能够很高效率地存储。一样,若是散列算法生成的字符串带有尾部空格,就不要把它们存储在CHAR或VARCHAR列中,它们会受到尾部空格去除的影响。合成的散列索引对于那些BLOB或TEXT数据列特别有用。用散列标识符值查找的速度比搜索BLOB列自己的速度快不少。
3. 在没必要要的时候避免检索大型的BLOB或TEXT值。例如,SELECT *查询就不是很好的想法,除非你可以肯定做为约束条件的WHERE子句只会找到所须要的数据行。不然,你可能毫无目的地在网络上传输大量的值。这也是BLOB或TEXT标识符信息存储在合成的索引列中对咱们有所帮助的例子。你能够搜索索引列,决定那些须要的数据行,而后从合格的数据行中检索BLOB或TEXT值。
4. 把BLOB或TEXT列分离到单独的表中。在某些环境中,若是把这些数据列移动到第二张数据表中,可让你把原数据表中的数据列转换为固定长度的数据行格式,那么它就是有意义的。这会减小主表中的碎片,使你获得固定长度数据行的性能优点。它还使你在主数据表上运行SELECT *查询的时候不会经过网络传输大量的BLOB或TEXT值。
3. 浮点数与定点数
在mysql 中float、double(或real)是浮点数,decimal(或numberic)是定点数。
浮点数相对于定点数的优势是在长度必定的状况下,
浮点数可以表示更大的数据范围;它的缺点是会引发精度问题。
在从此关于浮点数和定点数的应用中,你们要记住如下几点:
一、浮点数存在偏差问题;从上面的例子中咱们看到c1 列的值由131072.32 变成了131072.31.
二、对货币等对精度敏感的数据,应该用定点数表示或存储;
三、编程中,若是用到浮点数,要特别注意偏差问题,并尽可能避免作浮点数比较;
四、要注意浮点数中一些特殊值的处理。
选择合适的字符集
字符集是一套符号和编码的规则,并且若是在数据库建立阶段没有正确选择字符集,那么可能在后期须要更换字符集,而字符集的更换是代价比较高的操做,也存在必定的风险,因此,咱们推荐在应用开始阶段,就按照需求正确的选择合适的字符集,避免后期没必要要的调整。
MySQL 支持的字符集
mysql服务器能够支持多种字符集(能够用show character set命令查看全部mysql支持的字符集),在同一台服务器、同一个数据库、甚至同一个表的不一样字段均可以指定使用不一样的字符集,相比oracle等其余数据库管理系统,在同一个数据库只能使用相同的字符集,mysql明显存在更大的灵活性。
mysql的字符集包括字符集(CHARACTER)和校对规则(COLLATION)两个概念。字符集是用来定义mysql存储字符串的方式,校对规则则是定义了比较字符串的方式。字符集和校对规则是一对多的关系, MySQL支持30多种字符集的70多种校对规则。每一个字符集至少对应一个校对规则。能够用SHOW COLLATION LIKE 'utf8%';命令查看相关字符集的校对规则。
怎样选择合适的字符集
咱们建议在可以彻底知足应用的前提下,尽可能使用小的字符集。由于更小的字符集意味着可以节省空间、减小网络传输字节数,同时因为存储空间的较小间接的提升了系统的性能。
有不少字符集能够保存汉字,好比utf八、gb23十二、gbk、latin1 等等,可是经常使用的是gb2312 和gbk。由于gb2312 字库比gbk 字库小,有些偏僻字(例如:洺)不能保存,所以在选择字符集的时候必定要权衡这些偏僻字在应用出现的概率以及形成的影响,不能作出确定答复的话最好选用gbk。
MySQL 字符集的设置
mysql 的字符集和校对规则有4 个级别的默认设置:服务器级、数据库级、表级和字段级。分别在不一样的地方设置,做用也不相同。服务器字符集和校对,在mysql 服务启动的时候肯定。
- 能够在my.cnf 中设置:[mysqld] default-character-set=utf8
- 或者在启动选项中指定:mysqld --default-character-set=utf8
- 或者在编译的时候指定:./configure --with-charset=utf8
若是没有特别的指定服务器字符集,默认使用latin1 做为服务器字符集。上面三种设置的方式都只指定了字符集,没有指定校对规则,这样是使用该字符集默认的校对规则,若是要使用该字符集的非默认校对规则,则须要在指定字符集的同时指定校对规则。能够用show variables like 'character_set_server';命令查询当前服务器的字符集和校对规则。