引言
从第一次学习mysql开始,不知道为什么MySQL的数据类型始终没有像Java 一样深入脑海,对某些数据类型的定义和用法,也并不清晰,这篇文章,就好好总结一番,将MySQL中几个常用的数据类型归纳一下。
一、类型选择的原则
在设计表的时候,首先就是要考虑存储的数据与MySQL的哪种类型相吻合,比如,金额,就要用数字类型,最差也要用字符串类型,日期可以是date 类型,或者也可以是字符串类型,考虑这类问题,其实只需要考虑某个数据类型能否正确的表示将要存储的数据即可。
第二点非常重要原则是:
所选择的类型越简单越好,能保存数值的类型越小越好。
这点不难理解,数据类型描述了物理硬件存储数据的方式,简单的类型更快,小的类型更省空间,因此,在选择数据类型的时候就要尽可能的越小越简单越好,避免存储或性能上的浪费。
二、MySQL常见数据类型
与 Java 不同的是,MySQL的数据类型描述的更为抽象化一些。它们总共分为三类:
数值型、字符型、日期型
2.1 数值型
MySQL支持所有标准SQL数值数据类型。数值型可以分为两大类:整数和小数。
2.1.1 整数
整型共有 5 种:
Type | Storage (Bytes) | Minimum Value Signed | Minimum Value Unsigned | Maximum Value Signed | Maximum Value Unsigned |
---|---|---|---|---|---|
TINYINT | 1 | -128 | 0 | 127 | 255 |
SMALLINT | 2 | -32768 | 0 | 32767 | 65535 |
MEDIUMINT | 3 | -8388608 | 0 | 8388607 | 16777215 |
INT | 4 | -2147483648 | 0 | 2147483647 | 4294967295 |
BIGINT | 8 | -263 | 0 | 263-1 | 264-1 |
从官方文档上来看,INTEGER 和 INT 貌似没有什么太大的区别,可以理解为同义词。从MySQL官网中的说明,我们可以得知,SQL标准的整数类型只有 INTEGER(或 INT)和 SMALLINT,而剩下三种,则是MySQL对标准的一种扩展。
符号的定义是值得注意的点,如果不指定 unsigned 关键字,那么默认是有符号类型。如果插入的数据大于整型的范围,那么就会报 out of range 异常,同时插入临界值。
整型一般可以不设置 Length,这个属性代表了该类型的显示长度。
2.1.2 定点数(Fixed-Point)
定点数属于小数的一种,是一种可以存储精确小数的数据类型。
DECIMAL 和 NUMERIC
这两个类型用于存储确切精度的数据,例如货币数据,当然,个人认为在不同的场景下,可以采用最小货币单位存储方式,比如,在数据库中以整型存储金额,以分作为单位,并在整个系统中保持统一。
MySQL中,NUMERIC 是用 DECIMAL 来实现的,因此两者在本质上是无区别的。
salary DECIMAL(5, 2)
薪资可以使用上面的方式进行定义,那么它所表示的范围就是:-999.99 到 999.99 。前一个参数是总位数,后一个参数代表小数保留的位数。
另外,还有一种特殊的形式 DECIMAL(M) ,它等同于 DECIMAL(M, 0) ,它的意思是没有小数部分。或者干脆不指定任何参数,如果不指定 M 则默认为 10。
这样定义的字段,如果插入的数据超过了限定范围,那么就会插入临界值。
2.1.3 浮点数(Floating-Point)
FLOAT 和 DOUBLE 是两个浮点数类型,前者是单精度占4个字节,后者是双精度占8个字节。它们都是不精确的数据类型。
2.2 字符型
2.2.1 短文本 CHAR 和 VARCHAR
MySQL最常用的字符型是 CHAR 和 VARCHAR ,他们有相似处,同时存取却也存在差异。
CHAR和 VARCHAR 都需要指定一个长度,这个长度描述了需要存储的最大字符个数,如CHAR(30) 可以存储最多 30 个字符,注意,所有单个汉字都算一个字符。
CHAR 类型以定长存储,长度的范围可以是 0 到 255 之间任意值。如果存储的字符不够,那么 MySQL会为其自动以空格填补空间,当取出时,又会为其自动去除。
VARCHAR 类型以变长存储,而且长度范围可以是 0 到 65535 之间任意值。但其有效最大长度取决于最大行大小以及字符集。
Value | CHAR(4) | Storage Required | VARCHAR(4) | Storage Required |
---|---|---|---|---|
'' | ' ' | 4 bytes | '' | 1 byte |
'ab' | 'ab ' | 4 bytes | 'ab' | 3 bytes |
'abcd' | 'abcd' | 4 bytes | 'abcd' | 5 bytes |
'abcdefgh' | 'abcd' | 4 bytes | 'abcd' | 5 bytes |
2.2.2 长文本 TEXT 和 BLOB
BLOB是一个二进制大对象,可以容纳可变数量的数据,TEXT 可以存储较大的文本。
参考官网:https://dev.mysql.com/doc/refman/5.7/en/blob.html
2.2.3 ENUM 类型
在 MySQL中,枚举类型也属于字符型,枚举的值必须是字符串,不区分大小写。如:
CREATE TABLE enum_t(state ENUM('1', '2', '4')
)
枚举类型非常适合定义一些记录状态变化的字段,比如订单状态,这样,可以极好的提升数据的可维护性。在官方给出的说明中,有如下两方面。
优势:
1、压缩了数据出现的情况,同时,MySQL会自动将存储的字符串编码为数字,即进行了一些优化。
2、可读性的查询和输出。MySQL会结果集中自动将底层存储的数字转化回原来定义的字符串。
需要考虑的问题:
1、enum 类型内部维护着从 1 开始的索引值,每个字符串枚举值都对应着一个正整数序号 1、2、3... ,这也是为什么enum 里的枚举值必须是字符串的原因,而且官方也不建议枚举值的字符串和数字看起来很像,这样很容易和索引值混淆,因为我们同样可以直接使用索引值对字段进行插入操作:
2、对枚举字段使用 order by 子句,会按照索引顺序排序。这和Java 中的枚举排序基本一致(Java 中是按照枚举值定义的位置顺序来默认排序的)。另外,空字符串排在所有非空字符串前面,NULL 排在其他所有值前面。
2.2.4 SET 类型
SET 类型可以保存最多64个成员。与 ENUM 最大的区别在 SET 类型一次可以选取多个成员,而 ENUM 只能选取一个。
存储的值用一个引号包裹起来,每个值中间用逗号隔开注意中间不允许有空格:
''
'one'
'two'
'one,two'
2.3 日期型
参考之前的总结《MySQL日期类型的处理总结》
值得一提的是,日期类型需要用引号(单双都可)引起来,换句话说,我们可以直接将日期类型理解为符合日期格式规范的字符串。在Java 中,我们甚至可以直接以字符串的形式与MySQL进行日期类型的交互而不会有任何问题。
综上,就是关于MySQL常用数据类型的简单总结,参考了尚硅谷的MySQL基础视频,以及MySQL官网对数据类型的解释:
https://dev.mysql.com/doc/refman/5.7/en/data-types.html