1. 选择更小的数据类型:一般情况下,应该尽量使用可以正确存储数据的最小数据类型。更小的数据类型通常更快,它们占用更少的磁盘、内存和CPU缓存,并且处理时需要的CPU周期也更少。但是要确保没有低估需要存储的值的范围
  2. 尽量选择简单的数据类型:简单数据类型的操作通常需要更少的CPU周期,例如整型比字符操作代价更低,因为字符集和校对规则(排序规则)使字符比较比整型比较更复杂(eg:存储日期和时间应该使用MYSQL内建的类型(date,time,datetime)而不是字符串;存储IP地址应该用整型)
  3. 尽量避免NULL:通常情况下最好指定列为NOT NULL,除非真的需要存储NULL值。如果查询中包含可为NULL的列,对MYSQL来说更难优化
    1. 可为NULL的列使得索引、索引统计和值比较都更为复杂
    2. 可为NULL的列会使用更多的存储空间,在MYSQL里也需要特殊处理
    3. 当可为NULL的列被索引时,每个索引记录需要一个额外的字节,在MyISAM里甚至还可能导致固定大小的索引(例如只有一个整数列的索引)变成可变大小的索引

(通常把可为NULL的列改完NOT NULL带来的性能提升比较小,所以调优时没有必要首先在现有schema中查找并修改掉这种情况,除非确定这会导致问题,但是如果计划在列上建索引,就应该尽量避免设计成可为NULL的列。当然也有例外,例如值得一提的是,InnoDB使用单独的位存储NULL值,所以对于稀疏数据(即很多值为NULL,只有少数行的列有非NULL值)有很好的空间效率,但这一点不适用于MyISAM)

数据类型:

  • 整数类型:

整数类型分为两种:整数和实数。整数类型分为:TINYINT(8位存储空间),SMALLINT(16位存储空间),MEDIUMINT(24位存储空间),INT(32位存储空间),BIGINT(64位存储空间),存储的值的范围,N为存储空间的位数。可选UNSIGNED属性,表示不允许负值,大致可使证书的上限提高一倍,有符号和无符号类型使用相同的存储空间,并具有相同的性能。MYSQL可以为整数类型指定宽度,例如INT(11),对于大多数应用这是没有意义的,它不会限制值的合法范围,只是规定了MYSQL的一些交互工具,如MYSQL命名行客户端用来显示字符的个数,对于存储和计算来说,INT(1)和INT(20)是相同的。

实数是带有小数部分的数字。但不只是用于存储小数部分,可以使用DECIMAL存储比BIGINT还大的整数。MYSQL既支持精确类型,也支持不精确类型。 DECIMAL只是一种存储格式,在计算中DECIMAL会转为DOUBLE类型。有多种方法可以指定浮点列所需要的精度,这会使得MYSQL悄悄选择不同的数据类型,或者在存储时对值进行取舍。这些精度定义是非标准的,所以最好只指定数据类型不指定精度。

  • 字符串类型:

VARCHAR类型用于存储可变长字符串,比定长类型更节省空间(如果MYSQL表使用ROW_FORMAT=FIXED创建的话,每一行都会使用定长存储,这会很浪费空间)VARCHAR需要使用1或2个额外字节记录字符串的的长度:如果列的最大长度小于或等于255字节,则只使用1个字节表示,否则使用2个字节。VARCHAR节省存储空间,但是在UPDATE时可能使行变得比原来更长,导致需要做额外的工作。1.字符串列的最大长度比平均长度大很多;2.猎德更新很少,碎片不是问题;3.使用了像UTF-8这样复杂的字符集,每个字符都是用不同的字节数进行存储时;以上3种情况适合是用VARCHAR。(使用VARCHAR(5)和VARCHAR(200)存储'hello'的空间开销是一样的,但是更长的列会消耗更多的内存,因为MYSQL通常会分配固定大小的内存块来保存内部值。尤其是使用内存临时表进行排序或操作时会特别糟糕;在利用磁盘临时表进行排序时也同样糟糕,所以最好的策略是只分配真正需要的空间)

CHAR类型是定长的,适合存储很短的字符串,或者所有值都接近一个长度的数据。例如,CHAR非常适合存储密码的MD5值,因为这是一个定长的值。对于经常变更的数据,CHAR也比VARCHAR更好,因为定长的CHAR类型不容易产生碎片。对于非常短的列,CHAR比VARCHAR在存储空间上更有效率。存储CHAR值时,MYSQL会删除所有的末尾空格。

  • BLOB和TEXT类型

