02 | 字段:这么多字段类型,该怎么定义?

你好,我是朱晓峰。

MySQL中有很多字段类型,比如整数、文本、浮点数,等等。如果类型定义合理,就能节省存储空间,提升数据查询和处理的速度,相反,如果数据类型定义不合理,就有可能会导致数据超出取值范围,引发系统报错,甚至可能会出现计算错误的情况,进而影响到整个系统。

之前,我们就遇到过这样一个问题:在销售流水表中,需要定义商品销售的数量。由于有称重商品,不能用整数,我们想当然地用了浮点数,为了确保精度,我们还用了DOUBLE类型。结果却造成了在没有找零的情况下,客人无法结账的重大错误。经过排查,我们才发现,原来DOUBLE类型是不精准的,不能使用。

你看,准确地定义字段类型,不但关系到数据存储的效率,而且会影响整个信息系统的可靠性。所以,我们必须要掌握不同字段的类型,包括它们的适用场景、定义方法,这节课,我们就聊一聊这个问题。

首先,我要说的是MySQL中最简单的数据类型:整数类型。

整数类型

整数类型一共有5种,包括TINYINT、SMALLINT、MEDIUMINT、INT(INTEGER)和BIGINT,它们的区别如下表所示:

这么多整数类型,咱们该怎么选择呢?

其实,在评估用哪种整数类型的时候,你需要考虑存储空间和可靠性的平衡问题:一方面,用占用字节数少的整数类型可以节省存储空间;另一方面,要是为了节省存储空间,使用的整数类型取值范围太小,一旦遇到超出取值范围的情况,就可能引起系统错误,影响可靠性。

举个例子,在我们的项目中,商品编号采用的数据类型是INT。

我们之所以没有采用占用字节更少的SMALLINT类型整数,原因就在于,客户门店中流通的商品种类较多,而且,每天都有旧商品下架,新商品上架,这样不断迭代,日积月累。如果使用SMALLINT类型,虽然占用字节数比INT类型的整数少,但是却不能保证数据不会超出范围65535。相反,使用INT,就能确保有足够大的取值范围,不用担心数据超出范围影响可靠性的问题。

你要注意的是,在实际工作中,系统故障产生的成本远远超过增加几个字段存储空间所产生的成本。因此,我建议你首先确保数据不会超过取值范围,在这个前提之下,再去考虑如何节省存储空间。

接下来,我再给你介绍下浮点数类型和定点数类型。

浮点数类型和定点数类型

浮点数和定点数类型的特点是可以处理小数,你可以把整数看成小数的一个特例。因此,浮点数和定点数的使用场景,就比整数大多了。

我们先来了解下MySQL支持的浮点数类型,分别是FLOAT、DOUBLE、REAL。

  • FLOAT表示单精度浮点数;
  • DOUBLE表示双精度浮点数;
  • REAL默认就是DOUBLE。如果你把SQL模式设定为启用“REAL_AS_FLOAT”,那么,MySQL就认为REAL是FLOAT。如果要启用“REAL_AS_FLOAT”,就可以通过以下SQL语句实现:
SET sql_mode = “REAL_AS_FLOAT”;

FLOAT和DOUBLE这两种数据类型的区别是啥呢?其实就是,FLOAT占用字节数少,取值范围小;DOUBLE占用字节数多,取值范围也大。

看到这儿,你有没有发现一个问题:为什么浮点数类型的无符号数取值范围,只相当于有符号数取值范围的一半,也就是只相当于有符号数取值范围大于等于零的部分呢?

其实,这里的原因是,MySQL是按照这个格式存储浮点数的:符号(S)、尾数(M)和阶码(E)。因此,无论有没有符号,MySQL的浮点数都会存储表示符号的部分。因此,所谓的无符号数取值范围,其实就是有符号数取值范围大于等于零的部分。

不过,我要提醒你的是,浮点数类型有个缺陷,就是不精准。因此,在一些对精确度要求较高的项目中,千万不要使用浮点数,不然会导致结果错误,甚至是造成不可挽回的损失。下面我来重点解释一下为什么MySQL的浮点数不够精准。

为了方便你理解,我来借助一个实际的例子演示下。

我们先创建一个表,如下所示:

CREATE TABLE demo.goodsmaster
(
  barcode TEXT,
  goodsname TEXT,
  price DOUBLE,
  itemnumber INT PRIMARY KEY AUTO_INCREMENT
);

