专栏:MySQL数据库成长记
个人主页:手握风云
目录
一、常用数据类型分类
我们知道,库是管理数据的最大集合,库里面有很多的数据表,表是由数据行构成的。在面向对象软件开发的过程中,通常会先进行需求分析从而得到类和属性。我们先来看下面的一段Java代码:
class Student{
public int age;
public boolean geder;
public String name;
public Student(int age, boolean geder, String name) {
this.age = age;
this.geder = geder;
this.name = name;
}
}
public class Solution {
public static void main(String[] args) {
Student stu1 = new Student(19,true,"张三");
Student stu2 = new Student(20,false,"李四");
}
}
类是⾯向对象中的概 念,对应到数据库中的概念就是实体,类中的属性对应实体中的属性。实体通常以表的形式存在,每个实体对应⼀张表,表中的每条数据行就是实体的⼀个实例。
如果要定义实体的属性,就要为属性命名并指定合适的数据类型。与其他编程语⾔类似,SQL中规定了⽤于描述属性的数据类型。常用的数据类型有以下几类:
- 数据值类型
- 字符串类型
- 二进制类型
- 日期类型
数据值类型、字符串类型、日期类型我们在Java中经常用到,而二进制类型对应到Java中的byte数组,以二进制的形式存储并往后排。
二、数据值类型
2.1. 类型列表
类型 | 大小 | 说明 |
BIT[(M)] | 默认bit | 位值类型。M表⽰每个值的位数,取值范围为 1 ~ 64 。如果省略M,则默认为1。 |
TINYINT | 1byte | 取值范围 -2^7 ~ 2^7-1 ,无符号取值范围 2^8-1 |
BOOL | 1byte | TINYINT(1)的同义词。值为零被认为是假,⾮零值被认为是true |
SMALLINT[(M)] | 2byte | 取值范围 -2^15 ~ 2^15-1 ,⽆符号取值范围 2^16-1 |
MEDIUMINT[(M)] | 3byte | 取值范围 -2^23 ~ 2^23-1 ,⽆符号取值范围 2^24-1 |
INT[(M)] | 4byte | 取值范围 -2^31 ~ 2^31-1 ,⽆符号取值范围 2^32-1 |
INTEGER[(M)] | 4byte | INT[(M)]的同义词 |
BIGINT[(M)] | 8byte | 取值范围 -2^63 ~ 2^63-1 ,⽆符号取值范围 2^64-1 |
FLOAT | 4byte | 单精度浮点型,M是总位数,D是⼩数点后⾯的位数,⼤约可以精确到⼩数点后7 位 |
DOUBLE | 8byte | 双精度浮点型,M是总位数,D是⼩数点后⾯的位数,⼤约可以精确到⼩数点后 15位。 |
DECIMAL[(M,D)] | 动态 | 不存在精度损失,M是总位数,D是小数点后的位数。DECIMAL的最⼤位数(M)为 65,最大小数位数(D)为30。 |
由于FLOAT和DOUBLE的精度问题,一般在系统开发时不使用这两种数据类型。关于DECIMAL是如何实现精度不受损失的,其实是对一个大数每9位进行拆分,每一份用int来储存,int最大可以储存21亿的数字,再用诺干个int进行表示,而剩余的小数部分则用最小的数据类型来存储。而在真实的开发过程中,尤其像银行和金融这种涉及到大量金额的公司,既使用DECIMAL进行表示表示,但比较麻烦也可以使用int进行存储记录。
2.2. 数据类型取值范围
类型 | 大小 | 有符号最小值 | 有符号最大值 | 无符号最小值 | 无符号最大值 |
TINYINT | 1byte | -128 | 127 | 0 | 255 |
SMALLINT | 2byte | -32768 | 32767 | 0 | 65536 |
MEDIUMINT | 3byte | -8388608 | 8388607 | 0 | 16777215 |
INT | 4byte | -2147483648 | 214783647 | 0 | 4294967295 |
BIGINT | 8byte | -2^63 | 2^63-1 | 0 | 2^64-1 |
三、字符串类型
3.1. 类型列表
类型 | 说明 |
CHAR[(M)] | 固定⻓度字符串, M 表示长度,以字符为单位,取值范围 0 ~ 255 , M 省略则长度为1 |
VARCHAR(M) | 可变⻓度字符串, M 表示字符最大长度,范围0 ~ 65535 ,有效字符个数取 决于实际字符数和使⽤的字符集 |
TINYTEXT | 小文本类型,最大长度为 255 (2^8 - 1)个字符,有效字符个数取决于使用的字符集 |
TEXT[(M)] | 文本类型,最大长度为 65535 (2^16 - 1)个字符,有效字符个数取决于使用的字符集 |
MEDIUMTEXT | 中文本类型,最大长度为 16,777,215 (2^24 - 1)个字符,有效字符个数取决于使用的字符集 |
LONGTEXT | 大文本类型,最大长度为 4,294,967,295 即 4GB (2^32 - 1)个字符,有效字符个数取决于使用的字符集 |
BINARY[(M)] | 固定长度⼆进制字节,与CHAR类似,但存储的是⼆进制字节而不是字符串。 M 表示长度,以字节为单位,取值范围 0 ~ 255 ,M省略则长度为1 |
VARBINARY[(M)] | 可变长度⼆进制字节,与VARCHAR类似,但存储的是⼆进制字节而不是字符串。 M 表示长度,以字节为单位 |
TINYBLOB[(M)] | 小⼆进制字节类型,最大长度为 255 (2^8 - 1)个字节 |
BLOB[(M)] | ⼆进制字节类型,最大长度为 65535 (2^16 - 1)个字节 |
MEDIUMBLOB | 中⼆进制字节类型,最大长度为 16,777,215 (2^24 - 1)个字节 |
LONGBLOB | 大⼆进制字节类型,最大长度为 4GB (2^8 - 1)个字节 |
ENUM('value1','value2',…) | 枚举;从值列表 'value1','value2' 或 ''(空字符串) 和 NULL 中选⼀个值;最多可以有 65,535 个不同的元素 |
SET('value1','value2',…) | 集合;从值列表 'value1','value2' 中选零个或多个值;最多64个元素 |
CHAR的固定长度,比如指定10个字符,却只是用3个字符,长度依然是10个;VARCHAR的取值范围决定了能存储字符的最大个数65535/4=16383(当使用utf8mb4字符集时)。对于文本类型和二进制类型,我们用记事本的形式打开一个Excel文档,会发现里面都是我们看不懂的一堆乱码,这就是二进制类型。由于太浪费空间,现在MySQL已经不存这些二进制类型的数据了,有更好的方式去保存。
3.2. 关于排序
- 字符串类型的列以字符为单位,并且可以单独指定字符集和排序规则,比如字符集是 utf8mb4 ,排序规则是 utf8_0900_ai_ci
- ⼆进制的列以字节为单位,可以指定_bin结尾的排序规则,比如排序规则是 utf8mb4_bin ,这 时以比较和排序基于数字字符代码值
3.3. CHAR与VARVHAR的选择
- 如果数据确定长度都⼀样,就使用定长CHAR类型,比如身份证,学号,邮编等。比较浪费磁盘空间,但是效率⾼。
- 如果数据长度有变化,就使⽤变长VARCHAR,比如:名字,地址,但要规划好长度,保证最长的字符串能存的进去。比较节省磁盘空间,但是效率低。
四、日期类型
4.1. 类型列表
类型 | 大小 | 说明 | 0值 |
TIMESTAMP[(fsp)] | 4byte |
|
0000-00- 00 00:00:00 |
DATETIME[(fsp)] | 8byte |
|
0000-00-00 00:00:00 |
DATE | 3byte |
|
0000-00-00 |
TIME[(fsp)] | 3byte |
|
00:00:00 |
TEAR[(4)] | 1byte |
|
0 |
TIMESTAMP类型的日期如果超出范围就会溢出,返回到1970-01-01 00:00:01.000000,一般我们也不要用;最常用的就是DATETIME、DATE、TIME这三种类型;fsp为可选设置,⽤来指定⼩数秒精度,范围从0到6,值为0表示没有小数部分,如果省略,默认精度为0。
4.2. 其他
- CURRENT_DATE 和 CURRENT_DATE() 是 CURDATE() 的同义词用于获取当前日期
- CURRENT_TIME 和 CURRENT_TIME([fsp]) 是 CURTIME() 的同义词用于获取当前时间
- CURRENT_TIMESTAMP 和 CURRENT_TIMESTAMP([fsp]) 是 NOW() 的同义词用于获取当前日期和时间
mysql> select now();
+---------------------+
| now() |
+---------------------+
| 2025-03-25 10:52:32 |
+---------------------+
1 row in set (0.00 sec)
mysql> select curdate();
+------------+
| curdate() |
+------------+
| 2025-03-25 |
+------------+
1 row in set (0.00 sec)
mysql> select current_time();
+----------------+
| current_time() |
+----------------+
| 10:53:59 |
+----------------+
1 row in set (0.00 sec)