一、数据类型的选择

MySQL的数据类型有很多种,选择正确的数据类型对于获得高性能特别地重要,如何选择合适的数据类型呢?主要遵从以下三个原则:
1.更小的通常情况下性能更好

  一般情况下,应该尽量使用可以正确存储数据的最小数据类型,比如只需存储0--200的整数,则使用 tinyint unsigned 会比 int 好。更小的数据类型通常更快,因为它们占用更小的磁盘、内存和CPU缓存,并且处理时需要的CPU周期也更少。因此在选择的时候应该选择你认为不会超出范围的最小数据类型。

2.简单即为最好

  简单数据类型的操作通常情况下需要的CPU周期更小。比如,整型比字符串操作代价更低,因为字符集和校对规则使得字符的比较比整型比较更加的复杂(如:存储时间通常使用date、time、datetime 比 使用字符串存储性能更好)。

3.尽量避免NULL

  在设计表结构时,最好指定列为NOT NUll,除非真正的需要存储NULL值。

  解释:如果在查询的时候包含有NULL的列,对于MYSQL来说更加的难以优化,因为可以为NULL的列使得索引、索引统计和值比较都非常的复杂。可为NULL的列会使用更多的存储空间,在MYSQL里面也需要特殊的处理。当可以为NULL的列被索引时,每个索引记录需要一个额外的字节,在MyISAM里甚至还可能导致固定大小的索引变为可更改大小的索引(意味着性能受到影响)

二、常见的几种数据类型

1.整数类型

  tinyint(8位)、smallint(16位)、mediumint(24位)、int(32位)、bigint(64位)

  整形类型有可选择的unsigned的属性,如果不需要负数,则使用unsigned会使得存储正数的范围提高到一倍,比如tinyint存储范围为-128---127,使用tinyint unsigned存储的范围变为0---255。

  MySQL可以为整数类型指定宽度例如:int(11),但是对于大多数应用这是没有意义的:因为它不会限制值得合法范围,只是规定了MySQL的一些交互工具用来显示字符的个数,对于存储和计算来说,int(11)跟int(20)没有任何的区别。

2.实数类型

  可以使用decimal存储比bigint还大的整数,decimal用来存储精确的小数,在MySQL5.0以上的版本中decimal还支持高精度的计算。decimal可以指定小数点前后所允许的最大位数,MySQL会将数字打包存储在一个二进制的字符串中。浮点类型在存储同样范围的值时,通常比decimal使用更少的空间。

  选择:因为需要额外的空间计算和开销,所以应该尽量只在对小数进行计算的时候才使用decimal----涉及到财务计算类的业务。但是在数据量比较大的时候可以考虑使用bigint代替decimal,将需要存储的货币单位根据小数的位数乘以相应的倍数即可,这样就可以避免浮点计算的不精确和decimal精确计算的代价高的问题。

3.字符串类型

  varchar类型:

  varchar类型用于存储可变长度的字符串,是最常见的字符串数据类型,它比定长类型更加的节省空间,因为它仅仅使用必要的空间,字符串越短存储空间越小;varchar需要使用1到2个额外的字节来记录字符串的长度:如果字符串长度小于255使用1个字节记录反之使用两个字节存储。比如varchar(1000)它需要1002个字节,因为需要两个字节存储字符串的长度。

  在下面的几种情况下使用varchar是合适的:字符串列的最大长度比平均长度大很多;列的更新很少;使用了utf-8这样的复杂的字符集。

  char类型:

  char类型是定长的:MySQL总是根据定义的字符集长度分配足够的空间。char适合存储很短的字符串,或者所有值都接近同一个长度。例如char非常的适合存储密码的MD5值,因为这些值得长度都定长。对于经常变动的值使用char比varchar更好,因为定长的char类型不容易产生碎片。对于非常短的列,char比varchar在存储空间上也有更好的效率。比如在存储“是”和“否”使用char(1)只使用一个字节,使用varchar(1)却需要两个字节,另一个来存储记录的长度。

4.blob和text类型

  它们两个都被设计来存储很大的字符串类型的数据,blog使用二进制方式存储没有排序规则或字符集,text使用字符串方式存储有排序规则和字符集。与其他数据类型不同的是:MySQL把bolb和text值当做一个独立的对象处理。当它们的值太大时,InnoDB会使用专门的“外部”存储区域进行存储,这时每个值在行内需要1--4个字节存储一个指针,然后在外部存储真实的值。

  对于bolb和text的排序规则也和其他的数据类型不同:bolb和text会对其中前sort_length字符排序,二不是整个字符串排序,还可以指定前多少个字符进行排序,只需要减少max_sort_length的配置即可。

5.日期和时间类型

  datetime类型:

  这个类型能保存最大范围的值,从1001年到9999年,精度为秒。它把日期和时间封装到YYYYMMDDHHMMSS的整数中,使用8个字节的存储空间。

  timestamp类型:

  这个类型能保存最大范围的值,从1970年1月1日年到2038年,精度为秒。它只使用4个字节的存储空间,MySQL提供了from_unixtime()函数把unix时间戳转化为日期格式,和unix_timestamp()把日期格式转化为时间戳格式。

  区别:如果插入的时候timetamp没有指定具体的时间,MySQL会设置这个列为当前的时间,更新的时候回指定更新的时间为当前时间。而datetime则不具有这特性。

  选择:除了特殊情况下选择datetime(存储时间范围很大),其他情况下首选timestamp,因为它的空间效率更高。

  MySQL只支持最小以秒为单位的时间类型,如果需要存储比秒级别更小的时间该任何实现呢?可以使用bigint类型存储微秒级别的时间戳,或者使用double存储秒之后的小数部分。

