选择最佳的数据类型
原则:
- Smaller is usually better
- Simple is good
- avoid null if possible
- null列需要更多的存储空间以及需要特殊的处理
- 当null列作为索引的时候,将会使固定长度的索引转换为长度可变的
步骤:
- 为列选择合适数据类型。如数字,字符
- 选择特殊的类型。如datatime 和 timestamp都可以存储时间。后者用的存储空间只有前者的一半,且是自动更新的。
整数
类型 | 字节数 |
---|---|
TINYINT | 8 |
SMALLINT | 16 |
MEDIUINT | 24 |
INT | 32 |
BIGINT | 64 |
实数
类型 | 字节数 |
---|---|
FLOAT | 4 |
DOUBLE | 8 |
DECIMAL | 依赖于(M,D),M>D时,为M+2,否则为D+2 |
字符类型
VARHCAR 和 CHAR
varchar使用1到2个字节记录长度。因此最大长度不能超过65535。
varchar节省存储空间。如保存‘132’,对于varchar(100)和varchar(200),存储的空间都是一样的。但是内存的消耗不一样。
char是固定长度的。当使用char(100)保存‘132’时,会用空字符填充后面的剩余空间。
char是存储MD5值得最好选择。存储短的字符串时,最好使用char,效率也更高
什么时候应该使用char
- 某个字段的字符长度比较短时使用char
- 字段长度固定或相近时
BOLB和TEXT类型
用于存储大量的二进制和字符串。MySQL将BOLB和TEXT视为对象。
BOLB和TEXT的查询不是通过整个字符串的匹配进行查询的。而且根据匹配其子字符串。该子字符串的长度可以用max_sort_length进行设置。
内存引擎是不支持这两种数据类型的。因此如果要查询这两种类型的数据需要建立磁盘上的临时表。所以尽量避免使用BLOB和TEXT类型。如果无法避免,可以使用order by substring转换成子串的形式转换成表存在内存中。
使用枚举类型代替字符串
不适合使用枚举类型的情景:当字符串在未来可能会发生改变
MySQL将每一个枚举值保存为整数。这样能够节省空间。我们在设定主键的时候,也应该使用整数来作为主键。
日期和时间类型
DATETIME:
格式:YYYYMMDDHHMMSS
长度:8个字节
与时区无关。
TIMESTAMP
14位的TIMESTAMP的格式为YYYYMMDDHHMMSS
长度:4个字节
时间从1970年1月1日开始算起,与时区相关
尽量使用TIMESTAMP,因为它更节省空间。对于精确到毫秒的时间,可以使用BIGINT存储或者使用DOUBLE储存小数部分。
比特封装类型
BIT
BIT能够存储一个或者多个布尔值。但是MySQL将BIT当做字符串处理。
应该尽量避免这种类型。如果需要存储一个布尔值的话,可以使用CHAR(0),可以保存NULL或者是长度为0的字符串。
SET
SET能够保存多个布尔值,用以表示一系列位的集合
选择标识符
整数类型通常是标识列的最好选择
尽量避免使用ENUM和SET类型作为标识列
也尽量避免使用字符串类型。
- 因为他们很消耗空间,而且慢。如果使用的是MyISAM表,MyISAM会对字符串使用压缩索引,会更慢。
- 对于随机的字符串如MD5的也要注意,因为随机值分布在很大空间,会随机索引到不同职位。会使得insert和select变得很慢。
在使用ORM(对象关系映射)时,要注意自动生成的schema。有时候会为每个对象的每个属性使用单独的行,导致单个属性会有多个版本的存在。