《高性能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\ ...
随机推荐
- jQuery之检测分析纠错------地狱的镰刀
1. 答: 或者: $(selector).eq(0).hide(); 解答:get() 方法获得由选择器指定的 DOM 元素. 2. 答: 3, 答1: 答2: 4. slideDown()方法格式 ...
- window.frames在不同浏览器中的用法
document.frames 等同于 window.frames,用来取得当前页面内 window 对象的集合. 不支持Firefox,其他浏览器(chrome.opera.IE.360)均支持. ...
- Kafka监控利器
开发过程中,kafka几乎是标配的Mq,如果有一个kafka的监控助手,哪就更完美了,常用的kafka监控工具有 KafkaOffsetMonitor .Kafka Manager.Capillary ...
- bean 的生命周期
就是在new ClassPathXMLApplicationContext 的时候是否就直接在内存中new 出来,如果是对象比较的情景下 ,为了提高程序初始化的速度,可以用用. 如果设置为 true ...
- PHP 运行环境和服务器相关配置
1.在DOS命令窗口输入 mysql -hlocalhost -uroot -p回车 进入mysql数据库, 其中-h表示服务器名,localhost表示本地:-u为数据库用户名,root是mysql ...
- leetcode-pascal triangle I&&II
对于第2个pascal triangle,通过观察可以发现,其实只需要2个额外的变量来记录,于是就设了个tmp数组. 整体有点DP问题中的滚动数组的感觉. #include <vector> ...
- java--内存管理的几点小技巧
今天看一本书,书上提到了内存泄露,后面也提到了内存管理的小技巧,在这里记下来,以免以后忘记. 1.尽量使用直接量.比如:String str = "I can play!";而不是 ...
- SQA1
客观地验证软件项目产品和工作是否遵循恰当的标准.步骤和需求. 2.将软件质量保证工作及结果通知给相关组别和个人.
- 如何将iso文件安装到VirtualBox里的ubuntu去
我在Window的virtualbox里安装了一个ubuntu: 默认情况下IDE Secondary Master是空的. 方法1:Devices->Insert Guest Addition ...
- ubuntu 14.04 64位使用google官方android开发集成工具adt-64位无法使用adb
在使用ubuntu64位(14.04)时,下载来一个adt-bundle-linux-x86_64-20131030.zip,但是运行时报错: Android: Gradle: Execution f ...