良好的逻辑设计和物理设计是高性能的基石,应该根据系统将要执行的查询语句来设计schema,这往往需要权衡各种因素。

例如,反范式的设计可以加快某些类型的查询,但同时可能使另一些类型的查询变慢;添加计数表和汇总表是一种很好的优化查询的方式,但这些表的维护成本可能会很高。

选择优化的数据类型

MySQL支持的数据类型非常多,选择正确的数据类型对于获得高性能至关重要。基本原则为:

  • 更小的通常更好:一般情况下尽量使用可以正确存储数据的最小数据类型,更小的数据类型通常更快,因为其占用更少的磁盘、内存和CPU。
  • 简单就好:简单数据类型的操作通常需要更小的CPU,如整型比字符的操作代价更低,因为字符集和校对规则(排序)使字符比较比整型比较更复杂。实际例子为:应该使用MySQL内建的类型而不是字符串来存储日期和时间;应该使用整型存储IP地址。
  • 尽量避免NULL:通常情况下最好指定列为NOT NULL,除非真的需要存储NULL值,如果计划在列上建立索引,尽量避免设计成可为NULL的列。

在为列选择数据类型时,第一步需要确定合适的大类型:数字、字符串、时间等。下一步是选择具体类型。很多MySQL的数据类型可以存储相同类型的数据,只是存储的长度和范围不一样、允许的精度不同,或者需要的物理空间(磁盘和内存空间)不同。相同大类型的不同子类型数据有时也有一些特殊的行为和属性。

如DATETIME和TIMESTAMP都可以存储日期时间数据,但是TIMESTAMP使用DATETIME一半的存储空间,并且具有随时区变化而自动更新的特性,但其可表示的时间范围又要小得多。

整数类型

整数类型共有TINYINT,SMALLINT,MEDIUMINT,INT,BIGINT。分别使用8,16,24,32,64位存储空间,存储范围从-2(n-1)幂到2(n-1)幂 - 1。整数类型有可选的UNSIGNED属性,表示不允许负值,这可以使正数的上限提升一倍。MySQL可为整数类型指定宽度,如int(11),但其不会限制值的合法范围,只是规定了一些交互工具(如MySQL Client)用来显示字符的个数。对于存储和计算来说,int(1)、int(11)并无区别。

实数类型

实数是带有小数部分的数字,但也可以使用DECIMAL存储比BIGINT还大的整数,MySQL支持精确类型Decimal,也支持不精确类型Float、Double。存储相同范围的值,浮点类型通常比Decimal使用更少的空间,计算开销也更小。

字符串类型

VARCHAR类型用于存储可变长字符串,相较之定长类型更节约空间,最多能存储65535字节数据。VARCHAR需要使用1或2个额外字节记录字符串的长度:如果列的最大长度小于或等于255字节,则只使用1个字节表示,否则使用2个字节。但由于其长度是可变的,在Update时可能会使得行变得比原来更长,如果一个行占用的空间增长,并且在页内没有更多的空间存储时,InnoDB使用分裂页来使行可以放进页内。

CHAR类型是定长的,存储CHAR值时,MYSQL会删除所有的末尾空格。其适用于存储很短的字符串,如使用CHAR(1)存储Y/N,若使用VARCHAR(1)来存储,在相同字符集下会多使用一个字节来记录长度;或是接近于同一个长度,如MD5值。对于经常变更的值,char也比varchar更好,其不易产生碎片。

BLOB和TEXT类型

BLOB和TEXT都是为存储很大的数据而设计的字符串数据类型,分别采用二进制和字符方式存储,分属于两组数据类型家族:TINYTEXT,SMALLTEXT,TEXT,MEDIUMTEXT,LONGTEXT;对应的二进制类型是TINYBLOB,SMALLBLOB,BLOB,MEDIUMBLOB,LONGBLOB。

