设计数据库表时,你真的会选数据类型吗
转载自 设计数据库表时,你真的会选数据类型吗
关系型数据库,是开发人员最常接触的持久化存储之一了,使用关系型数据库有很多好处,比如支持通过事务处理保持数据的一致性、数据更新的开销很小、可以进行Join等复杂查询等。
同时,还有个好处就是关系型数据库有比较完善的数据类型,支持很多不同类型的数据存储。但是这些数据类型的使用和选择也有很多套路在的,本文就来简单介绍一下。
1. 整数类型
整数类型有:tinyint、smallint、mediumint、int、bigint,分别使用 8、16、24、32、64 位存储空间。
它们可以存储的值范围从 -2 的 (n-1) 次方到 2 的 (n-1) 次方 -1,n 是存储空间的位数。
整数有可选的 unsigned 属性(无符号类型),表示不允许有负值,因此可以使正数上限提高一倍。
有符号和无符号类型使用相同的存储空间,并具有相同的性能,因此可以根据实际情况选择合适的类型。
2. 实数类型
实数类型有:FLOAT、DOUBLE ,分别占用 4,8 字节。
如果插入值的精度(即:数字总位数)高于实际定义的精度,系统会自动进行四舍五入处理,使值的精度达到要求。
其中 DECIMAL 也可以用来指定精度,并且它比 FLOAT 和 DOUBLE 更适合做精确计算。在本文就不做详细介绍了,如果有人想了解的话可以给我留言,我下次再写。
3. 字符串类型
字符串类型有:
VARCHAR
CHAR
BLOB
TEXT
由于 BLOB 和 TEXT 不常用且由于篇幅问题,就不展开描述了。本文主要对 VARCHAR 和 CHAR 进行介绍,它们的区别如下表:
对比内容 | VARCHAR | CHAR |
---|---|---|
是否固定长度 | 否 | 是 |
存储上限字节 | 65535 | 255 |
保存或检索值时,是否删除字符串末尾空格 | 否 | 是 |
超过设置的范围后,字符串是否会被截断 | 否 | 是 |
除了以上不同之外,VARCHAR 还需要额外使用 1 个或 2 个字节来记录字符串长度。如果列的最大长度小于或等于 255 字节,则使用 1 个字节,否则使用 2 个字节。
由于 VARCHAR 是变长的,所以在 update 时,可能使行变得比原来更长,这就导致需要进行额外的工作。如果一个行占用的空间增加,并且在页内没有更多空间可以存储,在这种情况下,不同存储引擎的处理方式不一样的。例如:MyISAM 会将行拆分为不同的片段存储,InnoDB 则需要分裂页来使行可以放进页内。
在选择使用场景上,重点要抓住 VARCHAR 是变长,CHAR 是定长的特点。
比如在这些情况更适合使用 VARCHAR:
字符串的最大长度比平均长度大很多;
字段更新次数少(所以碎片不是问题);
使用了像 UTF-8 这样复杂的字符集,每个字符都使用不同的字节数进行存储。
而在这些情况则更适合使用 CHAR:
存储很短的字符串(而 VARCHAR 还要多一个字节来记录长度,本来打算节约存储的现在反而得不偿失)
定长的字符串(如 MD5、uuid);
需要频繁修改的字段。因为 VARCHAR 每次存储都要有额外的计算,得到长度等工作;
这里抛出一个小问题:使用 VARCHAR(5) 和 VARCHAR(200) 来存储 ‘hello’ 的空间开销是一样的。那么使用更短的列有什么好处呢?(思考几秒钟?)
答案:节约内存,因为更长的列会消耗更多的内存。MySQL 通常会分配固定大小的内存块来保存内部值。尤其是使用内存临时表进行排序或操作时会特别糟糕。在利用磁盘临时进行排序时也同样糟糕。
所以最好的策略是只分配真正需要的空间。
4. 日期和时间类型
下面表格是 TIMESTAMP 和 DATETIME 的一些对比:
对比内容 | TIMESTAMP | DATETIME |
---|---|---|
占用字节 | 4 | 8 |
时间范围 | 1970-01-01 08:00:01 ~ 2038-01-19 11:14:07 | 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59 |
存储的数据是否随时区变化 | 是 | 否 |
如果在插入数据时,没有指定第一个 TIMESTAMP 列的值,MySQL 则将这个列设置为当前时间,同时 TIMESTAMP 比 DATETIME 的空间效率更高。
最后,网上有很多讨论,时间到底要使用 INT、TIMESTAMP、DATETIME 哪种类型更适合。我认为这没有一个固定答案,具体可以参考文章:《选择合适的 MySQL 日期时间类型来存储你的时间》,我放在原文链接里面了。
5. 设计合理的数据类型
提供给大家 3 点设计原则:
更小的通常更好
简单就好
尽量避免 NULL
下面对其详细说明一下:
一般情况下,应该选择可以正确存储数据的最小数据类型,因为它们占用更少的磁盘、内存和 CPU 缓存,并且处理时需要的 CPU 周期也更少。
简单数据类型的操作需要更少的 CPU 周期。例如,整型比字符操作代价更低,因为字符集和校对规则(排序规则)使字符比较比整型比较更复杂。
通常情况下,最好指定列为 NOT NULL,除非真的需要存储 NULL 值。因为可为 NULL 的列会使索引、索引统计和值比较都更复杂。可为 NULL 的列会使用更多的存储空间,在 MySQL 里也需要特殊处理。
当可为 NULL 的列被索引时,每个索引需要一个额外的字节,在 MyISAM 里甚至还可能导致固定大小的索引变成可变大小的索引。通常把可为 NULL 的列改为 NOT NULL 带来的性能比较小,所以在优化时没有必要先在现有表里修改这种情况。
参考:
《高性能 MySQL》
设计数据库表时,你真的会选数据类型吗相关推荐
- 设计数据库表时数据类型的选择
设计数据库表时数据类型的选择 1. 整数类型 整数类型有:tinyint.smallint.mediumint.int.bigint,分别使用 8.16.24.32.64 位存储空间. 它们可以存储的 ...
- powerdesign java,PowerDesigner设计数据库表
1.说明 使用PowerDesigner设计数据库表, 然后将表设计导出为Word文档, 以及MySQL数据库对应的DDL刷库脚本. 2.创建模型 首先创建概念数据模型: File -> New ...
- 干掉 powerdesigner,设计数据库表用它就够了
点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 点击" 程序员内点事 "关注,选择&q ...
- 一篇文章告诉你如何设计数据库表
0.三大范式及反范式 ◆ 第一范式(1NF):强调的是列的原子性,即列不能够再分成其他几列. ◆ 第二范式(2NF):首先是 1NF,另外包含两部分内容,一是表必须有一个主键:二是没有包含在主键中的 ...
- 根据E-R图设计数据库表
上图是一个E-R图,一共有三个实体:司机.车辆.车队.并且这几个实体之间互相具有一定的联系. 我们首先把所有实体的表写出来. 数据类型的选择请参考文章:https://blog.csdn.net/qq ...
- 数据库建表时,对于字段的数据类型的选择
本文是<数据库设计那些事>的笔记和思考. 有如下几种情形: 当字段可选择多个类型时(比如生日字段,可以用时间戳,即整数类型,可以用字符串 类型,也可以用日期 类型):整数.二进制 优于 日 ...
- Access把每一天的数据累加_如何设计 QQ、微信等第三方账号登陆 ?以及设计数据库表!...
来源:http://suo.im/5SBVka 多账户的统一登录 名称解释 这里的多账户区别于系统级别的,我们讲的多账户系统是指,在我们互联网应用当中,我们的应用会使用多个第三方账号进行登录,比如现在 ...
- oracle数据库纵表设计,oracle 数据库设计-数据库表设计
在数据库设计中,我的工作中经常会分析怎样商业逻辑中的表格如何设计.再设计表的关系之前 需要先了解关系型数据库特点 1关系型数据库,是指采用了关系模型来组织数据的数据库: 2.关系型数据库的最大特点就是 ...
- token 微信access 过期_如何设计 QQ、微信等第三方账号登陆 ?以及设计数据库表!...
来源:http://suo.im/5SBVka 多账户的统一登录 名称解释 这里的多账户区别于系统级别的,我们讲的多账户系统是指,在我们互联网应用当中,我们的应用会使用多个第三方账号进行登录,比如现在 ...
最新文章
- 通过AI翻译大脑信息
- [iOS翻译]《The Swift Programming Language》系列:Welcome to Swift-01
- ffplay.c学习-4-⾳频输出和⾳频重采样
- sql 动态写入数据库字段_批处理写入,动态SQL和参数化SQL,数据库的性能如何?...
- eclipse IDE中無法打開android模擬器
- Android将应用调试log信息保存在SD卡
- java 获取泛型_聊聊Java泛型擦除那些事
- RDD和DataFrame和DataSet三者间的区别
- 【鱼眼镜头1】鱼眼镜头的四种投影模型(指导镜头的设计),中央镜头综述
- mac音频剪辑合并软件哪款比较好用,求推荐
- 普元EOS:执行自定义命名sql查询(无参,有参)
- 基于卷积神经网络CNN的面部表情识别
- 文本框内容改变的绑定事件
- 动环监控安装及调试过程,动环监控调试是什么
- wordpress实现全站HTTPS
- [和管子对话] 1 2007-4-5/对面向对象的你言我语
- 一次github和jenkins集成构建异常处理
- python代码覆盖率工具——coverage
- Sklearn到底是什么?
- python解析xml数据_用Python解析XML数据
热门文章
- 算法题目——子序列和问题(poj-3061)(尺取法)
- java pc计数器_java虚拟机-程序计数器PC Register
- Spring5 jar包下载
- C++vector容器-互换容器
- Circle and Points POJ - 1981(单位圆覆盖最多点)
- 单向链表的逆转(数据结构)(c语言)
- ./include/caffe/util/cudnn.hpp: error: too few arguments to function ‘SetPooling2dDescriptor
- 小 Q 与函数求和 1(牛客练习赛 81 E)
- (CCPC 2020 网络选拔赛)HDU 6900 Residual Polynomial(分治 + NTT)
- P6154 游走 概率dp