BLOB和TEXT都是为存储很大的数据而设计的字符串数据类型,分别采用二进制和字符方式存储。BLOB是SMALLBLOB的同义词,TEXT是SMALLTEXT的同义词(字符型包含:TINYTEXT,SMALLTEXT,TEXT,MEDIUMTEXT,LONGTEXT;对应的二进制类型:TINYBLOB,SMALLBLOB,BLOB,MEDIUMBLOB,LONGBLOB)BLOB与TEXT的不同:BLOB类型存储的是二进制数据,没有排序规则或字符集,而TEXT类型有字符集和排序规则。MYSQL对BLOB和TEXT列进行排序与其他类型不同,只对每列的最前max_sort_length字节而不是整个字符串做排序。如果只需要排序前面一小部分字符,则可以减小max_sort_legth的配置。或者使用ORDER BY SUSTRING(column,length)

  • ENUM枚举类型

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

CREATE TABLE enum_test( e ENUM('fish','apple','dog') NOT NULL);

INSERT INTO enum_test(e) VALUES('fish'),('dog'),('apple');

以上三行数据实际存储为整数,而不是字符串,如果使用数字作为ENUM枚举常量,这种双重性很容易导致混乱,例如ENUM('1','2','3')应尽量避免这么做。另外,枚举字段是按照内部存储的整数而不是定义的字符串进行排序的(即,以上数据按照 'fish','apple','dog'的顺序进行排序),所以定义枚举列时,应按照需要的顺序来定义,或者在查询中使用FIELD()函数显式地指定排序顺序,但是会导致MYSQL无法利用索引消除排序。

枚举的缺点:字符串列表是固定的,添加或删除字符串必须使用ALTER TABLE,因此对于一系列未来可能会改变的字符串,使用枚举不是一个好主意,除非能接受只在列表末尾添加元素。由于MYSQL把每个枚举值保存为整数,并且必须进行查找才能转换为字符串,所以枚举列有一些开销。通常枚举的列表都比较小,所以开销还可以控制,但也不能保证一直如此。在特定情况下,把CHAR/VARCHAR列与枚举列进行关联可能会比直接关联CHAR/VARCHAR列更慢。

  • 日期和时间类型

日期类型分为:DATETIME和TIMESTAMP。

DATETIME类型能保存大范围的值,从1001年到9999年,精度为妙。它把日期和时间封装到格式为YYYYMMDDHHMMSS的整数中,与时区无关,使用8个字节的存储空间。

TIMESTAMP类型保存了从1970年1月1日午夜(格林尼治标准时间)以来的秒数,它和UNIX时间戳相同。TIMESTAMP只使用4个存储空间,因此它的范围比DATETIME小得多:只能表示1970年到2038年。如果在多个时区存储或访问数据,TIMESTAMP和DATETIME的行为将很不一样,TIMESTAMP提供的值与时区有关系,后者则保留文本表示的日期和时间。例如,存储值为0的TIMESTAMP在美国东部时区显示为“1969-12-31 19:00:00”与格林尼治时间差5个小时。TIMESTAMP列默认为NOT NULL。

  • 位数据类型

BIT:MYSQL5.0之前,BIT是TINYINT的同义词,5.0之后二者为两种不同的数据类型。BIT列的最大长度是64位。MYSQL把BIT当作字符串类型,而不是数字类型。

mysql5.7版本中,当检索BIT(1)的值时,结果是一个包含二进制0或1值的字符串,而不是ASCII码的“0”或“1” 8.0.11版本中

SET:如果需要保持很多true/false值,可以考虑合并这些列到一个SET数据类型,它在MYSQL内部是以一系列打包的位的集合来表示的,可以有效利用存储空间。主要缺点是改变列定义的代价较高,需要用ALTER TABLE,改变大表开销过大。一般来说也无法在SET列上通过索引查找。

 