运行这个语句,我们就创建了一个表,其中的字段“price”就是浮点数类型。我们再通过下面的SQL语句,给这个表插入几条数据:

-- 第一条
INSERT INTO demo.goodsmaster
(
  barcode,
  goodsname,
  price
)
VALUES 
(
  '0001',
  '书',
  0.47
);
-- 第二条
INSERT INTO demo.goodsmaster
(
  barcode,
  goodsname,
  price
)
VALUES 
(
  '0002',
  '笔',
  0.44
);
-- 第三条
INSERT INTO demo.goodsmaster
(
  barcode,
  goodsname,
  price
)
VALUES 
(
  '0002',
  '胶水',
  0.19
);

现在,我们运行一个查询语句,看看现在表里数据的情况:

SELECT * from demo.goodsmaster;

这个时候,我们可以得到下面的结果:

mysql> SELECT *
    -> FROM demo.goodsmaster;
+---------+-----------+-------+------------+
| barcode | goodsname | price | itemnumber |
+---------+-----------+-------+------------+
| 0001    | 书        |  0.47 |          1 |
| 0002    | 笔        |  0.44 |          2 |
| 0002    | 胶水      |  0.19 |          3 |
+---------+-----------+-------+------------+
3 rows in set (0.00 sec)

然后我们用下面的SQL语句,把这3个价格加在一起,看看得到了什么:

SELECT SUM(price)
FROM demo.goodsmaster;

这里我们又用到一个关键字SUM,这是MySQL中的求和函数,是MySQL聚合函数的一种,你只要知道这个函数表示计算字段值的和就可以了。

我们期待的运行结果是:0.47 + 0.44 + 0.19 = 1.1,可是,我们得到的是:

mysql> SELECT SUM(price)
    -> FROM demo.goodsmaster;
+--------------------+
| SUM(price)         |
+--------------------+
| 1.0999999999999999 |
+--------------------+

查询结果是1.0999999999999999。看到了吗?虽然误差很小,但确实有误差。

你也可以尝试把数据类型改成FLOAT,然后运行求和查询,得到的是,1.0999999940395355。显然,误差更大了。

虽然1.10和1.0999999999999999好像差不多,但是我们有时候需要以通过数值对比为条件进行查询,一旦出现误差,就查不出需要的结果了:

SELECT *
FROM demo.goodsmaster
WHERE SUM(price)=1.1

那么,为什么会存在这样的误差呢?问题还是出在MySQL对浮点类型数据的存储方式上

MySQL用4个字节存储FLOAT类型数据,用8个字节来存储DOUBLE类型数据。无论哪个,都是采用二进制的方式来进行存储的。比如9.625,用二进制来表达,就是1001.101,或者表达成1.001101×2^3。看到了吗?如果尾数不是0或5(比如9.624),你就无法用一个二进制数来精确表达。怎么办呢?就只好在取值允许的范围内进行近似(四舍五入)。

现在你一定明白了,为什么数据类型是DOUBLE的时候,我们得到的结果误差更小一些,而数据类型是FLOAT的时候,误差会更大一下。原因就是,DOUBLE有8位字节,精度更高。

说到这里,我想你已经彻底理解了浮点数据类型不精准的原因了。

那么,MySQL有没有精准的数据类型呢?当然有,这就是定点数类型:DECIMAL

就像浮点数类型的存储方式,决定了它不可能精准一样,DECIMAL的存储方式决定了它一定是精准的。

浮点数类型是把十进制数转换成二进制数存储,DECIMAL则不同,它是把十进制数的整数部分和小数部分拆开,分别转换成十六进制数,进行存储。这样,所有的数值,就都可以精准表达了,不会存在因为无法表达而损失精度的问题。

MySQL用DECIMAL(M,D)的方式表示高精度小数。其中,M表示整数部分加小数部分,一共有多少位,M<=65。D表示小数部分位数,D<M。

下面我们就用刚才的表demo.goodsmaster验证一下。

首先,我们运行下面的语句,把字段“price”的数据类型修改为DECIMAL(5,2):

ALTER TABLE demo.goodsmaster
MODIFY COLUMN price DECIMAL(5,2);

然后,我们再一次运行求和语句:

