【MySQL】从零开始了解数据库开发 --- 数据类型
从零开始了解数据库开发
- MySQL中的数据类型
- 数字类型
- 字符串类型
- 日期类型
MySQL中的数据类型
MySQL数据库汇中,每一条数据都有其类型,主要分为三类:数字类型,字符串类型,日期时间类型。下面我们依次来介绍
数字类型
类型分类 | 数据类型 | 描述 |
---|---|---|
数字类型 | INT | 整数类型,用于存储整数。 有符号 -231 ~ 231-1 |
数字类型 | TINYINT | 小整数类型,用于存储非常小的整数。有符号 -128 ~ 127 |
数字类型 | SMALLINT | 小整数类型,用于存储较小的整数。 有符号 -215 ~ 215-1 |
数字类型 | MEDIUMINT | 中等大小整数类型,用于存储中等大小的整数。 |
数字类型 | BIGINT | 大整数类型,用于存储大整数。 有符号 -263 ~ 263-1 |
数字类型 | FLOAT[(M , D)] | 单精度浮点数类型,用于存储单精度浮点数。 M指定长度,D指定小数位数 |
数字类型 | DOUBLE [(M , D)] | 双精度浮点数类型,用于存储双精度浮点数。 |
数字类型 | DECIMAL [(M , D)] | 定点数类型,用于存储精确的小数。 |
数字类型 | BIT(M) | 位类型。M指定位数,默认值1 ,范围1-64 |
数字类型分为了整型,浮点型,位类型。创建表时可以选择合适的数据类型进行储存
我们先来看整型:我们创建这样一个表
我们插入一下age这个数据:
可以看到对于tinyint类型,超出其范围的数据是不能被插入到数据表中的。如果是unsigned tinyint类型呢
对于无符号的,返回就是0~255,超出范围的数据就不能被储存。对于其他整型类型也是一样的。
这个对于非法数据插入时的保持拦截是mysql的一个重要特性,在c/c++中,出现这种超出范围的存储char c = 123546
,编译器不一定会报错,可能会优化进行截断,c储存的值就不是我们赋予的值。如果数据库也这么处理,那么数据库中的数据将变得不可信!所以这种拦截可以保证插入到数据库中的数据一定是合法的!所以:数据类型本身也是一种约束
注意:尽量不使用unsigned,对于int类型可能存放不下的数据,int unsigned同样可能存放不下,与其如此,还不如设计时,将int类型提升为bigint类型 但是也一定要注意使用合适的类型,对于数据库庞大的数据,每一个都浪费一点,那么会造成很大的资源浪费!
再来看字节类型BIT(M),我们创建一个表:
可以看到超出1位的数值不能被插入。
最后来看浮点数:
float[(m, d)] [unsigned] : M指定显示长度,d指定小数位数,占用空间4个字节
创建一张这个表
我们插入几行数据
通过这个插入可以发现,对于整数部分超出M-d位的是不能被存储的,如果小数部分超出,则会进行四舍五入保值。注意四舍五入后如果超出范围,也会被拦截。对于浮点型的无符号类型,是对储存类型直接去掉负数,储存的上限不会变。
当把数据类型改为float时,如果数值超出其储存范围,会出现损失精度的现象:
对于float无法储存的数据,这里建议使用decimal。
我们建立一个这样的表,插入同样的数据:
decimal的精度显然更高!
decimal整数最大位数m为65。支持小数最大位数d是30。如果d被省略,默认为0.如果m被省略,默认是10。
建议:如果希望小数的精度高,推荐使用decimal。
字符串类型
类型分类 | 数据类型 | 描述 |
---|---|---|
字符串类型 | VARCHAR | 变长字符串类型,用于存储可变长度的字符串。 最多只能是65535 |
字符串类型 | CHAR | 定长字符串类型,用于存储固定长度的字符串。 最多只能是255 |
字符串类型 | TEXT | 文本类型,用于存储长文本。 |
字符串类型 | TINYTEXT | 微型文本类型,用于存储非常短的文本。 |
字符串类型 | MEDIUMTEXT | 中等长度文本类型,用于存储中等长度的文本。 |
字符串类型 | LONGTEXT | 长文本类型,用于存储非常长的文本。 |
字符串类型 | BLOB | 二进制大对象类型,用于存储二进制数据。 |
字符串类型 | TINYBLOB | 微型二进制大对象类型,用于存储非常小的二进制数据。 |
字符串类型 | MEDIUMBLOB | 中等长度二进制大对象类型,用于存储中等长度的二进制数据。 |
字符串类型 | LONGBLOB | 长二进制大对象类型,用于存储非常长的二进制数据。 |
字符串类型 | ENUM | 枚举类型,用于存储枚举值,即一组预定义的字符串。 |
字符串类型 | SET | 集合类型,用于存储一组预定义的字符串,可以包含多个值。 |
字符串类型最典型的就是 char与varchar。我们先来看char,这是一个固定长度的字符串,我们的插入必须是小于等于其长度。
这里发现汉字和英语字母都是最大插入三个,但是utf8编码中汉字是占3个字节,所以:mysql中的字符与c/c++中不同 ,字符可以是字母或汉字。c/C++中字符就是一个字节,mysql不是!
再来看varchar(L): 可变长度字符串,L表示字符长度,最大长度65535个字节。
这里性质与char一致,大于其长度的无法插入。
再来看这样一个现象,当我们想要修改varchar的储存长度为65535时,会出现一个报错:
提升我们不能扩展到65535,而只能到16383。这里是因为根据字符集的规定,中文字符可能会使用不同的字节数:
- 如果你使用的是utf8mb4字符集(MySQL推荐使用的完整UTF-8编码),每个中文字符确实占用4个字节
- 如果是utf8字符集,每个中文字符占用3个字节
- 如果是latin1字符集,每个中文字符可能无法正常存储
所以对于utf8mb4字符集字符集65535个字节最多只能储存16383个中文字符!
varchar(len)与编码密切相关!varchar长度可以指定为0到65535之间的值,但是有1 - 3 个字节用于记录数据大小,所以说有效字节数是65532
如果储存的长度过长,建议使用大文本储存。
如何选择定长或变长字符串?
- 如果数据确定长度都一样,就使用定长(char),比如:身份证,手机号,md5
- 如果数据长度有变化,就使用变长(varchar), 比如:名字,地址,但是你要保证最长的能存的进去。
- 定长的磁盘空间比较浪费,但是效率高。
- 变长的磁盘空间比较节省,但是效率低。
- 定长的意义是,直接开辟好对应的空间
- 变长的意义是,在不超过自定义范围的情况下,用多少,开辟多少
- 两者的关系与 c/c++中的 char[ ] 与 string 很相似
日期类型
类型分类 | 数据类型 | 描述 |
---|---|---|
日期类型 | DATE | 日期类型,用于存储日期值(年-月-日)。 |
日期类型 | TIME | 时间类型,用于存储时间值(时:分:秒)。 |
日期类型 | DATETIME | 日期时间类型,用于存储日期和时间值(年-月-日 时:分:秒)。 |
日期类型 | TIMESTAMP | 时间戳类型,用于存储时间戳值,表示自1970-01-01 00:00:00 UTC以来的秒数。 |
常用的日期有如下三个:
- date :日期 ‘yyyy-mm-dd’ ,占用三字节。记录需要储存的时间日期
- datetime :时间日期格式 ‘yyyy-mm-dd HH:ii:ss’ 表示范围从 1000 到 9999 ,占用八字节。记录需要储存的时间日期
- timestamp :时间戳,从1970年开始的 yyyy-mm-dd HH:ii:ss 格式和 datetime 完全一致,占用四字节。一个表中可以有多个TIMESTAMP字段,但只有一个可以设置为
DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
。这个是记录数据的创建/修改时间。