mysql数据库——选择优化的数据类型的更多相关文章

  1. mysql数据库性能优化(包括SQL,表结构,索引,缓存)

    优化目标减少 IO 次数IO永远是数据库最容易瓶颈的地方,这是由数据库的职责所决定的,大部分数据库操作中超过90%的时间都是 IO 操作所占用的,减少 IO 次数是 SQL 优化中需要第一优先考虑,当 ...

  2. MySQL数据库笔记二:数据类型及数据库操作

    三.MySQL数据库数据类型 MySQL数据库中支持多种数据类型:数值型.字符型.日期型 常用的数据类型: 1.整型 int:整形,存储整数 int(M):M表示预期值.与存储大小和数值的范围无关. ...

  3. MySQL数据库性能优化:表、索引、SQL等

    一.MySQL 数据库性能优化之SQL优化 注:这篇文章是以 MySQL 为背景,很多内容同时适用于其他关系型数据库,需要有一些索引知识为基础 优化目标 减少 IO 次数IO永远是数据库最容易瓶颈的地 ...

  4. mysql数据库索引优化

    参考 :http://www.cnblogs.com/yangmei123/archive/2016/04/10/5375723.html MySQL数据库的优化:    数据库优化的目的:     ...

  5. MYSQL数据库的优化

    我们究竟应该如何对MySQL数据库进行优化?下面我就从MySQL对硬件的选择.MySQL的安装.my.cnf的优化.MySQL如何进行架构设计及数据切分等方面来说明这个问题. 服务器物理硬件的优化 在 ...

  6. MySQL数据库的优化(下)MySQL数据库的高可用架构方案

    MySQL数据库的优化(下)MySQL数据库的高可用架构方案 2011-03-09 08:53 抚琴煮酒 51CTO 字号:T | T 在上一篇MySQL数据库的优化中,我们跟随笔者学习了单机MySQ ...

  7. [转]MySQL数据库的优化-运维架构师必会高薪技能,笔者近六年来一线城市工作实战经验

    本文转自:http://liangweilinux.blog.51cto.com/8340258/1728131 年,嘿,废话不多说,下面开启MySQL优化之旅! 我们究竟应该如何对MySQL数据库进 ...

  8. MySQL数据库的优化-运维架构师必会高薪技能,笔者近六年来一线城市工作实战经验

    原文地址:http://liangweilinux.blog.51cto.com/8340258/1728131 首先在此感谢下我的老师年一线实战经验,我当然不能和我的老师平起平坐,得到老师三分之一的 ...

  9. 我的mysql数据库sql优化原则

    原文 我的mysql数据库sql优化原则 一.前提 这里的原则 只是针对mysql数据库,其他的数据库 某些是殊途同归,某些还是存在差异.我总结的也是mysql普遍的规则,对于某些特殊情况得特殊对待. ...

随机推荐

  1. jdbc原理与步骤

    jdbc原理 1.加载JDBC驱动,并将其注册到DriverManager 2.建立数据库连接,获取connection对象 3.建立Statement对象或PreparedStatement对象 4 ...

  2. 基于gis的系统开发,程序运行出现问题 ArcGIS product not specified.You must first bind to an ArcGIS version prior to using any ArcGIS components.

    在之前初始化的时候添加下面的一行代码:ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.EngineOrDesktop);还需要添加一个引 ...

  3. Java知识系统回顾整理01基础05控制流程05 continue

    continue:继续下一次循环 一.continue 题目: 如果是双数,后面的代码不执行,直接进行下一次循环 要求效果: 答案: public class HelloWorld { public ...

  4. c++中 预编译头文件PCH

    转载:https://blog.csdn.net/lovemysea/article/details/74858430 一.预编译头文件使用经验: 如果预编译头文件被正确使用时,它确实大大提高我们编程 ...

  5. 获取Jetbrain全家桶激活码

    支持正版,本KEY仅用于体验软件 激活码 激活码一: 2GCA2ZHNKP-eyJsaWNlbnNlSWQiOiIyR0NBMlpITktQIiwibGljZW5zZWVOYW1lIjoi5r+A5r ...

  6. CDH5部署三部曲之一:准备工作

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  7. 如何快速构建React组件库

    前言 俗话说:"麻雀虽小,五脏俱全",搭建一个组件库,知之非难,行之不易,涉及到的技术方方面面,犹如海面风平浪静,实则暗礁险滩,处处惊险- 目前团队内已经有较为成熟的 Vue 技术 ...

  8. webfunny前端监控开源项目

    前言介绍 如果你是一位前端工程师,那你一定不止一次去解决一些顽固的线上问题,你也曾想方设法复现用户的bug,结果可能都不太理想. 怎样定位前端线上问题,一直以来,都是很头疼的问题,因为它发生于用户的一 ...

  9. shell-的变量-局部变量

    1. 定义本地变量 本地变量在用户当前的shell生产期的脚本中使用.例如,本地变量OLDBOY取值为ett098,这个值只在用户当前shell生存期中有意义.如果在shell中启动另一个进程或退出, ...

  10. 安装两个Eclipse 版本不一致,高版本无法打开

    Could not create the JavaVirtual Machine,A fatal exception has occurred. 首先删除了 工作空间的配置 然后删除掉C:\Windo ...