一.库表的设计范式
- 第一范式:表中的任何字段不可拆分
- 第二范式:表中的非主属性都要完全依赖于主键
- 第三范式:满足第二范式的基础上,表中的非主属性不能相互依赖
二.选择更优的数据类型
1.原则
- 更小的通常更好,前提是存储范围不被低估
- 简单为好,简单数据类型处理起来更高效
- 避免存储NULL,可以为NULL的列使得索引、索引统计和值都比较复杂
2.字段类型
-
整型
- tinyint:8
- mediumint:16
- int:32
- bigint:64
- unsingned修饰:范围扩大一倍
int(1)和int(32) 的存储和计算是相同的,只是长度只是规定了交互工具展示的位数
-
实数类型
- 浮点运算
- float:32位
- double:64位
- 精确计算:decimal
- 浮点运算
-
字符类型
- varchar:可变字符串,需要1~2位存储长度,适用场景:
- 最大长度远大于最小长度
- 列的更新很少
- 适用了复杂的字符集,每个字符的字节数不同
- char:固定长度字符串,未完全填充时使用空格,适用场景:
- 非常短的字符串,无需而外存储长度
- 所有字符串长度几乎相同
- 经常修改的数据,比varchar好,不容易出现碎片
- 大文本类型
- blob:二进制,没有排序规则和字符集
- text:有排序规则和字符集
- 枚举类型:存储更为紧凑,同时会将值存为整数
- 日期和时间类型
- datetime:1000~9999,精度微秒
- timestamp:1970年1月1日以来的秒数,依赖于时区(服务器、操作系统、客户端均可设置),插入和更新时会默认更新第一列timestamp值为当前时间
- 压缩位数据类型bit,二进制而非数字类型
- json数据类型,需要存储额外的字符,占用空间更大
- varchar:可变字符串,需要1~2位存储长度,适用场景:
三.设计陷阱
- 避免太多列,服务器和存储引擎之间通过行复制进行工作,服务器将行解码为列,列过多时解码的CPU消耗较高
- 避免太多连接:连接过多时会成为并发的瓶颈
- NULL不是虚拟值,可以使用0、特殊字符、空字符串进行代替