《高性能MySQL》笔记——MySQL建表数据类型的选择
前段时间看了《高性能MySQL》中的选择优化的数据类型,这里主要是做一下笔记。
首先数据选择有几个简单原则:
- 更小的通常更好。一般情况下,应该尽量使用可以正确存储数据的最小数据类型。例如只需要存 0~200,tinyint unsigned 更好。更小的数据类型通常更快,因为它们占用更少的磁盘、内存和 CPU 缓存,并且处理时需要的 CPU 周期也更少。
- 简单就好。简单数据类型的操作通常需要更少的 CPU 周期。例如,整型比字符操作代价更低,因为字符集和校对规则(排序规则)使字符比较 比 整型比较更复杂。这里有两个例子:一个是应该使用 MySQL 内建的类型(date, time, datatime)而不是字符串来存储日期和时间,另一个是应该用无符号整型存储 IP 地址。
- 尽量避免NULL。通常情况下最好指定列为 NOT NULL,除非真的需要存储 NULL 值。如果查询中包含可为 NULL 的列,对 MySQL 来说更难优化,因为可为 NULL 的列使得索引、索引统计和值比较都更复杂。特别是计划在列上建索引,就应该尽量避免设计成可为 NULL 的列。
整数类型:(tinyint,smallint,mediumint,int,bigint)
存储(字节) | 存储(位) | 有符号范围 | 无符号范围 | |
TINYINT | 1 | 8 | -128 ~127 | 0~255 |
SMALLINT | 2 | 16 | -32768~32767 | 0~65535 |
MEDIUMINT | 3 | 24 | -8388608~8388607 | 0~16777215 |
INT | 4 | 32 | -2147483648~2147483647 | 0~4294967295 |
BIGINT | 8 | 64 | -2^63~2^63-1 | 0~2^64-1 |
- 整数类型有可选的 unsigned 属性,表示不允许负值,这大致可以使正数的上限提高一倍。主键自增 id 适合设置为 unsigned 属性的 int 类型。
- MySQL 可以为整数类型指定宽度,例如 int(11),对大多数应用这是没有意义的:它不会限制值的合法范围,只是规定了 MySQL 的一些交互工具(例如 MySQL 命令行客户端)用来显示字符的个数。对于存储和计算来说,int(1) 和 int(20) 是相同的。
实数类型:(float,double,decimal)
- float,double 属于浮点类型(近似值)。decimal 属于定点类型(精确值)。
- MySQL 浮点型和定点型可以用类型名称后加(M,D)来表示,M 表示该值的总共长度,D 表示小数点后面的长度。
- float 使用 4 个字节存储;double 使用使用 8 个字节存储;decimal 则是将数字打包保存到一个二进制字符串中(每 4 个字节存 9 个数字)。例如,decimal(18, 9) 小数点两边将各存储 9 个数字,一共使用 9 个字节:小数点前的数字用 4 个字节,小数点后的数字用 4 个字节,小数点本身占 1 个字节。
- 因为需要额外的空间和计算开销,所以应该尽量只在对小数进行精确计算时才使用 decimal——例如存储财务数据。但在数据量比较大的时候,可以考虑使用 bigint 代替 decimal ,将需要存储的货币单位根据最小的位数乘以相应的倍数即可。
字符串类型:
varchar 和 char 类型
- varchar 类型用于存储可变长字符串,是最常见的字符串数据类型。
- varchar 需要使用 1 或 2 个额外字节记录字符串长度:如果列的最大长度小于或等于 255 字节,则只使用 1 个字节表示,否则使用 2 个字节。
- char 类型是定长的:MySQL 总是根据定义的字符串长度分配足够的空间。
- char 存储会删除存储数据的末尾空格;varchar 不会。(准确来说是 MySQL 4.1 以后的版本 varchar 不会删除存储数据的末尾空格)
blob 和 text 类型
- blob 和 text 都是为了存储很大的数据而设计的字符串数据类型,分别采用二进制和字符方式存储。
- 与其它类型不同,MySQL 把每个 blob 和 text 值当作一个独立的对象处理。
- blob 和 text 家族之间仅有的不同是 blob 类型存储的是二进制数据,没有排序规则或字符集,而 text 类型有字符集和排序规则。
- memory 引擎不支持 blob 和 text 类型。
枚举(enum)类型
- MySQL 在内部会将每个值在列表中的位置保存为整数,并且在表的 .frm 文件中保存 “数字-字符串” 映射关系的 “查找表”。
- 如果使用数字作为枚举常量,这种双重性很容易导致混乱,例如 enum('1', '2', '3') 。建议尽量避免这么做。
- 枚举字段是按照内部存储的整数而不是定义的字符串进行排序的。
日期和时间类型:
- MySQL 能存储的最小时间粒度为秒。
- datetime 保存范围从 1001 年到 9999 年,精度为秒。与时区无关。使用 8 字节的存储空间。
- timestamp 类型保存了从 1970 年 1 月 1 日 午夜(格林尼治标准时间)以来的秒数,它和 unix 时间戳相同。使用 4 字节的存储空间,范围从 1970 年到 2038 年。与时区有关。
- MySQL 4.1 以及更新的版本按照 datetime 的方式格式化 timestamp 的值,这仅仅是显示格式上的区别,timestamp 的存储格式在各个版本都是一样的。
- 除了特殊行为之外,通常也应该尽量使用 timestamp ,因为它比 datetime 空间效率更高。有时候人们会将 unix 时间戳存储为整数值,但这不会带来任何收益。用整数保存时间戳的格式通常不方便处理,所以我们不推荐这么做。(对于这点很多公司项目中是用整数存储,我也查了资料,使用整数的理由一般是日期比较,计算时整数更好处理)
《高性能MySQL》笔记——MySQL建表数据类型的选择的更多相关文章
- 点评阿里JAVA手册之MySQL数据库 (建表规约、索引规约、SQL语句、ORM映射)
下载原版阿里JAVA开发手册 [阿里巴巴Java开发手册v1.2.0] 本文主要是对照阿里开发手册,注释自己在工作中运用情况. 本文内容:MySQL数据库 (建表规约.索引规约.SQL语句.ORM映 ...
- 关于Hibernate 连接mysql不能自动建表的问题
最近看旧书,李刚那本<轻量级J2EE>在讲解hibernate的时候遇到一个问题,就是与mysql连接后,明明配置了自动建表,却老是建不了表,上网查了发现是方言的原因,到底什么是方言?这里 ...
- MySql笔记之数据表
数据表:行称为记录 列称为字段 用来存储数据 一.数据类型 数据类型是指列.存储过程参数.表达式和局部变量的数据特征,它决定了数据的存储格式,代表了不同的信息类型. 在我们存储不同类型的数据时,为了 ...
- MySQL基础2-创建表和主键约束
1.创建表 在操作数据表之前,应该使用"USE 数据库名"指定操作是在哪个数据库中进行 主键约束(唯一标识) ****非空*** ****唯一*** ****被引用****(学习外 ...
- mysql那些事(4)建库建表编码的选择
mysql建数据库或者建表的时候会遇到选择编码的问题,以前我们都是习惯性的选择utf8,但是在mysql在5.5.3版本后加了utf8mb4的编码,utf8mb4可以存4个字节Unicode,mb4就 ...
- 涂抹mysql笔记-mysql管理工具
五花八门的mysql管理工具<>mysql提供的命令行工具 mysql_install_db:mysql建库工具,在源码安装mysql环节我们使用过. mysql_safe:mysql启动 ...
- 涂抹mysql笔记-mysql复制特性
<>mysql复制特性:既可以实现整个服务(all databases)级别的复制,也可以只复制某个数据库或某个数据库中的某个指定的表对象.即可以实现A复制到B(主从单向复制),B再复制到 ...
- 涂抹mysql笔记-mysql性能调优和诊断
<>关键性指标1.IOPS(Input/Output operations Per Second)每秒处理的I/O请求次数:需要说明的一点,通常提到磁盘读写能力,比如形容它每秒读300M写 ...
- 涂抹mysql笔记-mysql数据库文件结构
<>初始化选项文件:默认位置:windows平台 windir\my.ini windir可通过echo $WINDIR$查看 系统盘的根目录即:c:\my.ini installdir\ ...
随机推荐
- EJB是什么?
1. 我们不禁要问,什么是"服务集群"?什么是"企业级开发"? 既然说了EJB 是为了"服务集群"和"企业级开发",那么 ...
- percona mysql 5.7再centerOS 7上的安装
第一次测试装的,还不是很熟练.很多东西不太对,以后还回改进 一.卸载包检查是否安装有MySQL Server: rpm -qa | grep mysql rpm -qa | grep mariadb ...
- 爬虫入门之urllib库(一)
1 爬虫概述 (1)互联网爬虫 一个程序,根据Url进行爬取网页,获取有用信息 (2)核心任务 爬取网页 解析数据 难点 :爬虫和反爬虫之间的博弈 (3)爬虫语言 php 多进程和多线程支持不好 ja ...
- npm 安装axios和使用增删改查
1:安装axios(建议安装淘宝镜像) npm install axios 2:项目导入 npm install --save axios vue-axios 3:页面导入 import axios ...
- 通过一个实际例子理解Kubernetes里pod的自动scale - 水平自动伸缩
kubectl scale命令用于程序在负载加重或缩小时进行pod扩容或缩小,我们通过一些实际例子来观察scale命令到底能达到什么效果. 命令行创建一个deployment: kubectl run ...
- 将nodeList转换为数组(兼容性)
将nodeList转换为数组(兼容性) function arrayofNodes(nodes){ var arr = null; try{ arr = Array.prototype.slice.c ...
- escape,unescape与encodeURIComponent,decodeURIComponent
escape:将string转成unicode字符串 escape('
- ACM-ICPC (10/12)
01分数规划 背景:根据楼教主回忆,曾经在一场比赛中秒掉了一道最优比例生成树问题,导致很多人跟风失败,最终悲剧. 什么是01分数规划呢? 这样的等式求最大,最小即为01分数规划. 如果你不知道该如何 ...
- POJ 3070 矩阵快速幂
题意:求菲波那切数列的第n项. 分析:矩阵快速幂. 右边的矩阵为a0 ,a1,,, 然后求乘一次,就进一位,求第n项,就是矩阵的n次方后,再乘以b矩阵后的第一行的第一列. #include <c ...
- position中需要注意的地方
relative是相对元素本身位置进行移位,但不会改变本身位置的大小 本身的位置 移位后,可以看到,p5的位置还是在那,并不会自动往上走,也就是p2的位置原来所占据的位置不变的.不会因为偏移而改变布局 ...