三、MySQL设计中的一些陷阱

1.太多的列

  MySQL存储引擎在工作的时候需要在服务器层和存储引擎之间通过行缓冲格式拷贝数据,然后在服务器层将缓冲内容解码成各个列。从行缓冲中将编码过的列传换成数据结构的操作代价是非常高的(注意:MyISAM的定长行结构实际上与服务器层的行结构匹配,所以不需要转化)。当一个表列非常多,但是我们使用到的却只有几列时,这时转化代价就非常的大。

2.太对关联的表

  MySQL限制了每个关联的操作最多只能有61个表,但是事实上我们通常情况下有可能会超过这个值,而且就算是在61个表之下,解析和优化查询的代价也是非常大的。一个经验就是,如果希望执行查询得快速并且并发性好,单个查询最好是在12个表以内做关联。

高性能MySQL学习总结二----常见数据类型选择及优化的更多相关文章

  1. MySQL学习(二) 数据类型

    MySQL支持多种列类型:数值类型.日期/时间类型和字符串(字符)类型. 数值类型 数值类型又分为整数型与小数型 整数型 下面的表显示了需要的每个整数类型的存储和范围 创建一张表 mysql> ...

  2. MySQL学习(二)数据类型

    截取书中内容留作学习.... 1.整数类型 2.浮点数与定点数类型 3.日期时间类型 向数据库中插入当前系统时间:CURRENT_TIME或者NOW() 4.文本字符串类型 MySQL枚举类型:cre ...

  3. Typescript 学习笔记二:数据类型

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

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

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

  5. 高性能mysql学习笔记

    此文已由作者朱笑天授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 笔者在工作之余阅读了一下高性能mysql,以下的内容对mysql的介绍以及书中涉及一些概念的总结归纳. 1. ...

  6. MySQL学习笔记(二):MySQL数据类型汇总及选择参考

    本文主要介绍了MySQL 的常用数据类型,以及实际应用时如何选择合适的类型.  ******几个通用的简单原则:******* 1. 更小的通常更好.但是要确保没有低估需要存储的值的范围,如果无法确定 ...

  7. MySQL学习(二)索引原理及其背后的数据结构

    首先区分几个概念: 聚集索引 主索引和辅助索引(即二级索引) innodb中每个表都有一个聚簇索引(clustered index ),除此之外的表上的每个非聚簇索引都是二级索引,又叫辅助索引(sec ...

  8. Mysql学习笔记之常用数据类型 (转)

    http://www.cnblogs.com/doit8791/archive/2012/05/11/2495319.html 数据类型是定义列中可以存储什么数据以及该数据实际怎么存储的基本规则.My ...

  9. MySQL学习笔记(二)

    连接与断开服务器 应该以下面的方式连接MySQL服务器,而不是将密码以明文方式输入连接. C:\> mysql -h host -u user -pEnter password: ******* ...

随机推荐

  1. Cassandra与职业发展 | 阿里云栾小凡 × 蔚来汽车张旭东 × 网龙阙乃祯

    # 活动精彩实录 | Cassandra与职业发展 点击此处观看完整活动录像​ 大家好,我叫邓为,我目前在DataStax担任领航架构师.我在DataStax工作了7年多的时间,也有7年多的Cassa ...

  2. 第2.3节 Python运算符大全

    一. Python的算术运算 Python的算术运算符与C语言类似,略有不同.包括加(+).减(-).乘(*).除(/).取余(%).按位或(|).按位与(&).按位求补(~).左移位(< ...

  3. 第15.39节、splitDockWidget和tabifyDockWidget嵌套布局QDockWidget的PyQt人机对话案例:笨笨机器人

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 一.引言 在第<第三十一章.containers容器类部件QDo ...

  4. kickstart 谷歌 D 2020 年 7 月 12 日 13: 00 - 16: 00

    https://codingcompetitions.withgoogle.com/kickstart/round/000000000019ff08/0000000000386d5c (kick st ...

  5. SQL数据库优化的六种方法

    SQL命令因为语法简单.操作高效受到了很多用户的欢迎.但是,SQL命令的效率受到不同的数据库功能的限制,特别是在计算时间方面,再加上语言的高效率也不意味着优化会更容易,所以每个数据库都需要依据实际情况 ...

  6. 【Codeforces 809E】Surprise me!(莫比乌斯反演 & 虚树)

    Description 给定一颗 \(n\) 个顶点的树,顶点 \(i\) 的权值为 \(a_i\).求: \[\frac{1}{n(n-1)}\sum_{i=1}^n\sum_{j=1}^n\var ...

  7. Spark3.0中Dates和Timestamps

    Spark3.0使用的是预公历,而之前都是儒略历和公历的混合(即1582年之前的日期使用儒略历,1582年之后使用公历,java.sql.Date这个API用的就是这种,而Java8里使用java.t ...

  8. 深入理解Java虚拟机(六)——JVM调优分析与实战

    大内存硬件上的程序部署策略 单个虚拟机管理大内存 出现问题 如果JVM中的堆内存太小,就会频繁地出发GC,而每次GC会将用户线程暂停,所以,频繁地GC会导致长时间的停顿.如果扩大计算的内存的大小,就能 ...

  9. 查找列表中的元素,移动空格 并查找以a或A 为开头 并以c 结尾的元素

    li = ['alec',' aric','Alex','Tony','rain']tu = ('alec',' aric','Alex','Tony','rain')dic = { 'k1':'al ...

  10. java多线程之消费生产模型-使用synchronized解决虚假唤醒

    package com.wenshao.juc; /** * 生产者和消费者案例 * * @author Administrator * */ public class TestProductorAn ...