Schema与数据类型优化
良好的逻辑设计和物理设计是高性能的基石,应该根据系统将要执行的查询数据来设计schema,这往往需要权衡各种因素。
MySQL支持的数据类型非常多,选择正确的数据类型对于获得高性能至关重要。
- 更小的通常更好 一般情况下,应该尽量使用可以正确存储数据的最小数据类型。更小的数据类型通常更快,因为它们占用更少的磁盘,内存和缓存。并且处理时需要的CPU周期也更少。
- 简单就好 简单数据类型的操作通常需要更少的CPU周期。(应该使用MySQL内建的类型而不是字符串来存储日期和时间,应该用整型来存储IP地址)
- 尽量避免NULL 如果查询中包含可为NULL的列,对MySQL来说更难优化,因为可为NULL的列使得索引、索引统计和值比较都更加复杂。可为NULL的列会使用更多的存储空间,在MySQL里需要特殊处理。通常把NULL列改为NOT NULL带来的性能提升比较小,所以没有必要首先在现有Schema中查找并修改掉这种情况,除非确定会导致问题。但是如果计划在列上建立索引,就应该尽量避免设计成可为NULL的列。
在为列选择数据类型时,第一步需要确定合适的大类型。下一步是选择具体类型,很多MySQL的数据类型可以存储相同类型的数据,只是存储的长度和范围不一样、允许的精度不同,或者需要的物理空间不同。
例如DATETIME和TIMESTAMP列都可以存储相同类型的数据:时间和日期,精确到秒。但是TIMESTAMP只是用DATETIME一般的存储空间,并且会根据时区进行变化,具有特殊的自动更新能力。但是TIMESTAMP允许的时间范围要小得多。
MySQL为了兼容性支持很多数据类型的别名。
MySQL中有两种类型的数字:整数和实数。
如果存储整数,可以使用:TINYINT SMALLINT MEDIUMINT INT BIGINT,分别对应8,16,24,32,64位存储空间。 整数类型可以携带UNSIGNED属性,有符号数和无符号数使用相同的存储空间,并且有相同的性能。
MySQL既支持精确类型,也支持不精确类型。FLOAT和DOUBLE类型支持使用标准的浮点运算进行近似计算。DECIMAL类型用于存储精确的小数。由于CPU不支持对DECIMAL的直接计算,MySQL服务器自身实现了DECIMAL的高精度计算。
浮点和DECIMAL类型都可以指定精度。对于DEMICAL列,可以指定小数点前后所允许的最大位数。但会影响列的空间消耗。MySQL5.0和更高版本将数字打包保存到一个二进制字符串中(每四个字节存九个数字,小数点本身占一个字节)。
MySQL5.0和更高版本中的DECIMAL类型允许最多65个数字。
字符串
MySQL支持多种字符串类型,每种类型还有很多变种。
VARCHAR和CHAR类型是两种最主要的字符串类型,根据存储引擎的具体实现,这两种字符串类型在磁盘中和内存中的存储方式也不同。
VARCHAR类型用于存储可变长度字符串,是一种最常见的字符串数据类型。它比定长类型更节省空间,因为它仅仅使用必要的空间(但如果MySQL表使用ROW_FORMAT=FIXED的话,每一行都定长,很浪费空间),VARCHAR需要使用1到2个额外字节记录字符串长度,如果列的最大长度小虎或等于255,则使用1字节来表示,否则使用2字节来表示。
VARCHAR节省了存储空间,所以对性能有一定的帮助。但是,由于行是变长的,在UPDATE时可能使得行变得比原来长,这就导致需要额外的工作。如果一个行占用的空间增长,并且在页内没有更多的存储空间,在这种情况下,不同的存储引擎的处理方式是不一样的。MyISAM会将行拆成不同的片段存储,InnoDB则需要分裂页来使行可以放进页内。
下面情况下使用VARCHAR是合适的:字符串列的最大长度比平均长度大很多;列更新的很少(碎片不是问题);使用了像UTF-8这样复杂的字符集,每个字符都使用不同的字节数进行存储。
最好的策略是只分配真正需要的空间。
BLOB和TEXT都是为存储很大的数据而设计的字符串数据类型,分别采用二进制和字符方式存储。实际上是隶属于两个完全不同的数据类型。MYSQL会将此二者特殊处理,InnoDB会使用专门的外部存储区域来进行存储,Memory引擎不支持Blob和Text类型,所以,如果使用Blob或者Text并且需要使用隐式临时表,将不得不使用MyISAM磁盘临时表。有一个技巧:在所有用到Blob字段的地方都使用SubString(column, length)将其转化为字符串,这样就可以使用内存表了。
当一些字符串固定出现,可以将这些字符串统一替换为枚举类型,MySQL在存储枚举类型会非常紧凑,其内部将每个值在列表中的位置保存为整数,并且在表的.frm文件中保存“数字-字符串”映射关系的“查找表”。但在扩充枚举类型的可选值的时候,则需要进行Alter Table。
日期和时间
MySQL能存储的最小时间单位粒度为秒(但可以使用微秒级粒度进行临时运算)
MySQL提供两种日期类型:DATETIME和TIMESTAMP。
DATETIME
该类型的保存范围为1001年到9999年,精度为秒,它将日期和时间封装为YYYYMMDDHHMMSS的整数中,与时区无关,使用8字节存储。
TIMESTAMP
该类型保存从1970年1月1日起(格林尼治时间)以来的秒数(UNIX时间戳)TIMESTAMP只使用了4字节来进行存储,只能保存19700年到2038年之间的时间。
MySQL提供了FROM_UNIXTIME()函数把Unix时间戳转换为日期,同样地,提供了UNIX_TIMESTAMP()函数将日期转换为时间戳。 TIMESTAMP显示的值依赖于时区。
TIMESTAMP和DATETIME没有特殊属性,默认情况下,插入的TIMESTAMP的值为当前时间。
位数据
MySQL有少数集中存储类型使用紧凑的位存储数据。这些位类型,不管底层存储格式和处理方式如何,从技术上来说都是字符串类型。
BIT
在MySQL5.0以前,BIT和TINYINT是同义词,5.0以后则是两个完全不同的类型。可以在BIT列存储一个或多个TRUE/FALSE值。BIT列的最大长度为64位。
BIT存储因存储引擎而异。MyISAM会将打包存储所有的BIT列,因此占用的空间较小,而InnoDB和Memory则将每个BIT以最小整数存储。
MySQL会把BIT当成字符串类型,而不是数字类型,其结果是包含二进制0或者1的字符串,而不是ASCII码‘0’和‘1’。 检索BIT列,会根据检索环境动态地将结果转换为字符串类型或者数字类型。
如果想在一个BIT的存储空间存储一个TRUE/FALSE值,另一个方法是创建一个可以为空的CHAR(0)列,该列可以保存NULL或者长度为0的字符串。
SET
如果需要保存多个TRUE/FALSE,可以考虑合并这些列到SET数据类型,它在MySQL内部是以一系列到爆的位的集合来表示的。其主要的缺点是改变列的定义代价较高(ALTER TABLE)。而且也无法在SET列上进行检索查询。
标识符
标识列在查询过程中是非常有用的。当选择标识列的类型时,不仅仅需要考虑存储类型,还需要考虑MySQL对这种类型怎么执行计算和比较。例如MySQL在内部使用整数存储ENUM和SET,然后在比较的时候转换为字符串。
其中,整数类型是标识符的最好的选择,而ENUM和SET就是一种非常糟糕的选择。ENUM和SET列适合存储固定信息。 如果可能,尽量避免使用字符串类型作为标识列,因为它非常消耗空间,比数字类型慢。
对于完全随机的字符串也需要注意,如MD5,SHA1,或者UUID产生的字符串,这些函数生成的新值会任意分布在很大的空间内,这样会导致SELECT或者INSERT语句很慢。
MySQL schema设计中的陷阱
- 太多的列。MySQL存储引擎API工作时需要在服务器层和存储引擎层之间通过行缓冲格式拷贝数据,然后uzai服务器层将缓冲内容解码成各个列。从行缓冲中将编码过的列转换成行数据结构的操作代价是非常高的。
- 太多的关联。MySQL限制了每个关联操作最多只能61个关联表,如果希望查询执行得快,并且并发性好,单个查询最好在12个表以内做关联。
- 枚举。
- NULL。不要过分遵循“不适用NULL”的准则。
Schema与数据类型优化的更多相关文章
- mysql笔记01 MySQL架构与历史、Schema与数据类型优化
MySQL架构与历史 1. MySQL架构推荐参考:http://www.cnblogs.com/baochuan/archive/2012/03/15/2397536.html 2. MySQL会解 ...
- MySQL Schema与数据类型优化
Schema与数据类型优化 选择优化的数据类型 1.更小的通常更好 更小的数据类型通常更快,因为它们占用更少的磁盘,内存和CPU缓存 2.简单就好 简单数据类型的操作通常需要更少的CPU周期.例如:整 ...
- Schema 与数据类型优化
这是<高性能 MySQL(第三版)>第四章<Schema 与数据类型优化>的读书笔记. 1. 选择优化的数据类型 数据类型的选择原则: 越小越好:选择满足需求的最小类型.注意, ...
- MySQL设计之Schema与数据类型优化
一.数据类型优化 1.更小通常更好 应该尽量使用可以正确存储数据的最小数据类型,更小的数据类型通常更快,因为它们占用更少的磁盘.内存和CPU缓存,并且处理时需要的CPU周期更少,但是要确保没有低估需要 ...
- 高性能MySQL笔记 第4章 Schema与数据类型优化
4.1 选择优化的数据类型 通用原则 更小的通常更好 前提是要确保没有低估需要存储的值范围:因为它占用更少的磁盘.内存.CPU缓存,并且处理时需要的CPU周期也更少. 简单就好 简 ...
- Mysql高性能笔记(一):Schema与数据类型优化
1.数据类型 1.1.几个参考优化原则 a. 更小的通常更好 i.更小的数据类型,占用更少磁盘.内存和CPU缓存,需要的CPU周期更少 ii.如果无法确定哪个数据类型是最好的,就选择不会超过范围的最 ...
- MySQL之Schema与数据类型优化
选择优化的数据类型 MySQL支持的数据类型非常多,选择正确的数据类型对于获得高性能至关重要.不管存储哪种类型的数据,下面几个简单的原则都有助于做出更好的选择: 更小的通常更好一般情况下,应该尽量使用 ...
- (三)Schema与数据类型优化
1.Schema schema,中文叫模式,是数据库的组织和结构 2.选择优化的数据类型 更小的通常更好:尽量使用可以正确存储数据的最小数据类型 简单就好:简单数据类型的操作通常需要更少的cpu周期. ...
- 深入学习MySQL 03 Schema与数据类型优化
Schema是什么鬼 schema就是数据库对象的集合,这个集合包含了各种对象如:表.视图.存储过程.索引等.为了区分不同的集合,就需要给不同的集合起不同的名字,默认情况下一个用户对应一个集合,用户的 ...
随机推荐
- python 模块:xlrd && xlwt
主要来自:http://www.jb51.net/article/60510.htm python读excel--xlrd 这个过程有几个比较麻烦的问题,比如读取日期.读合并单元格内容.下面先看看基本 ...
- Hibernate学习笔记(5)---Query接口
Hibernate中具有三种检索方式(HQL,QBC,SQL) Query接口 一个查询接口,用于向数据库中查询对象.并控制执行查询的过程.Query接口内封装了一个HQL查询语句. 举个栗子 //查 ...
- 实战经验分享之C#对象XML序列化
.Net Framework提供了对应的System.Xml.Seriazliation.XmlSerializer负责把对象序列化到XML,和从XML中反序列化为对象.Serializer的使用比较 ...
- Error: Can't find Python executable, you can set the PYTHON env variable.
该错误解决方案. NodeJS安装Npm包时出现错误: npm WARN prefer global node-gyp@3.4.0 should be installed with -g > s ...
- vscode 开发工具
做开发两年了,而我记忆力不太好,所以写代码得靠强大的编辑器提示. 陆陆续续使用了如 notepad++.dreamweaver.sublime text.webstorm.phpstorm.Atom等 ...
- python3之运算符
1.python算术运算符 >>> a=15 >>> b=5 >>> a+b #加 20 >>> a-b #减 10 >& ...
- Redis随笔(四)Centos7 搭redis3.2.9集群-3主3从的6个节点服务
1.虚拟机环境 使用的Linux环境已经版本: Centos 7 64位系统 主机ip: 192.168.56.180 192.168.56.181 192.168.56.182 每台服务器是1主 ...
- 使用js对form表单base64加密
利用js可以对前台数据加密,以防止被恶意获取,以下代码,用base64对数据进行加密,可以在后台进行解密. 引入的js <script type="text/javascript&qu ...
- 初识mysql学习笔记
使用VMVirtualBox导入Ubuntu后,可以通过sudo apt-get install mysql-server命令下载mysql. 在学习过程中,我遇到了连接不上Xshell的问题.最终在 ...
- faster-rcnn系列笔记(一)
目录: 1. 序言 2.正文 2.1 关于ROI 2.2 关于RPN 2.3 关于anchor 3. 关于数据集合制作 4. 关于参数设置 5. 参考 1.序言 叽歪一下目标检测这个模型吧,这篇笔 ...