SELECT SUM(price)
FROM demo.goodsmaster;

这次,我们得到了完美的结果:1.10。

由于DECIMAL数据类型的精准性,在我们的项目中,除了极少数(比如商品编号)用到整数类型外,其他的数值都用的是DECIMAL,原因就是这个项目所处的零售行业,要求精准,一分钱也不能差。

当然,在一些对精度要求不高的场景下,比起占用同样的字节长度的定点数,浮点数表达的数值范围可以更大一些。

简单小结下浮点数和定点数的特点:浮点类型取值范围大,但是不精准,适用于需要取值范围大,又可以容忍微小误差的科学计算场景(比如计算化学、分子建模、流体动力学等);定点数类型取值范围相对小,但是精准,没有误差,适合于对精度要求极高的场景(比如涉及金额计算的场景)。

文本类型

在实际的项目中,我们还经常遇到一种数据,就是字符串数据。比如,刚刚那个简单的表demo.goodsmaster中,有两个字段“barcode”和“goodsname”。它们当中存储的条码、商品名称,都是字符串数据。这两个字段的数据类型,我们都选择了TEXT类型。

TEXT类型是MySQL支持的文本类型的一种。此外,MySQL还支持CHAR、VARCHAR、ENUM和SET等文本类型。我们来看看它们的区别。

  • CHAR(M):固定长度字符串。CHAR(M)类型必须预先定义字符串长度。如果太短,数据可能会超出范围;如果太长,又浪费存储空间。
  • VARCHAR(M): 可变长度字符串。VARCHAR(M)也需要预先知道字符串的最大长度,不过只要不超过这个最大长度,具体存储的时候,是按照实际字符串长度存储的。
  • TEXT:字符串。系统自动按照实际长度存储,不需要预先定义长度。
  • ENUM: 枚举类型,取值必须是预先设定的一组字符串值范围之内的一个,必须要知道字符串所有可能的取值。
  • SET:是一个字符串对象,取值必须是在预先设定的字符串值范围之内的0个或多个,也必须知道字符串所有可能的取值。

对于ENUM类型和SET类型来说,你必须知道所有可能的取值,所以只能用在某些特定场合,比如某个参数设定的取值范围只有几个固定值的场景。

因为不需要预先知道字符串的长度,系统会按照实际的数据长度进行存储,所以TEXT类型最为灵活方便,所以下面我们重点学习一下它。

TEXT类型也有4种,它们的区别就是最大长度不同。

  • TINYTEXT:255字符(这里假设字符是ASCII码,一个字符占用一个字节,下同)。
  • TEXT: 65535字符。
  • MEDIUMTEXT:16777215字符。
  • LONGTEXT: 4294967295字符(相当于4GB)。

不过,需要注意的是,TEXT也有一个问题:由于实际存储的长度不确定,MySQL不允许TEXT类型的字段做主键。遇到这种情况,你只能采用CHAR(M),或者VARCHAR(M)。

所以,我建议你,在你的项目中,只要不是主键字段,就可以按照数据可能的最大长度,选择这几种TEXT类型中的的一种,作为存储字符串的数据类型。

日期与时间类型

除了刚刚说的这3种类型,还有一类也是经常用到的,那就是日期与时间类型。

日期与时间是重要的信息,在我们的系统中,几乎所有的数据表都用得到。原因是客户需要知道数据的时间标签,从而进行数据查询、统计和处理。

用得最多的日期时间类型,就是DATETIME。虽然MySQL也支持YEAR(年)、TIME(时间)、DATE(日期),以及TIMESTAMP类型,但是我建议你,在实际项目中,尽量用DATETIME类型。因为这个数据类型包括了完整的日期和时间信息,使用起来比较方便。毕竟,如果日期时间信息分散在好几个字段,就会很不容易记,而且查询的时候,SQL语句也会更加复杂。

这里我也给你列出了MySQL支持的其他日期时间类型的一些参数:

可以看到,不同数据类型表示的时间内容不同、取值范围不同,而且占用的字节数也不一样,你要根据实际需要灵活选取。

不过,我也给你一条小建议:为了确保数据的完整性和系统的稳定性,优先考虑使用DATETIME类型。因为虽然DATETIME类型占用的存储空间最多,但是它表达的时间最为完整,取值范围也最大。

