良好的逻辑设计和物理设计是高性能的基石,应该根据系统将要执行的查询数据来设计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设计中的陷阱

  1. 太多的列。MySQL存储引擎API工作时需要在服务器层和存储引擎层之间通过行缓冲格式拷贝数据,然后uzai服务器层将缓冲内容解码成各个列。从行缓冲中将编码过的列转换成行数据结构的操作代价是非常高的。
  2. 太多的关联。MySQL限制了每个关联操作最多只能61个关联表,如果希望查询执行得快,并且并发性好,单个查询最好在12个表以内做关联。
  3. 枚举
  4. NULL。不要过分遵循“不适用NULL”的准则。

Schema与数据类型优化的更多相关文章

  1. mysql笔记01 MySQL架构与历史、Schema与数据类型优化

    MySQL架构与历史 1. MySQL架构推荐参考:http://www.cnblogs.com/baochuan/archive/2012/03/15/2397536.html 2. MySQL会解 ...

  2. MySQL Schema与数据类型优化

    Schema与数据类型优化 选择优化的数据类型 1.更小的通常更好 更小的数据类型通常更快,因为它们占用更少的磁盘,内存和CPU缓存 2.简单就好 简单数据类型的操作通常需要更少的CPU周期.例如:整 ...

  3. Schema 与数据类型优化

    这是<高性能 MySQL(第三版)>第四章<Schema 与数据类型优化>的读书笔记. 1. 选择优化的数据类型 数据类型的选择原则: 越小越好:选择满足需求的最小类型.注意, ...

  4. MySQL设计之Schema与数据类型优化

    一.数据类型优化 1.更小通常更好 应该尽量使用可以正确存储数据的最小数据类型,更小的数据类型通常更快,因为它们占用更少的磁盘.内存和CPU缓存,并且处理时需要的CPU周期更少,但是要确保没有低估需要 ...

  5. 高性能MySQL笔记 第4章 Schema与数据类型优化

    4.1 选择优化的数据类型   通用原则   更小的通常更好   前提是要确保没有低估需要存储的值范围:因为它占用更少的磁盘.内存.CPU缓存,并且处理时需要的CPU周期也更少.   简单就好   简 ...

  6. Mysql高性能笔记(一):Schema与数据类型优化

    1.数据类型 1.1.几个参考优化原则 a.  更小的通常更好 i.更小的数据类型,占用更少磁盘.内存和CPU缓存,需要的CPU周期更少 ii.如果无法确定哪个数据类型是最好的,就选择不会超过范围的最 ...

  7. MySQL之Schema与数据类型优化

    选择优化的数据类型 MySQL支持的数据类型非常多,选择正确的数据类型对于获得高性能至关重要.不管存储哪种类型的数据,下面几个简单的原则都有助于做出更好的选择: 更小的通常更好一般情况下,应该尽量使用 ...

  8. (三)Schema与数据类型优化

    1.Schema schema,中文叫模式,是数据库的组织和结构 2.选择优化的数据类型 更小的通常更好:尽量使用可以正确存储数据的最小数据类型 简单就好:简单数据类型的操作通常需要更少的cpu周期. ...

  9. 深入学习MySQL 03 Schema与数据类型优化

    Schema是什么鬼 schema就是数据库对象的集合,这个集合包含了各种对象如:表.视图.存储过程.索引等.为了区分不同的集合,就需要给不同的集合起不同的名字,默认情况下一个用户对应一个集合,用户的 ...

随机推荐

  1. 解决ios手机上传竖拍照片旋转90度问题

    html5+canvas进行移动端手机照片上传时,发现ios手机上传竖拍照片会逆时针旋转90度,横拍照片无此问题:Android手机没这个问题. 因此解决这个问题的思路是:获取到照片拍摄的方向角,对非 ...

  2. Go 语言编写单元测试

    吾尝终日而思矣,不如须臾之所学也:吾尝跂而望矣,不如登高之博见也.登高而招,臂非加长也,而见者远:顺风而呼,声非加疾也,而闻者彰.假舆马者,非利足也,而致千里:假舟楫者,非能水也,而绝江河.君子生非异 ...

  3. Windows同时安装Python2、Python3兼容运行

    Python2.Python3可以同时安装在windows上,关键是如何有选择的运行Python2还是Python3.   指定运行版本 如果你有一个Python文件叫 hello.py,那么你可以这 ...

  4. visual studio相关操作

    1.同一个解决方案下的两个项目之间怎么相互调用 在项目的“引用”上右键,添加引用,选你要引用的项目.然后在代码里就能调用引用项目里的某个类的方法了. 2.如果一个项目类型为”类库“的项目要运行,会报如 ...

  5. cassandra的gc调优

    我们用的是cassandra3.7官方的docker镜像,在生产环境发现有一个小时一次停顿的现象.我猜测是java gc的原因,于是看了cassandra的gc日志,果然发现有每小时长达300ms-2 ...

  6. Spring框架入门之开发环境搭建(MyEclipse2017平台)

    基于MyEclipse2017平台搭建Spring开发环境,这里MyEclipse已将Spring集成好了,我们只需要做一简单配置即可 一.环境配置 OS:Windows7 64位 IDE工具:MyE ...

  7. HTML知识点总结之table

    table元素 table用来创建表格,表格也可以用来布局,但是嵌套过于复杂,不利于灵活布局,已经几乎没人用它来布局了. 表格基本上有如下几个标签构成: (1)<table>标签用来创建表 ...

  8. Yii2基本概念之——属性(property)

    学习任何一门学问,往往都是从起基本的概念学起.万丈高楼平地起,这些基本概念就是高楼的基石,必须做详尽的分析.我们知道,Yii2是一款脉络清晰的框架,理顺了基础的概念和基本功能,学习更高级和复杂的功能就 ...

  9. 深入理解 react-router 路由系统

    作者:范洪春链接:https://zhuanlan.zhihu.com/p/20381597来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 在 web 应用开发中,路由 ...

  10. HDU 5144 NPY and shot(物理运动学+三分查找)

    NPY and shot Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tot ...