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就是数据库对象的集合,这个集合包含了各种对象如:表.视图.存储过程.索引等.为了区分不同的集合,就需要给不同的集合起不同的名字,默认情况下一个用户对应一个集合,用户的 ...
随机推荐
- Jenkins 学习笔记
Jenkins 的内容网站蛮多的,但是一开始我看起来确实很费劲.似乎好多东西都是悬空的,没有把底层的信息交代清楚. 我把自己对于 Jenkins 的探索过程记录下来,如下. 目录 Jenkins 学习 ...
- Nginx集群之WCF大文件上传及下载(支持6G传输)
目录 1 大概思路... 1 2 Nginx集群之WCF大文件上传及下载... 1 3 BasicHttpBinding相关配置解析... 2 4 编写 ...
- vue实现星级评价效果
希望对你们有用,已经自己试过可以的才发布出来的 效果如下: html: <template> <div class="evaStar"> <ul cl ...
- HTML 中有用的字符实体
HTML 中有用的字符实体
- Windows资源
Windows资源是一种二进制数据,由链接器链接进程序成为程序的一部分,通过资源的方式可以很方便的对应用程序进行扩展.在Windows中资源可以是系统自定义的,也可以是用户自定义的.在VC++中资源是 ...
- CSS中的块级元素(block)与行内元素(inline)
css中有3种基本的定位机制:普通流(相对定位实际上看做普通流定位模型的一部分)浮动(float)绝对定位(固定定位是绝对定位的一种)所以在学习浮动之前,我们先要了解块级元素与内联元素(行内元素).块 ...
- 大白话说Java泛型(一):入门、原理、使用
文章首发于[博客园-陈树义],点击跳转到原文<大白话说Java泛型(一):入门.原理.使用> 远在 JDK 1.4 版本的时候,那时候是没有泛型的概念的.当时 Java 程序员们写集合类的 ...
- css的常用效果总结
1.模糊遮罩效率,模糊滤镜效果 -webkit-filter: blur(3px); -moz-filter: blur(3px); -o-filter: blur(3px); -ms-filter: ...
- Python模块学习系列
python模块-time python模块-datetime python模块-OS模块详解
- Zabbix实战-简易教程(4)--Server端安装
在数据库安装完成后,接着开始安装server端了.我们这里采用yum安装. 3.2.0 安装需求 ● PHP 5.6.18 ● curl 7.47.1 ● zabbix_server (Zabbix) ...