BLOB类型没有排序规则或字符集,而TEXT类型有字符集和排序规则。BLOB和TEXT在排序时与其他类型也不一样:其只对每个列的最前max_sort_length字节而不是整个字符字符串进行排序。可配置此属性或者使用order by substring(column,length)进行部分排序。

使用枚举代替字符串类型

枚举列可以把一些不重复的字符串存储成一个预定义的集合,MYSQL存储枚举时非常紧凑,会根据列表值的数量压缩到一个或者两个字节中。MySQL内部会将每个值在列表中的位置保存为整数,并且在表的.frm文件中保存数字-字符串映射关系的查找表。下面有一个例子:

使用枚举的好处则是可以节约存储空间,不好的是,字符串列表是固定的,添加或者删除字符串必须使用ALTER TABLE,对于一系列未来可能改变的字符串,使用枚举不是个好主意。

日期和时间类型

MySQL提供两种相似的日期类型:DATETIME和TIMESTAMP,精度均为秒,对于大多数应用程序,其都能工作,但某些场景下,一个比另一个工作得更好。

DATETIME:时间范围为1001~9999年,精度为秒,其将日期时间封装到YYYYMMDDHHMMSS的整数中,与时区无关,使用8个字节存储空间。

TIMESTAMP:保存了自1970-01-01 00:00:00以来的秒数,使用4个字节的存储空间,只能表示1970~2038。TIMESTAMP显示的值依赖于时区,MySQL服务器、操作系统,以及客户端连接都有时区设置。默认情况下,如果插入时没有指定第一个TIMESTAMP列的值,MYSQL 则会设置这个列的值为当前时间;在更新一行记录时,也会默认更新第一个TIMESTAMP列的值。也可以配置TIMESTAMP的插入和更新行为,其默认为NOT NULL,其他数据类型则默认为NULL

选择标识符

为标识符选择合适的数据类型非常重要,在建立索引、联合查询时都有很大影响。选定一种类型之后,需要确保在所有关联的表中都使用同样的类型,类型之间需要精确匹配,包括UNSIGNED这样的属性。混用不同数据类型可能导致性能问题或者由隐式类型转换带来额外的问题。

  • 整数类型通常是标识列最好的选择,速度很快并且可以AUTO_INCREMENT
  • ENUM和SET通常是比较糟糕的选择,除非是固定状态信息
  • 字符串类型,也应该选择其作为标识符,但占用更多的空间(索引),通常速度慢于整型,并且其无序插入会增加索引、空间成本。

特殊数据类型

人们经常使用VARCHAR(15)来存储IPV4地址,然而它们实际上是32位无符号整数,所以应该使用无符号整数来存储IPV4地址,MySQL提供INET_ATON()和INET_NTOA()函数在字符串与无符号整数之间切换。

范式和反范式

对于任何给定的数据通常都有很多种表示方法,从完全的范式化到完全的反范式化,以及两者的折中。在范式化的数据库中,每个事实数据会出现并且只出现一次,相反,在反范式化的数据库中,信息是冗余的,可能会存储在多个地方。范式化设计的优点:

  • 范式化的更新操作通常比反范式化要快,只需要修改更少的数据。
  • 范式化的表通常更小,可以更好地放在内存里,所以执行操作会更快。
  • 很少有多余的数据意味着检索列表数据时更少需要DISTINCT 或者GROUP BY 语句。

    范式化设计的schema的缺点是通常需要关联。稍微复杂一些的查询语句在符合范式的schema上都可能需要至少一次关联,也许更多。这不但代价昂贵,也可能使一些索引策略无效。

反范式的优缺点

反范式化的schema所有数据都在一张表中,其优点为:

  • 不需要进行表关联。
  • 单独的表也能使用更有效的索引策略。

    缺点为更新操作代价过高。实际使用中一般都是范式化与反范式化共用。

缓存表和汇总表

有时提升性能最好的方法是在同一张表中保存衍生的冗余数据。然而,有时也需要创建一张完全独立的汇总表或缓存表(特别是为满足检索的需求时)。