另外,这里还有个问题,为什么时间类型TIME的取值范围不是-23:59:59~23:59:59呢?原因是MySQL设计的TIME类型,不光表示一天之内的时间,而且可以用来表示一个时间间隔,这个时间间隔可以超过24小时。

时间类型的应用场景还是比较广的,后面我会单独用一节课来讲在数据库中处理时间的问题。这节课,你一定要知道MySQL支持哪几种时间类型,它们的区别是什么,这样在学后面的内容时,才能游刃有余。

总结

今天,我给你介绍了几个常用的字段数据类型,包括整数类型、浮点数类型、定点数类型、文本类型和日期时间类型。同时,我们还清楚了为什么整数类型用得少,浮点数为什么不精准,以及常用的日期时间类型。

另外,我们还学习了几个新的SQL语句。尤其是第2条,我们在项目中会经常用到,你一定要重点牢记。

-- 修改字段类型语句
ALTER TABLE demo.goodsmaster
MODIFY COLUMN price DOUBLE;
-- 计算字段合计函数:
SELECT SUM(price)
FROM demo.goodsmaster;

最后,我还想再给你分享1个小技巧。在定义数据类型时,如果确定是整数,就用INT;如果是小数,一定用定点数类型DECIMAL;如果是字符串,只要不是主键,就用TEXT;如果是日期与时间,就用DATETIME。

  • 整数:INT。
  • 小数:DECIMAL。
  • 字符串:TEXT。
  • 日期与时间:DATETIME。

这样做的好处是,首先确保你的系统不会因为数据类型定义出错。

不过,凡事都是有两面的,可靠性好,并不意味着高效。比如,TEXT虽然使用方便,但是效率不如CHAR(M)和VARCHAR(M)。如果你有进一步优化的需求,我再给你分享一份文档,你可以对照着看下。

思考题

假设用户需要一个表来记录会员信息,会员信息包括会员卡编号、会员名称、会员电话、积分值。如果要你为这些字段定义数据类型,你会如何选择呢?为什么?

欢迎在留言区写下你的思考和答案,我们一起交流讨论。如果你觉得今天的内容对你有所帮助,也欢迎你分享你的朋友或同事,我们下节课见。

