MENU

MySQL 数据类型

January 12, 2021 • Read: 1173 • 编码,MySQL

每一个变量,常量和参数都有数据类型,它主要是用来指定一定的存储格式、约束和有效范围。

MySQL提供了多种数据类型,主要包括数值型、字符串类型、日期和时间类型。不同的MySQL版本支持的数据类型可能会有不同,书中是以5.7为例,介绍MySQL中的各个数据类型。

数值类型

MySQL支持所有标准SQL的数值类型,其中包括严格数值类型(INTEGER、SMALLINT、DECIMAL、NUMERIC),近似数据类型(FLOAT、REAL、DUBLE PRECISION),并在此基础上做了扩展。增加了TINYINT、MEDIUMINT、BIGINT三种长度不同的数据类型,并增加了BIT类型,存放位数据。

整型类型字节最小值最大值
TINYINT1有符号:-128
无符号:0
有符号:127
无符号:255
SMALLINT2有符号:-32768
无符号:0
有符号:32767
无符号:65535
MEDIUMINT3有符号:-8388608
无符号:0
有符号:8838507
无符号:1677215
INT、INTEREG4有符号:-2147483648
无符号:0
有符号:2147483647
无符号:4294967295
BIGINT8有符号:-9223372036854775808
无符号:0
有符号:9223372036854775807
无符号:18446744073709551615
浮点类型字节最小值最大值
FLOAT4±1.175494351E-38±3.402823466E+38
DOUBLE8±2.2250738585072014E-308±1.7976931348623157E+308
定点数类型字节描述
DEC(M,D)
DECIMAL(M,D)
M+2最大取值范围与DOUBLE相同,给定DECIMAL的有效值范围由M,D决定
位类型字节最小值最大值
BIT(M)1 ~ 8BIT(1)BIT(2)

在整数类型中,按照取值范围和存储方式的不同,分为tinyint、smallint、mediumint、int和bigint这五个类型。如果存入的值超过取值范围会发生 "Out of renge"错误提示,为了避免这种情况发生,,选择数据类型时要根据实际应用场景确定取值范围。最后根据结果慎重选择数据类型。

对于整数类型,MySQL还支持类型名称后面的小括号内指定显示宽度,例如:int(5) ,表示当数值宽度小于5位数时,在数字前面填满宽度,如果不指定宽度,默认为 int(11),一般配合zerofill使用,就是“0”填充,在数值位数不够的空间使用 "0"填满。使用下面的例子描述填充前后的区别:

创建t1表 ,设置id1和id2两个字段,id2指定显示长度为5;

mysql> create table t1(id1 int ,id2 int(5));
Query OK, 0 rows affected (0.01 sec)

mysql> desc t1;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id1   | int(11) | YES  |     | NULL    |       |
| id2   | int(5)  | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)

给id1和id2 插入数值1,没有任何异常:

mysql> insert into t1 values(1,1);
Query OK, 1 row affected (0.01 sec)

mysql> select * from t1;
+------+------+
| id1  | id2  |
+------+------+
|    1 |    1 |
+------+------+
1 row in set (0.00 sec)

修改id1和id2的数据类型,加上zerofill参数:

mysql> alter table t1 modify id1 int zerofill;
Query OK, 1 row affected (0.04 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> alter table t1 modify id2 int(5) zerofill;
Query OK, 1 row affected (0.04 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> select * from t1;
+------------+-------+
| id1        | id2   |
+------------+-------+
| 0000000001 | 00001 |
+------------+-------+
1 row in set (0.00 sec)

这个时候,数值前面使用了0来填充剩余宽度,设置宽度限制后,不影响取值范围,不会对插入值进行截断或者报错。

mysql> insert into t1 values(1,123456789);
Query OK, 1 row affected (0.00 sec)

mysql> select * from t1;
+------------+-----------+
| id1        | id2       |
+------------+-----------+
| 0000000001 |     00001 |
| 0000000001 | 123456789 |
+------------+-----------+
2 rows in set (0.00 sec)

所有的整数类型都有一个可选的属性UNSIGNED(无符号),如果字段里保存的是非负数或需要比较大的上限值时,可以使用此选项,它的取值范围是正常值的下限取0,上限值是原值的两倍。如果一个字段被设定为zerofill,则MySQL自动给该字段添加UNSIGNED属性。

另外,整数类型还有一个属性:AUTO_INCREMENT。在需要产生唯一标识符或顺序值时可利用此属性,这个属性只用于整数类型。AUTO_INCREMENT的值一般从1开始,每行增加1,在插入NULL到一个AUTO_INCREMENT的列时,MySQL插入一个比该列最大数值大1的值。一个表中最多只能有一个AUTO_INCREMENT。对于任何想使用AUTO_INCREMENT的列来说应定义其为 NOT NULL 并定义为PRIMARY KEY或定义为UNIQUE键。

可以使用下面三种方式定义:

CREATE TABLE AI(ID INT AUTO_INCREMENT NOT NULL PRIMARY KEY);
CREATE TABLE AI(ID INT AUTO_INCREMENT NOT NULL ,PRIMARY KEY(id));
CREATE TABLE AI(ID INT AUTO_INCREMENT NOT NULL ,UNIQUE(id));

关于小数

对于小数的表示,MySQL分为浮点数和定点数。浮点数包括 float (单精度)和double(双精度),而定点数只有decimal一种表示。定点数在MySQL内部以字符串的格式存储,比浮点数更精准,适合用来存储货币等精度较高的数据。

浮点数和定点数都可以使用(M,D)的方式来表示,M表示一共存储多少位数字,D表示小数点后面的位数,M和D又被称之为精度和标度。例如定义为 float(7,4) 的一个列可显示为 -999.9999。MySQ在保存值时进行四舍五入,因此在float(7,4)中插入999.00009,近似结果是999.0001。需要注意的是,浮点数后面 的M和D的用法是非标准用法,如果要用于数据库迁移,最好不要这么使用。float和double在不指定精度时,默认会按照实际的精度来显示,而decimal在不指定精度时,默认的整数位为10,默认小数位为0。

通过下面的例子来比较floatdoubledecimal 三者之间的不同:

创建测试表,并将id1,id2,id3设置为

mysql> create table `t1`(
    -> `id1` float(5,2) default NULL,
    -> `id2` double(5,2) default NULL,
    -> `id3` decimal(5,2) default NULL
    -> );
Query OK, 0 rows affected (0.02 sec)

分别插入数据1.23

mysql> insert into t1 values(1.23,1.23,1.23);
Query OK, 1 row affected (0.01 sec)

mysql> select * from t1;
+------+------+------+
| id1  | id2  | id3  |
+------+------+------+
| 1.23 | 1.23 | 1.23 |
+------+------+------+
1 row in set (0.00 sec)

数据都正常插入了,没有问题。

再向数据表中插入1.234:

mysql> insert into t1 values(1.234,1.234,1.234);
Query OK, 1 row affected, 1 warning (0.01 sec)

mysql> select * from t1;
+------+------+------+
| id1  | id2  | id3  |
+------+------+------+
| 1.23 | 1.23 | 1.23 |
| 1.23 | 1.23 | 1.23 |
| 1.23 | 1.23 | 1.23 |
+------+------+------+
3 rows in set (0.00 sec)

这时候发现id1和id2因为标位限制的原因舍去了最后一位,同时出现了一个warning,id3被截断。如果是传统的SQLMode下,这条记录是无法插入的。

然后将字段的精度和标度全部去掉,再次插入数据:

mysql> alter table t1 modify id1 float;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> alter table t1 modify id2 double;
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> alter table t1 modify id3 decimal;
Query OK, 3 rows affected, 3 warnings (0.04 sec)
Records: 3  Duplicates: 0  Warnings: 3

mysql> desc t1;
+-------+---------------+------+-----+---------+-------+
| Field | Type          | Null | Key | Default | Extra |
+-------+---------------+------+-----+---------+-------+
| id1   | float         | YES  |     | NULL    |       |
| id2   | double        | YES  |     | NULL    |       |
| id3   | decimal(10,0) | YES  |     | NULL    |       |
+-------+---------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

mysql> insert into t1 values(1.234,1.234,1.234);
Query OK, 1 row affected, 1 warning (0.01 sec)

mysql> show warnings;
+-------+------+------------------------------------------+
| Level | Code | Message                                  |
+-------+------+------------------------------------------+
| Note  | 1265 | Data truncated for column 'id3' at row 1 |
+-------+------+------------------------------------------+
1 row in set (0.00 sec)

mysql> select * from t1;
+-------+-------+------+
| id1   | id2   | id3  |
+-------+-------+------+
|  1.23 |  1.23 |    1 |
|  1.23 |  1.23 |    1 |
|  1.23 |  1.23 |    1 |
| 1.234 | 1.234 |    1 |
+-------+-------+------+
4 rows in set (0.00 sec)

这时,可以发现id1、id2字段可以正常插入数据,而id3的小数位被截断。

  • 浮点数:如果不写精度和标度,则按照实际精度值显示,如果设置了精度和标度,则会自动将四舍五入后的结果插入,系统不会报错.
  • 定点数:如果不写精度和标度,则按照默认值deciaml(10,0) 来进行操作,并且如果数据超越了精度和标度值,系统则会报错。

位字段

BIT(位)类型,用于存放位字段值,BIT(M)可以用来存放多位二进制数,M范围为1~64,如果不写,默认为1位。对于位字段,直接使用 select 查询将不会看到结果,可以使用bin()(显示为二进制格式)或者hex()(显示为十六进制格式)函数进行读取。

例子,对测试表t2进行bin类型字段的insert和select操作,这里主要观差select结果:

mysql> desc t2;
+-------+--------+------+-----+---------+-------+
| Field | Type   | Null | Key | Default | Extra |
+-------+--------+------+-----+---------+-------+
| id    | bit(1) | YES  |     | NULL    |       |
+-------+--------+------+-----+---------+-------+
1 row in set (0.00 sec)

mysql> insert into t2 values(1);
Query OK, 1 row affected (0.01 sec)

mysql> select * from t2;
+------+
| id   |
+------+
|     |
+------+
1 row in set (0.00 sec)

可以发现,直接使用 select * 的结果无法正常显示,下面改用bin()函数和hex()函数试试:

mysql> select bin(id),hex(id) from t2;
+---------+---------+
| bin(id) | hex(id) |
+---------+---------+
| 1       | 1       |
+---------+---------+
1 row in set (0.00 sec)

数据在插入bit类型的位字段,首先转换为二进制,如果位数允许,则插入成功,如果位数小于实际定义位数则插入失败。

下面的例子中:t2 插入数字2,因为数字2 转换为二进制码是"10",而id的定义是bit(1),所以插入失败:

mysql> insert into t2 values(2);
Query OK, 1 row affected, 1 warning (0.01 sec)

mysql> show warnings;
+---------+------+---------------------------------------------+
| Level   | Code | Message                                     |
+---------+------+---------------------------------------------+
| Warning | 1264 | Out of range value for column 'id' at row 1 |
+---------+------+---------------------------------------------+
1 row in set (0.00 sec)

修改字段类型后再次插入:

mysql> alter table t2 modify id bit(2);
Query OK, 1 rows affected (0.01 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> insert into t2 values(2);
Query OK, 1 row affected (0.01 sec)

mysql> select bin(id),hex(id) from t2;
+---------+---------+
| bin(id) | hex(id) |
+---------+---------+
| 1       | 1       |
| 1       | 1       |
| 10      | 2       |
+---------+---------+
3 rows in set (0.00 sec)

时间日期类型

MySQL中有多种数据类型可用于日期和时间的表示,不同MySQL版本中可能会有所差异,下面表中列出MySQL5.7中所支持的日期和时间类型。

时间和日期类型字节最小值最大值
DATE41000-01-019999-12-31
DATETIME81000-01-01 00:00:009999-12-31 23:59:59
TIMESTAMP4197001010800012038年某个时刻
TIME3-838:59:59838:59:59
TEAR119012155

各个字段区别如下:

  • 如果要表示年月日,通常使用DATE类型来表示
  • 如果要表示年月日时分秒,通常使用DATETIME或TIMESTAMP表示。
  • 如果只用来表示时分秒,通常使用TIME字段进行表示
  • 如果只是用来表示年份,可以使用YEAR,她比DATE占用空间更小。YEAR由2位和4位格式的年,默认是四位格式。在四位格式中允许的值是1901~2155 和0000。在两位格式中,允许的值是70~69,也就是1970年~2069年。(从MySQL5.5.27开始,已不支持2位数的year)。

每种日期类型都有一个有效值范围,超过这个有效值范围,在默认的SQL Mode下系统会进行错误提示,并将以零值来存储。

数据类型零值
DATE0000-00-00 00:00:00
DATETIME0000-00-00
TIMESTAMP0000-00-00 00:00:00
TIME00:00:00
YEAR0000

DATE、TIME和DATETIME是经常使用的3种日期类型,使用下面的例子插入相同的是时间值,看看显示结果。

创建表 t 字段分别为 date、time datetime 三种类型:

mysql> create table t(d date,t time,dt datetime);
Query OK, 0 rows affected (0.03 sec)

mysql> desc t;
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| d     | date     | YES  |     | NULL    |       |
| t     | time     | YES  |     | NULL    |       |
| dt    | datetime | YES  |     | NULL    |       |
+-------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)

使用now函数插入当前日期,并查看显示结果:

mysql> insert into t values(now(),now(),now());
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> show warnings;
+-------+------+----------------------------------------+
| Level | Code | Message                                |
+-------+------+----------------------------------------+
| Note  | 1265 | Data truncated for column 'd' at row 1 |
+-------+------+----------------------------------------+
1 row in set (0.00 sec)

mysql> select * from t;
+------------+----------+---------------------+
| d          | t        | dt                  |
+------------+----------+---------------------+
| 2020-09-01 | 13:38:03 | 2020-09-01 13:38:03 |
+------------+----------+---------------------+
1 row in set (0.00 sec)

显而易见,DATETIME是DATE和TIME的组合。用户可以根据不同的需要,选择不同的时间或日期满足不同的应用。

TIMESTAMP类型特性:

首先看一下explicit_defaults_for_timestamp的状态,如果是ON 则需要修改为开启:

mysql> show variables like '%explicit%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| explicit_defaults_for_timestamp | OFF   |
+---------------------------------+-------+
1 row in set, 1 warning (0.00 sec)

创建t表,包含 id1 和id2,字段均为TIMESTAMP类型:

mysql> create table t (id1 timestamp,id2 timestamp);
Query OK, 0 rows affected (0.03 sec)

mysql> desc t;
+-------+-----------+------+-----+---------------------+-----------------------------+
| Field | Type      | Null | Key | Default             | Extra                       |
+-------+-----------+------+-----+---------------------+-----------------------------+
| id1   | timestamp | NO   |     | CURRENT_TIMESTAMP   | on update CURRENT_TIMESTAMP |
| id2   | timestamp | NO   |     | 0000-00-00 00:00:00 |                             |
+-------+-----------+------+-----+---------------------+-----------------------------+
2 rows in set (0.01 sec)

系统给第一个TIMESTAMP类型设置了默认值CURRENT_TIMESTAMP(系统日期),并且设置了NOT NULLon update CURRENT_TIMESTAMP属性,如果有第二个TIMESTAMP类型则默认值设为零值,写入NULL测试:

mysql> insert into t (id1) values(null);
Query OK, 1 row affected (0.00 sec)

mysql> select * from t;
+---------------------+---------------------+
| id1                 | id2                 |
+---------------------+---------------------+
| 2020-10-04 01:32:51 | 0000-00-00 00:00:00 |
+---------------------+---------------------+
1 rows in set (0.00 sec)

在MySQL5.6之前,可以修改id2的默认值为其他日期常量,但不能设置为CURRENT_TIMESTAMP ,MySQL规定,只能有一列TIMESTAMP的值为CURRENT_TIMESTAMP,然而在MySQL5.6之后,就去掉了这个限制,可以随意修改。

如果explicit_defaults_for_timestamp的状态为ON,则默认值、not null、on update CURRENT_TIMESTAMP 都不会设置,需要手动设置:

mysql> set global explicit_defaults_for_timestamp = ON;
Query OK, 0 rows affected (0.00 sec)

mysql> create table t (id1 timestamp);
Query OK, 0 rows affected (0.03 sec)

mysql> desc t;
+-------+-----------+------+-----+---------+-------+
| Field | Type      | Null | Key | Default | Extra |
+-------+-----------+------+-----+---------+-------+
| id1   | timestamp | YES  |     | NULL    |       |
+-------+-----------+------+-----+---------+-------+

TIMESTAMP还有一个重要特点,和时区相关。写入数据时会先转换为本地时间存放;读取数据时,也会转成本地时间显示。这样就会造成不同时区的用户看到的时间是不一样的。

从上面可以看出,TIMESTAMP和DATATIME的表示方法非常相似,它们主要以一下区别:

  • TIMESTAMP支持的时间范围更小,是19700101080001到2038年的某个时间,而DATETIME是从1000-01-01 00:00:00到9999-12-31 23:59:59 时间范围更大。两者都可以设置默认值和on update CURRENT_TIMESTAMP属性,使得日期列可以根据其他列的更新自动更新为最新时间。
  • TIMESTAMP插入和查询都会受到时区的影响,所以更能反映出实际的日期,而DATETIME只能反映出插入时当地的时区,其他时区的人查看数据必然会有误差。

字符串类型

MySQL中提供了多种对字符数据的存储类型,不同的版本可能会有所差异。以MySQL5.7为例,MySQL包含了CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM、SET等多种字符串类型。

字符串类型字节描述及存储需求
CHAR(M)MM为 0 ~ 255 之间的整数
VARCHAR(M) M为0 ~ 65535之间的整数,值的长度 +1 个字节
TINYBLOB 允许长度 0 ~ 255 字节,值的长度 +1 个字节
BLOB 允许长度 0 ~ 65535 字节,值的长度 +2 个字节
MEDIUMBLOB 允许长度 0 ~ 167772150 字节,值的长度 +3 个字节
LONGBLOG 允许长度 0 ~ 4294967295 字节 值的长度 +4 个字节
TINYTEXT 允许长度 0 ~ 255 字节,值的长度 +2个字节
TEXT 允许长度 0 ~ 65535 个字节,值的长度 +2 个字节
MEDIUMTEXT 允许长度 0 ~ 167772150 字节,值的长度 +3 个字节
LONGTEXT 允许长度 0 ~ 4294967295 字节 值的长度 +4 个字节
VARBINARY 允许长度 0 ~ M 个字节的变长字节字符串,值的长度 +1 字节
BINARY 允许长度 0 ~ M 个字节的定长字节字符串

CHAR和VARCHAR类型

CHAR和VARCHAR很相似,两者都是用来保存MySQL中较短的字符串。两者的主要区别是存储方式的不同:

  • CHAR列的长度固定为创建表时所设定的长度,长度可以是 0 ~ 255 任何值;VARCHAR中的值为可变长度,长度范围可以是 0 ~ 65535 之间的值
  • 在检索的时候,CHAR会删除掉尾部空格,而VARCHAR会保留这些空格

BINARY 和 VARBINARY

BINARY和VARBINYARY类似于CHAR和VARCHAR,不同的是BINARY和VARBINYARY包含二进制字符串,而不包含非二进制的字符串。

ENUM类型

ENUM中文叫枚举类型,它的值范围是需要在创表的时候通过枚举方式显式指定的,对于1 ~ 255 个成员需要使用1个字节存储;对于255 ~ 65535个成员需要2个字节存储。最多允许有65535个成员。

创建测试表,并插入四条记录:

mysql> create table t (gender enum('M','F'));
Query OK, 0 rows affected (0.02 sec)

mysql> INSERT INTO t VALUES('M'),('1'),('f'),(NULL);
Query OK, 4 rows affected (0.01 sec)
Records: 4  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM t;
+--------+
| gender |
+--------+
| M      |
| M      |
| F      |
| NULL   |
+--------+
4 rows in set (0.00 sec)

从上面的例子中可以看出以下几点:

  • ENUM是忽略大小写的,在存储 "M" 和 "f" 时都转换为了大写
  • 当插入的值不在ENUM指定范围的时候,并没有报错,而是插入了ENUM中的第一个值
  • ENUM类型只允许值从和集中取出单个值,而不能一次取多个值

SET类型

SET类型和ENUM类型非常相似,也是一个字符串对象,里面可以包含 0 ~ 64 个成员,成员不同,存储上也不同:

  • 1 ~ 8 个成员组合,占 1 个字节
  • 9 ~ 16 个成员组合,占 2 个字节
  • 17 ~ 24 个成员组合,占 3 个字节
  • 25 ~ 32 个成员组合,占 4 个字节
  • 33 ~ 64 个成员组合,占 8 个字节

SET和ENUM除了存储的不同之外,主要区别是SET类型可以一次选取多个成员,而ENUM只能选一个。

mysql> create table t (col set('a','b','c','d'));
Query OK, 0 rows affected (0.03 sec)

mysql> INSERT INTO t VALUES('a,b'),('a,d,a'),('a,b'),('a,c'),('a');
Query OK, 5 rows affected (0.01 sec)
Records: 5  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM t;
+------+
| col  |
+------+
| a,b  |
| a,d  |
| a,b  |
| a,c  |
| a    |
+------+
5 rows in set (0.00 sec)

SET类型可以从允许的范围值中任意的选取一个或多个元素进行组合,输入的值只要在允许值的组合范围内,都可以写入到SET类型的列中,如果值超出允许值范围将不允许写入,包含重复成员的集合只取一次,例如:(a,d,a) 写入后的结果是:(a,d)

JSON类型

JSON是JavaScript Object Notation的缩写,是一种数据交换格式。自MySQL5.7.8版本起,MySQL开始支持JSON类型,在此之前通常使用VARCHAR或TEXT来保存JSON格式的数据。JSON类型 相比字符串类型有以下优点:

  • JSON类型会自动校验数据是否为JSON格式,如果不是JSON格式的数据,就会报错。
  • MySQL提供了一组操作JSON数据的内置函数,可以方便的操作数据
  • 优化的存储格式,存储在JSON列中的JSON数据被转换成内部的存储格式,允许快速读取。

创建表,并写入数据:

mysql> create table t1 (id1 json);
Query OK, 0 rows affected (0.03 sec)

mysql> INSERT INTO t1 VALUES('{"age":20,"time":"2018-07-14 10:52:00"}');
Query OK, 1 row affected (0.01 sec)

-- 写入的JSON语法错误时会报错
mysql> INSERT INTO t1 VALUES('{"age":2');
ERROR 3140 (22032): Invalid JSON text: "Missing a comma or '}' after an object member." at position 8 in value for column 't1.id1'.

使用json_type()可以看到插入的json是什么类型:

mysql> SELECT json_type('"abc"') js1,json_type('[1,2,"abc"]') js2,json_type('{"t1":"value"}') js3;
+--------+-------+--------+
| js1    | js2   | js3    |
+--------+-------+--------+
| STRING | ARRAY | OBJECT |
+--------+-------+--------+
1 row in set (0.01 sec)

JSON数据类型对大小写敏感,x和X是完全不同的两个JSON数据,常见的null、false、true必须是小写才合法。通过函数json_valid() 可以看判断json值是否合法

mysql> select JSON_VALID('null') n1,JSON_VALID('NULL') n2,JSON_VALID('false') f1,JSON_VALID('FALSE') f2;
+------+------+------+------+
| n1   | n2   | f1   | f2   |
+------+------+------+------+
|    1 |    0 |    1 |    0 |
+------+------+------+------+
1 row in set (0.00 sec)

如果插入的JSON数据中包含单引号或双引号,需要转义。

  • 显式插入
mysql> INSERT INTO t1 VALUES(JSON_OBJECT("name","ab\"c"));
Query OK, 1 row affected (0.00 sec)
  • 隐式插入
mysql> INSERT INTO t1 VALUES('{"name":"ab\"c"}');
ERROR 3140 (22032): Invalid JSON text: "Missing a comma or '}' after an object member." at position 12 in value for column 't1.id1'.
mysql> INSERT INTO t1 VALUES('{"name":"ab\\"c"}');
Query OK, 1 row affected (0.00 sec)

使用隐式插入的话,需要两个反斜杠才能正常识别。

MySQL对JSON的存储做了一些限制,JSON列不允许有默认值,且文本的最大长度取决于系统变量max_allwed_packet。改值只在存储时限制,内从中计算时是允许超过这个值的。

更多JSON函数,后续章节会讲到。

笔记来自:《深入浅出MySQL:数据库开发,优化与管理维护(第三版)》

Last Modified: September 12, 2021