我们用术语“缓存表”来表示存储那些可以比较简单地从schema其他表获取(但是每次获取的速度比较慢)数据的表(例如,逻辑上冗余的数据)。而术语“汇总表”时,则保存的是使用GROUP BY 语句聚合数据的表(例如,数据不是逻辑上冗余的)。

以网站为例,假设需要计算之前24小时内发送的消息数。在一个很繁忙的网站不可能维护一个实时精确的计数器。作为替代方案,可以每小时生成一张汇总表。这样一条简单的查询就可以做到,并且比实时维护计数器要高效得多。缺点是计数器并不是100%精确。

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

  1. MySQL Schema与数据类型优化

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

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

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

  3. Schema 与数据类型优化

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

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

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

  5. MySQL Schema与数据类型的优化

    选择优化的数据类型: 1. 更小的通常更好: 一般情况下,应该尽量使用可以正确存储数据的最小数据类型.更小的数据类型通常更快,因为他们占用更少的磁盘,内存和cpu缓存,并且处理时需要的cpu周期也更少 ...

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

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

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

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

  8. Schema与数据类型优化

    良好的逻辑设计和物理设计是高性能的基石,应该根据系统将要执行的查询数据来设计schema,这往往需要权衡各种因素. MySQL支持的数据类型非常多,选择正确的数据类型对于获得高性能至关重要. 更小的通 ...

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

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

随机推荐

  1. CSS 多行文本溢出省略显示

    文本溢出我们经常用到的应该就是text-overflow:ellipsis了,相信大家也很熟悉,但是对于多行文本的溢出处理确接触的不是很多,最近在公司群里面有同事问到,并且自己也遇到过这个问题,所以专 ...

  2. Libevent2.1.8版在Liunx中编译安装遇到的问题

    Libevent2.1.8版在Liunx中编译安装遇到的问题 前言:在网上找了很久,都没有一个明确的解决方法,通过分析可能的原因,将自己实际操作及解决的成功结果记录如下,以供遇到相似的问题,能提供思路 ...

  3. win10 共享文件夹设置无需用户名密码访问

    文件夹设置共享,添加Everyone 文件夹右键属性,选择共享,添加Everyone,添加后可设置读写权限. 权限添加Everyone,不然没有权限访问 设置安全策略 Win+R 打开运行,输入 se ...

  4. ClouderaManager安装时mysql信息问题

    在安装ClouderaManager5.7时,需要输入mysql信息,如下所示: 记录在此,以防忘记: database host name:localhost database type:MySQL ...

  5. linux 之sed用法

    sed:Stream Editor文本流编辑,sed是一个"非交互式的"面向字符流的编辑器.在使用sed处理时,它把当前处理的行存储在临时缓冲区中,称为"模式空间&quo ...

  6. XCTF GAME

    首先这题有两种解法,一种是使用ida查看伪代码直接写exp跑出flag,另外一种是调试,因为最近在学调试,刚好用于实战上了. 一.查壳 二.32位文件拖入od动态调试 先找到game的主要函数,插件中 ...

  7. ArcnLinux安装基础配置(二)

    本文为对此ArchLinux安装使用教程网站中部分内容的总结和扩展补充,想看更详细的内容可以去此网站. 添加一个用户 useradd -m -G wheel -s /bin/bash cirry 设置 ...

  8. Java基础00-字符串14

    1. API 1.1 API概述 2. String String常用类的常用方法 String字符串变量的创建: 声明:    String 变量名; String str; 声明并初始化: Str ...

  9. nginx+waf防火墙

    1.官网下载nginx源码包(nginx-1.20.0.tar.gz) 新建nginx安装目录​mkdir -p /opt/nginx​新增nginx运行用户​useradd -s /sbin/nol ...

  10. Mycat读写分离的简单实现

    目录 1.Mycat读写分离的配置 1.1.Mycat是什么 1.2.Mycat能干什么 1.2.1.数据库的读写分离 1.2.1.1.数据库读写分离图解 1.2.2.数据库分库分表 1.2.2.1. ...