精选留言

  • 朱晓峰

    2021-03-11 10:40:01

    你好,我是朱晓峰,下面我就来公布一下上节课思考题的答案:

    上节课,我们学习了数据存储的完整过程,包括创建数据库、数据表、确认字段和插入数据。下面是思考题的答案:
     
    设计销售表如下:
     
    CREATE TABLE demo.sales
    (
             goodsname text,
             salesprice decimal(10,2),
             quantity decimal(10,3),
             salesvalue decimal(10,2)
    );
    作者回复

    供大家参考

    2021-03-12 10:17:39

  • cheriston

    2021-04-21 09:18:35

    老师 按照你的代码插入数据 报错啊:
    [Err] 1366 - Incorrect string value: '\xE4\xB9\xA6' for column 'goodsname' at row 1
    好像是字符集问题,为什么,怎么改。
    作者回复

    可能是表的字符集不对,我用的是默认的:CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci,你可以试一下

    2021-04-21 10:02:30

  • 右耳朵猫咪

    2021-03-11 08:33:44

    老师好,有一些公司用分而不是用元来表示金额,存储类型是int。这种方式和decimal哪个比较好呢?
    作者回复

    还是一个精度问题。如果用分来表示金额,存储类型是INT,那么,如果场景中只有加减运算,就不会有问题。但是如果涉及到乘除运算,运算过程中出现分以下的金额,就会出现精度损失的问题。所以,还是要根据实际的业务场景,来决定。

    2021-03-11 09:39:49

  • 陈启年

    2021-03-12 13:24:20

    朱老师,Text类型这段文字:
    “TEXT 类型也有 4 种,它们的区别就是最大长度不同。TINYTEXT:占用 255 字符。TEXT: 占用 65535 字符...”
    此处的“字符”改为“字节”,是否更加严谨
    作者回复

    这里用字符,侧重点在数据类型的使用上,表示这个数据类型的最多可以放多少个字符。这里假设是ASCII码,因此一个字符就是一个字节。字节侧重存储,意思是这个数据类型的数据最大需要占用多少存储空间。比如,tinytext类型最多可以存放255个字符,但是最多占用的存储空间是256个字节,因为有一个字节用来存储字符串长度。

    2021-03-12 17:57:26

  • lesserror

    2021-03-11 19:11:17

    今天的MySQL查漏补缺来了。虽然MySQL的数据类型就那么几种,但是在实际的项目中还是有很多人在定义表字段的时候选择了不合适的数据类型,导致后期维护成本增加。

    例如文中说的,在对精度有要求的字段中没有使用DECIMAL数据类型,反而选用了FLOAT、DOUBLE数据类型。我经手过的很多老项目也喜欢用INT类型来存时间戳,这种时间存取方式很麻烦而且也不直观。我个人也是持和老师相同的观点,采用DATETIME类型来存时间字段。因为虽然 DATETIME 类型占用的存储空间最多,但是它表达的时间最为完整,取值范围也最大。

    另外,关于小数点精度丢失的那部分内容,老师解释的很准确。
    作者回复

    技术服务于业务,根据业务需要决定类型定义

    2021-03-12 10:16:22

  • 海明

    2021-03-11 13:26:28

    朱老师,我看上面有个例子是这样写的,但是sum可以这样使用吗。sum函数在where这里。
    SELECT *
    FROM demo.goodsmaster
    WHERE SUM(price)=1.1
    作者回复

    这样写是不行的,SUM是聚合函数,一般要跟GROUP BY 关键字一起使用,比如,你有一个商品信息表demo.goodsmaster,其中有3个字段,分别是barcode,goodsname,price,现在商品名称可能重复,想查一下价格合计是1.1的商品,可以这样写:
    SELECT goodsname,SUM(price)
    FROM demo.goodsmaster
    GROUP BY goodsname
    HAVIING SUM(price)=1.1;

    2021-03-12 09:45:15

  • SharpBB

    2022-02-08 10:04:05

    1.整数类型
    TINYINT多用于布尔类型 枚举类型
    占1个字节
    一般来讲INT用的最多
    占4个字节
    除非该数字有可能超过21亿 一般不用BIGINT
    不要为了节省一点存储空间 而忽视数据溢出带来的风险 可靠性第一!
    2.浮点数类型和定点数类型
    浮点数
    float 单精度浮点数
    double 双精度浮点数 mysql默认使用
    缺陷:浮点数不精准
    二进制无法精确表达 所以只能四舍五入
    定点数
    decimal可以精确表达
    把十进制的整数与小数拆分 用十六进制存储
    decimal(5,2)
    前面的5是长度 后面的2是保留几位小数
    涉及小数 可以无脑用decimal
    ps:涉及金额的 也可以以分为单位 用整型来存储
    3.文本类型
    一般都可无脑用text 65535字符 如果过长 则使用longtext
    text类型无需提前定义长度 且按实际长度存储
    varchar(M)需要定义长度 但也是按实际长度存储的
    注意 这里的M指的是字符 所以不管是英文还是中文 都可容纳M个
    但text类型不能作为主键
    这时候可以选择varchar或char
    4.日期与时间类型
    尽量使用datetime类型 用的最多 最完整
    5.总结
    整数用int 小数用decimal 字符串用text/varchar 时间用datetime

    导图复制的 可能排版不太好
    作者回复

    是的

    2022-03-12 16:51:14

  • 青鸟飞鱼

    2021-03-11 08:38:06

    老师,blob的运用场景是什么呢?
    作者回复

    blob是二进制字符串,比如可以把图片转换成二进制数据存入类型是blob的字段中。好处是可以像一个普通字段那样来处理图片,缺点是占用的存储资源大

    2021-03-11 09:32:12

  • NARUTO

    2021-09-01 15:56:55

    对于跨国的大型系统,时间字段可能会有时区的影响,不同的区域的用户使用时,都希望看到本地的时间,统计报表数据也是类似,这种场景下的时间业务字段,老师建议是用什么类型比较好?理由是什么呢?
    作者回复

    建议使用DATETIME类型,理由是MySQL不会因为不同时区而返回不同的时间值,容易控制。

    2021-09-28 11:04:17

  • 2021-03-11 14:07:31

    为什么浮点数无符号取值范围的右边界也是个范围呢,
    作者回复

    这是因为,浮点数的取值范围可以有2种方式来确定,一种方式是小数点放在在最前面,这样得出最小的无符号数,另外一种是把小数点放在最后,这样得出最大的无符号数

    2021-03-12 10:53:06

  • PHP菜鸟

    2021-12-24 11:34:47

    我们小公司,每天的总额百分百不会超过一百万,那用int就行了,单位是分,那我用int和decimal哪个效率高点呢?
    作者回复

    int效率更高

    2022-01-16 13:01:22

  • 2021-07-29 11:30:15

    老师,据说MySQL查询的速度 char>varchar>text ,所以一般能用varchar解决的优先用varchar,这里为什么推荐用text呢?
    作者回复

    text不需要预先定义字段长度,不容易溢出,在入门阶段,用text类型可以提高代码的可靠性

    2021-08-02 11:23:39

  • 陈忠

    2021-12-17 10:29:56

    浮点数二进制表示麻烦老师讲一下,谢谢
    作者回复

    这个问题在课程中已经有详细表述,“比如 9.625,用二进制来表达,就是 1001.101,或者表达成 1.001101×2^3”,具体为什么可以这样表述,建议参考计算机基础书籍中关于二进制数的相关章节。

    2022-01-16 12:55:25

  • Registerwei

    2021-11-22 10:14:13

    老师,为什么int类型的时候,mediumint比int的范围小;到了text的时候,mediumtext就比text范围大了呢?
    作者回复

    文本类型数据与整数类型数据存储方式不同

    2022-01-16 11:52:56

  • 牧童倒拔垂杨柳

    2021-08-26 15:56:48

    CREATE TABLE vip_info(
    id INT PRIMARY KEY AUTO_INCREMENT, -- 主键
    vip_number TEXT, -- 会员编号,虽然会员编号有固定长度,但可能随会员数量增加长度有变化
    vim_name TEXT, -- 会员名称,鬼知道会有什么样子的名称出现
    vip_phone char(11), -- 国内手机号和座机号一般都是11位,如果碰上外国会员。。。。,自求多福
    integral DECIMAL(9,2) -- 积分可能是整数,可能是小数,所以用DECIMAL
    );
    作者回复

    请参考思考题答案

    2021-09-06 15:37:41

  • Flychen

    2021-07-21 10:44:13

    时间戳以后也尽量用大datetime 代替 timestamp 吗
    作者回复

    要根据具体场景的需要。datetime的好处是表示的时间范围大,没有时区问题,但是占用较多的存储空间,如果节省空间优先,timestamp的取值范围也够,又没有时区问题,也可以用timestamp

    2021-08-02 11:21:19

  • 希望

    2021-06-29 01:27:35

    为什么时间不用timestamp类型呢
    作者回复

    2个原因,第一,datetime可以表达的时间范围比较大;第二,datetime与时区无关。为了代码的可靠性和可移植性,适当牺牲一些存储空间,我认为还是值得的。当然,要看具体的使用场景,如果确定timestamp的取值范围够用,也不会有时区的问题,用timestamp也是可以的。

    2021-08-02 10:07:43

  • 大聖

    2021-06-08 09:39:41

    比较了一下CHAR,VARCHAR和Text,如果不做主键,那么选择Text最为灵活。如果作为主键的情况:
    1. 如果长度超过范围且如果长度固定,应该选择CHAR,原因是相比于VARCHAR,CHAR更省空间,VARCHAR会在数据上附加1到2个byte
    2.如果长度不固定,应该选择VARCHAR

    另外,对于CHAR和VARCHAR的长度,好像没有提到中文字符,不过我自己测试,不论中文还是英文,都占用一个长度
    作者回复

    请参考思考题答案

    2021-06-08 10:37:41

  • zhunode

    2021-05-22 09:33:24

    老师好。您在总结开头写到:“我们还知道了为什么整数类型用得少”这段,我再看了一遍整数类型部分,并没有说明整数类型为什么用的少,而是说要选择合适的整数类型(。
    作者回复

    在介绍浮点数和定点数类型的时候,提到整数类型可以看作小数的一个特例,也提到浮点数和定点数的使用场景比整数大多了,其实就是说整数类型使用的场景比较少。

    2021-06-07 16:00:55

  • 进步永无止境

    2021-04-01 21:36:11

    DATETIME 存储大小是分版本的5.7以后是5个字节
    作者回复

    在MySQL8 中,DATETIME占用8个字节存储空间

    2021-05-20 15:07:47