mysql的数据类型和字符集

MySQL的数据类型

MySQL数据库支持的数据类型主要有以下几种:

  • 整型
  • 浮点型
  • 字符
  • BLOB型
  • 枚举和集合类型
  • JSON类型(MySQL5.7新增加的支持)

整型

整数类型是数据库中最基本的数据类型。标准SQL中支持INTEGER和SMALLINT这两类整数类型。MySQL数据库除了支持这两种类型之外,还扩展支持了TINYINT, MEDIUMINT和BIGINT。

MySQL中各种整型占据的字节数和取值范文如下:

整数类型 字节数 无符号数取值范围 有符号数取值范围(添加一位符号为,把无符号数除以2) 默认显示宽度
TINYINT 1 0~2^8 -128~127 4
SMALLINT 2 0~2^16 -32768~32767 6
MEDIUMINT 3 0~2^24 -8388608~8388607 9
INT 4 0~2^32 -2147483648~2147483647 11
INTEGER 4 0~2^32 -2147483648~2147483647 11
BIGINT 8 0~2^64 -(2^64)/2~[(2^64)/2]  -1 20

INT类型和INTEGER类型的字节数和取值范围是一样,在MySQL中INT类型和INTEGER类型是一样的。

MySQL支持数据类型的名称后面指定该类型的显示宽度。

数据类型 (显示宽度)#其中,数据类型参数是整数数据类型的名称,显示宽度参数是指定宽度的数值。#在建表时,若是没有指定显示宽度,则MySQL使用默认的显示宽度:mysql> create table tb3(a tinyint, b smallint, c mediumint, d int, e bigint);Query OK, 0 rows affected (0.02 sec)

mysql> show create table tb3;    # 查看默认的显示宽度+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Table | Create Table                                                                                                                                                                                                        |+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| tb3   | CREATE TABLE `tb3` (  `a` tinyint(4) DEFAULT NULL,  `b` smallint(6) DEFAULT NULL,  `c` mediumint(9) DEFAULT NULL,  `d` int(11) DEFAULT NULL,  `e` bigint(20) DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8 |+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+1 row in set (0.00 sec)

mysql>

整型的zerofill参数和auto_increment参数:

  • zerofill,在插入数据长度没有达到默认显示宽度时,用0填充。
mysql> create table tb4(a int(4) zerofill, b int(4));  # 建表时使用zerofill参数
Query OK, 0 rows affected (0.01 sec)

mysql> insert into tb4 values(1,2);                    #插入的数据不足时,用0填充。
Query OK, 1 row affected (0.00 sec)

mysql> select * from tb4;
+------+------+
| a    | b    |
+------+------+
| 0001 |    2 |
+------+------+
1 row in set (0.00 sec)

mysql> insert into tb4 values(10000,20000);          #插入超过指定宽度的数据Query OK, 1 row affected (0.00 sec)

mysql> select * from tb4;                            #仍然会正常显示+-------+-------+| a     | b     |+-------+-------+|  0001 |     2 || 10000 | 20000 |+-------+-------+2 rows in set (0.00 sec)

mysql> insert into tb4 values(123456789123,123456789123);         #插入超过默认宽度的数据会报错ERROR 1264 (22003): Out of range value for column ‘a‘ at row 1mysql> 
  • auto_increment参数,自增长,需要注意的是自增长序列必须为索引,一张表中,只能有一个自增长的字段。
mysql> create table tb5(a int(4) auto_increment, b int);                     #直接创建会报错
ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key
mysql> create table tb5(a int(4) auto_increment primary key, b int);         #自增长列必须为索引
Query OK, 0 rows affected (0.03 sec)

mysql> insert into tb5(b) values(5);         #插入字段b数值Query OK, 1 row affected (0.00 sec)

mysql> select * from tb5;                    #自增长列是从1开始的+---+------+| a | b    |+---+------+| 1 |    5 |+---+------+1 row in set (0.00 sec)

#自增长列的下一个值,是从这个列中最大的一个数值+1,开始的,如下:mysql> insert into tb5(b) values(8);         #插入两条数据Query OK, 1 row affected (0.01 sec)

mysql> insert into tb5(b) values(9);         #插入数据之后,字段a的值为3Query OK, 1 row affected (0.00 sec)

mysql> insert into tb5 values(-7, 21);       #插入字段a的数值为-7Query OK, 1 row affected (0.01 sec)

mysql> insert into tb5(b) values(23);        #再插入一条数据,字段a的值为4,而不是-6Query OK, 1 row affected (0.00 sec)

mysql> select * from tb5;+----+------+| a  | b    |+----+------+| -7 |   21 ||  1 |    5 ||  2 |    8 ||  3 |    9 ||  4 |   23 |+----+------+5 rows in set (0.00 sec)

#可以设置自增长字段的初始值mysql> create table tb5( a int(4) auto_increment primary key, b int) auto_increment=5;   #设置初始值为5Query OK, 0 rows affected (0.01 sec)

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

mysql> select * from tb5;+---+------+| a | b    |+---+------+| 5 |   23 |+---+------+1 row in set (0.00 sec)

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

mysql> select * from tb5;+---+------+| a | b    |+---+------+| 5 |   23 || 6 |   21 |+---+------+2 rows in set (0.00 sec)

浮点型

MySQL中使用浮点类型和定点数类型来表示小数。浮点数类型包括单精度浮点数和双精度浮点数。定点数类型就是DECIMAL型。

类型 字节数 负数取值范围 非负数取值范围
float 4 暂无 暂无
double 8 暂无 暂无
DECIMAL(M,D)或者DEC(M,D) M+2 暂无 暂无

MySQL可以指定浮点数和定点数的精度。

数据类型 (M,D)
#M称为精度,是数据的总长度,小数点不占位置;D参数称为标度,指小数点后的长度

浮点数在保存的时候经常会出一些意想不到的结果,建议使用DEC保存。

https://www.cnblogs.com/phpfensi/p/8143313.html
创建mysql数据表的时候,经常会遇到存储小数(浮点数)的情况,如:价格,重量,身高等。

目前大的公司流行三种存储方案:

1、将数据扩大10的倍数达到使用整数类型存储目的。

比如价格,我们经常以分为单位进行存储,也就是将数据扩大100倍,这样元改成分存储。

重量可以用克为单位,如果克还是小数,就以毫克,微克等单位进行存储。

2、使用decimal类型的方式存储

比如价格,我们可以使用两位小数的精度进行存储。强烈不建议采用float或者double的类型存储,会存在精度损失的问题,在以后做值比较的时候,容易出现不正确的结果。

3、小数和整数部分分开存储。

比如价格3.14,我们存成两个字段,一个字段存储3,一个字段存储14,一般情况下用的少。当存储的数据范围超出decimal的范围时,可以将数据按照整数和小数拆分。

MySQL中小数的存储

MySQL小数的存储,可以参照上面提到的方法!

日期与时间类型

日期与时间类型是为了方便在数据库中存储日期和时间而设定的。MySQL中有多种表示日期和时间的数据类型。其中,year表示时间,date表示日期,time表示实际;datetime和timestamp表示日期和时间。

类型 字节数 取值范围 零值
YEAR 1 1901~2155 0000
DATE 4 1000-01-01~9999~12-31 0000:00:00
TIME 3 -839:59:59~838:59:59 00:00:00
DATETIME 8 1000-01-01 00:00:00 ~9999~12-31 23:59:59 0000-00-00 00:00:00
TIMESTAMP(包含时区信息) 4 1970-01-01 08:00:01~2038-01-19 11:14:07 0000-00-00  00:00:00

每一种时间类型都有一个有效的范围。介绍一下Time类型。

TIME类型使用3个字节来表示时间。MySQL中以HH:MM:SS的形式显示TIME类型的值。其中,HH表示时,MM表示分,取值范围为0~59;SS表示秒,取值范围为0~59。虽然小时的范围是0~23,但是为表示某种特殊需要的时间间隔,将TIME类型的范围扩大了,而且还支持负数。

TIME类型的字段赋值表示方法如下:

“D HH:MM:SS”格式的字符串表示。其中,D表示天数,取值范围为0~34。保存时,小时的值等于(D*34+HH).
mysql> create table tb6(d time);
Query OK, 0 rows affected (0.02 sec)

mysql> insert into tb6 values("2 11:30:50");
Query OK, 1 row affected (0.01 sec)

mysql> select * from tb6;
+----------+
| d        |
+----------+
| 59:30:50 |
+----------+
1 row in set (0.00 sec)

mysql>

在向数据库输入年份,日期的时候,MySQL有一些便捷的方法,但是推荐使用标准的输入,即没有缺省的输入!

字符类型

char类型和varchar类型都是在创建表时指定了最大长度,其基本形式如下:

字符串类型(M)        # M表示该字符串的最大长度为M,M指的是字符的个数,而不是字节!

char(M):表示该字段的字符串的最大长度为M,M取值范围为0~255之间的任意值。存储的占用的字节也是M字节固定不变的!varhchar(M):表示字段的字符串最大长度为M,M取值范围为0~65535之间的任意值。指定为varchar类型之后,其长度可以在0到M(最大长度)之间。其占用的字节为,字符的实际字节数再加1.一个实例:在utf8中一个英文字母占用一个自己,一个汉字占用3个字节。mysql> create table tb7(a char(5), b varchar(5));Query OK, 0 rows affected (0.04 sec)mysql> insert into tb7 values("a", "a"), ("bb","bb");  #插入数值Query OK, 2 rows affected (0.00 sec)Records: 2  Duplicates: 0  Warnings: 0

mysql> select a, b from tb7;    +------+------+| a    | b    |           #这个记录中a占用5个字节,b占用2个字节+------+------+| a    | a    || bb   | bb   |           #这个记录中a占用5个字节,b占用3个字节。+------+------+2 rows in set (0.00 sec)

#插入汉字mysql> insert into tb7 values("aaaaa","bbbbb");Query OK, 1 row affected (0.01 sec)

mysql> insert into tb7 values("上下左右中","上下左右中");Query OK, 1 row affected (0.00 sec)

mysql> select a, b from tb7;+-----------------+-----------------+| a               | b               |+-----------------+-----------------+| aaaaa           | bbbbb           |      #这个记录a占用了5个字节,b占用了5+1个字节| 上下左右中        | 上下左右中       |      #这个记录中a占用了5*3=15个字节,b占用了5*3+1=16个字节+-----------------+-----------------+2 rows in set (0.00 sec)

mysql>

特别注意: 通过以上的实例可以发现,char(M)和varchar(M)中的M指的是字符的个数,不是字节!

      那么M的取值范围,那个范围究竟是字节还是字符呢?

TEXT类型

TEXT类型是一种特殊的字符串类型。TEXT只保存字符数据。包含以下四种类型:

类型 允许长度 存储空间
TINYTEXT 0~255字节 存储的实际字节+2个字节
TEXT 0~65535字节 存储的实际字节+2个字节
MEDIUMTEXT 0~2^24-1字节 存储的实际字节+3个字节
LONGTEXT 0~2^32-1字节 存储的实际字节+4个字节

在实际存储时,可以根据不同需求选择不同的类型存储。

ENUM类型

ENUM类型又称为枚举类型。在创建表时,ENUM类型的取值范围就以列表的形式指定了。

属性名  ENUM("value1", "value2",...)
#ENUM类型的值只能取列表中的一个元素,取值列表最多有65535个元素。这些数值是以数组的形式存储,MySQL中存入的是数组的下标,而不是列表中的值。默认顺序,按数组的顺序排序。#如果ENUM类型加上了 NOT NULL属性,其默认值为取值列表的第一个元素。如果不加NOT NULL 属性,ENUM允许插入空值,而且NULL为默认值。

mysql> create table tb8(a enum("a","b","c","d") not null, b enum("e","f","g"));Query OK, 0 rows affected (0.03 sec)

mysql> insert into tb8(a) values("a");     #b的默认值为空Query OK, 1 row affected (0.02 sec)

mysql> select * from tb8;+---+------+| a | b    |+---+------+| a | NULL |+---+------+1 row in set (0.00 sec)

mysql> insert into tb8(b) values("e");       #的默认值为第一个字符“a”Query OK, 1 row affected (0.01 sec)

mysql> select * from tb8;+---+------+| a | b    |+---+------+| a | NULL || a | e    |+---+------+2 rows in set (0.00 sec)

mysql> insert into tb8(b) values(1);        #插入数字,表示对应数组的下标的值Query OK, 1 row affected (0.00 sec)

mysql> select * from tb8;+---+------+| a | b    |+---+------+| a | NULL || a | e    || a | e    |+---+------+3 rows in set (0.00 sec)

mysql> insert into tb8(b) values(0);       #插入0是会报错的,因此这里的数值下标从1开始。ERROR 1265 (01000): Data truncated for column ‘b‘ at row 1mysql>

set类型

set类型与enum类型一样,区别在于set类型可以选取多个值,而enum类型只能选择一个值。

插入记录时,set字段中的元素顺序是无关紧要的,存入MySQL数据库后,数据库系统会自动按照定义时的顺序显示。

mysql> create table tb9(str1 set("a", "b", "c","d"), num set("one", "two","three") not null);  #创建一个表
Query OK, 0 rows affected (0.01 sec)
mysql> insert into tb9(str1,num) values("a,d", "one,three");             # 插入多个数据
Query OK, 1 row affected (0.02 sec)

mysql> select * from tb9;
+------+-----------+
| str1 | num       |
+------+-----------+
| a,d  | one,three |
+------+-----------+
1 row in set (0.00 sec)

mysql> insert into tb9(num) values("one,two");                        #不设置not null默认数据为NULL
Query OK, 1 row affected (0.01 sec)

mysql> select * from tb9;
+------+-----------+
| str1 | num       |
+------+-----------+
| a,d  | one,three |
| NULL | one,two   |
+------+-----------+
2 rows in set (0.00 sec)

mysql> insert into tb9(str1) values("c,d");                          #设置NOT NULL默认数值,没有默认数值
ERROR 1364 (HY000): Field ‘num‘ doesn‘t have a default value
mysql> insert into tb9(str1,num) values("d,b,a,a", "three, one");    #注意插入的多个数值之间不要有空格ERROR 1265 (01000): Data truncated for column ‘num‘ at row 1mysql> insert into tb9(str1,num) values("d,b,a,a", "three,one");     #打乱顺序插入Query OK, 1 row affected (0.00 sec)

mysql> select * from tb9;        #仍然是按照定义时的顺序存储的+-------+-----------+| str1  | num       |+-------+-----------+| a,d   | one,three || NULL  | one,two   || a,b,d | one,three |+-------+-----------+3 rows in set (0.00 sec)

mysql>

二进制类型

二进制类型是在数据库中存储二进制数据的数据类型。包含以下几种:

项目 说明
BINARY(M) 字节长度为M,允许长度为0~M的定长二进制字符串
VARBINARY(M) 允许长度为0~M的变长二进制字符串,字节数为数值的字节数+1
BIT(M) M位二进制数据,M最大值为64
TINYBLOB 可变长二进制数据,最多为255个字节
BLOB 可变长二进制数据,最多为(2^16-1)个字节
MEDIUMBLOB 可变长二进制数据,最多为(2^24-1)个字节
LONGBLOB 可变长二进制数据,最多为(2^32-1)个字节

BLOB类型是一种特殊的二进制类型。BLOB类型可以用来数量很大的二进制数据,如图片等。但是通常情况下,可以把图片和文档存储在文件系统中,在BLOB中存入对应图片,文档的路径地址。但是这样,访问的速度可能会慢一点吧!

JSON类型:

在MySQL5.7中新增加了对JSON的支持。与在字符串列中存储json相比,数据类型有以下几点优势:

  • 自动验证在JSON列中存储的JSON文档,无效的列会报错。
  • 优化的存储格式。存储在JSON列中的JSON文档将 转换为内部格式,以允许快速读取文档元素。当服务器稍后必须读取以此二进制格式存储的JSON值时,不需要从文本表示中解析该值。二进制格式的结构使服务器能够直接通过键或数组索引查找子对象或嵌套值,而无需在文档中读取它们之前或之后的所有值。存储JSON所需的空间与LONGBLOB和LONGTEXT类型大致相同。请务必记住,JSON列中存储的任何JSON文档的大小都限制为max_allowed_packet系统变量的值。(当服务器在内存中内部操作JSON值时,它可能大于此值;当服务器存储时,该限制适用。)
  • JSON列没有默认值

虚构一张表,来说明MySQL5.7中JSON的用法:

#创建一张表CREATE TABLE json_test (
    id INT auto_increment PRIMARY KEY,
    userinfo json
);

#在表中插入json数据类型,JSON数据类型有两种,一种是JSON数组,另一种是JSON对象。INSERT INTO json_test(userinfo) VALUES(‘{"name":"libai","address":"china","email":"[email protected]"}‘);INSERT INTO json_test(userinfo) VALUES(‘{"name":"Obama","address":"miguo","email":"[email protected]"}‘);INSERT INTO json_test(userinfo) VALUES(‘{"name":"putin","address":"russia","email":"[email protected]"}‘);###  JSON对象包含一组由逗号分隔的键值对,并包含在字符{和}字符中:INSERT INTO json_test(userinfo) VALUES(‘["wangxz","guangzhou","[email protected]"]‘);###  JSON数组包含一个由逗号分隔的值列表

还可以插入JSON数组和JSON对象的嵌套:

INSERT INTO json_test(userinfo) VALUES(‘[5,{"id":1, "name":"lfy"}, ["a","b"]]‘);

如果插入无效的JSON数组和JSON对象将会报错。

除MySQL数据类型之外,还有一组SQL函数可用于对JSON值进行操作。

  

mysql> select * from json_test;
+----+--------------------------------------------------------------------+
| id | userinfo                                                           |
+----+--------------------------------------------------------------------+
|  1 | {"name": "libai", "email": "libai@163.com", "address": "china"}    |
|  2 | {"name": "Obama", "email": "libai@gmail.com", "address": "miguo"}  |
|  3 | {"name": "putin", "email": "putin@gmail.com", "address": "russia"} |
|  4 | ["wangxz", "guangzhou", "[email protected]"]                          |
+----+--------------------------------------------------------------------+
4 rows in set (0.00 sec)
  • JSON_TYPE函数返回JSON的类型:
mysql> select json_type(userinfo) from json_test where id = 1;  #返回的是JSON对象类型
+---------------------+
| json_type(userinfo) |
+---------------------+
| OBJECT              |
+---------------------+
1 row in set (0.00 sec)

mysql> select json_type(userinfo) from json_test where id = 4;   #返回的是数组类型
+---------------------+
| json_type(userinfo) |
+---------------------+
| ARRAY               |
+---------------------+
1 row in set (0.00 sec)

mysql> 
  • 在向表中插入JSON类型时,可以借助于JSON_ARRAY()函数和JSON_OBJECT()函数,得到JSON数据类型。
mysql> select json_array("a", 1, now());
+----------------------------------------+
| json_array("a", 1, now())              |
+----------------------------------------+
| ["a", 1, "2018-10-05 09:20:23.000000"] |
+----------------------------------------+
1 row in set (0.00 sec)

mysql> insert into json_test(userinfo) select json_array("a", 1, now());
Query OK, 1 row affected (0.02 sec)
Records: 1  Duplicates: 0  Warnings: 0

#这样在操作是不用去构造对应的JSON数组,可以借助于这个函数直接插入
mysql> select json_object("name","tump","address","miguo","email","tump@gmail.com");
+-----------------------------------------------------------------------+
| json_object("name","tump","address","miguo","email","tump@gmail.com") |
+-----------------------------------------------------------------------+
| {"name": "tump", "email": "tump@gmail.com", "address": "miguo"}       |
+-----------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> insert into json_test(userinfo) select json_object("name","tump","address","miguo","email","tump@gmail.com");
Query OK, 1 row affected (0.01 sec)
Records: 1  Duplicates: 0  Warnings: 0#JSON_OBJECT获取一个键值对列表,并返回包含这些对的JSON对象。
  • JSON_MERGE获取两个或多个文档的组合结果
mysql> select json_merge(‘["a","b"]‘, ‘{"key":"value"}‘);
+--------------------------------------------+
| json_merge(‘["a","b"]‘, ‘{"key":"value"}‘) |
+--------------------------------------------+
| ["a", "b", {"key": "value"}]               |
+--------------------------------------------+
1 row in set, 1 warning (0.00 sec)

mysql>
  • 可以将JSON值分配给用户定义的变量,但是定义的变量不能是JSON类型。
mysql> set @j = json_object("key","value");
Query OK, 0 rows affected (0.00 sec)

mysql> select @j;
+------------------+
| @j               |
+------------------+
| {"key": "value"} |
+------------------+
1 row in set (0.00 sec)

mysql> select charset(@j), collation(@j);
+-------------+---------------+
| charset(@j) | collation(@j) |
+-------------+---------------+
| utf8mb4     | utf8mb4_bin   |
+-------------+---------------+
1 row in set (0.00 sec)

#通过转换生成的字符串具有以上的字符集和排序规则,utf8mb4_bin是二进制排序规则,所以区分大小写。
mysql> select json_array("x") = json_array("X");
+-----------------------------------+
| json_array("x") = json_array("X") |
+-----------------------------------+
|                                 0 |
+-----------------------------------+
1 row in set (0.00 sec)

mysql> select json_valid("null"),json_valid("NULL"),json_valid("true"),json_valid(True);
+--------------------+--------------------+--------------------+------------------+
| json_valid("null") | json_valid("NULL") | json_valid("true") | json_valid(True) |
+--------------------+--------------------+--------------------+------------------+
|                  1 |                  0 |                  1 |                0 |
+--------------------+--------------------+--------------------+------------------+
1 row in set (0.00 sec)

所以这些值null, true,false还是以小写的形式。
  • 把引号插入到JSON对象中
#使用json_object对象时,需要使用反斜线转义引号才能插入mysql> insert into json_test(userinfo) values(json_object("mascot", "The mysql mascot is a dolphin named \"Sakila\"."));
Query OK, 1 row affected (0.00 sec)

mysql> insert into json_test(userinfo) select json_object("mascot", "The mysql mascot is a dolphin named \"Sakila\".");
Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0
#把插入的值作为json对象插入时,需要使用双反斜线。
mysql> insert into json_test(userinfo) values(‘{"mascot":"The mysql mascot is a dolphin named \"Sakila\"."}‘);
ERROR 3140 (22032): Invalid JSON text: "Missing a comma or ‘}‘ after an object member." at position 49 in value for column ‘json_test.userinfo‘.
mysql> insert into json_test(userinfo) values(‘{"mascot":"The mysql mascot is a dolphin named \\"Sakila\\"."}‘);
Query OK, 1 row affected (0.01 sec)

#使用双反斜线可以防止MySQL做转义处理,而是将字符串文字传递给存储引擎进行处理。mysql> select * from json_test order by id desc limit 3;+----+---------------------------------------------------------------+| id | userinfo                                                      |+----+---------------------------------------------------------------+| 10 | {"mascot": "The mysql mascot is a dolphin named \"Sakila\"."} ||  9 | {"mascot": "The mysql mascot is a dolphin named \"Sakila\"."} ||  8 | {"mascot": "The mysql mascot is a dolphin named \"Sakila\"."} |+----+---------------------------------------------------------------+3 rows in set (0.00 sec)

#查询数据可以看到反斜线的存在查找JSON数据类型中,某一个key的值:因为表中插入了测试数据,因此加上了where语句!mysql> select userinfo->"$.address" from json_test where id <= 3;    #注意格式+-----------------------+| userinfo->"$.address" |+-----------------------+| "china"               || "miguo"               || "russia"              |+-----------------------+3 rows in set (0.00 sec)

mysql> select userinfo->"$.mascot" from json_test where id >7;+---------------------------------------------------+| userinfo->"$.mascot"                              |+---------------------------------------------------+| "The mysql mascot is a dolphin named \"Sakila\"." || "The mysql mascot is a dolphin named \"Sakila\"." || "The mysql mascot is a dolphin named \"Sakila\"." |+---------------------------------------------------+3 rows in set (0.00 sec)

mysql> select userinfo->>"$.mascot" from json_test where id >7;   #注意这一种与上面一种写法的区别,去掉了字符上的转义符+-----------------------------------------------+| userinfo->>"$.mascot"                         |+-----------------------------------------------+| The mysql mascot is a dolphin named "Sakila". || The mysql mascot is a dolphin named "Sakila". || The mysql mascot is a dolphin named "Sakila". |+-----------------------------------------------+3 rows in set (0.00 sec)

JSON值的规范化,合并和自动包装:

当解析一个字符串时,发现它是一个有效的JSON文档时,它就会被标准化。

json_object的过程就是一个标准化的过程。

json_merge将组合的后面的一个数组连接到前面一个数值的末尾,组合为单个数据。

mysql> select json_merge(‘[1,2]‘, ‘["a","b"]‘);
+----------------------------------+
| json_merge(‘[1,2]‘, ‘["a","b"]‘) |
+----------------------------------+
| [1, 2, "a", "b"]                 |
+----------------------------------+
1 row in set, 1 warning (0.00 sec)

mysql> 

合并时多个对象生成单个对象。如果多个对象具有相同的键,则生成的合并对象中该键的值是包含该键所有值的数值。

mysql> select json_merge(‘{"a":1,"b":2}‘, ‘{"a":3, "c":4}‘);
+-----------------------------------------------+
| json_merge(‘{"a":1,"b":2}‘, ‘{"a":3, "c":4}‘) |
+-----------------------------------------------+
| {"a": [1, 3], "b": 2, "c": 4}                 |
+-----------------------------------------------+
1 row in set, 1 warning (0.00 sec)

mysql>

自动将两个字符合并为数组:

mysql> select json_merge("1", "2");
+----------------------+
| json_merge("1", "2") |
+----------------------+
| [1, 2]               |
+----------------------+
1 row in set, 1 warning (0.00 sec)

mysql>

通过将对象自动包装为数值,来合并数组和对象:

mysql> select json_merge(‘[1,2]‘, ‘{"a":1,"b":2}‘);
+--------------------------------------+
| json_merge(‘[1,2]‘, ‘{"a":1,"b":2}‘) |
+--------------------------------------+
| [1, 2, {"a": 1, "b": 2}]             |
+--------------------------------------+
1 row in set, 1 warning (0.00 sec)

mysql>

对JSON的操作:

  • JSON_EXTRACT---对于提取JSON文档的一部分或修改JSON文档的函数非常有用。
mysql> select json_extract(‘{"id":14, "name":"wangxz"}‘, "$.name");
+------------------------------------------------------+
| json_extract(‘{"id":14, "name":"wangxz"}‘, "$.name") |
+------------------------------------------------------+
| "wangxz"                                             |
+------------------------------------------------------+
1 row in set (0.00 sec)

#使用前导的$符合表示当前选中的JSON文档,后面采用如上的方式,选择提取文档中的数据mysql> select json_extract(userinfo, "$.name") from json_test WHERE id <= 3; #json_extract在select语句中的使用+----------------------------------+| json_extract(userinfo, "$.name") |+----------------------------------+| "libai"                          || "Obama"                          || "putin"                          |+----------------------------------+3 rows in set (0.00 sec)

上面提到可以使用$符合来表示当前选中的JSON文档。在选择时$符合可以和通配符结合。

mysql> select json_extract(‘[5, {"id": 1, "name": "lfy"}, ["a", "b"]]‘, "$[*]"); #选择JSON数组中的所有元素的值
+-------------------------------------------------------------------+
| json_extract(‘[5, {"id": 1, "name": "lfy"}, ["a", "b"]]‘, "$[*]") |
+-------------------------------------------------------------------+
| [5, {"id": 1, "name": "lfy"}, ["a", "b"]]                         |
+-------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> select json_extract(‘[5, {"id": 1, "name": "lfy"}, ["a", "b"]]‘, "$[0]"); #选择JSON数组中的第一个元素
+-------------------------------------------------------------------+
| json_extract(‘[5, {"id": 1, "name": "lfy"}, ["a", "b"]]‘, "$[0]") |
+-------------------------------------------------------------------+
| 5                                                                 |
+-------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> select json_extract(‘[5, {"id": 1, "name": "lfy"}, ["a", "b"]]‘, "$[1]"); #选择JSON数组中的第二个元素,这个JSON对象
+-------------------------------------------------------------------+
| json_extract(‘[5, {"id": 1, "name": "lfy"}, ["a", "b"]]‘, "$[1]") |
+-------------------------------------------------------------------+
| {"id": 1, "name": "lfy"}                                          |
+-------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> select json_extract(‘[5, {"id": 1, "name": "lfy"}, ["a", "b"]]‘, "$[1].id");  #选择JSON对象的id
+----------------------------------------------------------------------+
| json_extract(‘[5, {"id": 1, "name": "lfy"}, ["a", "b"]]‘, "$[1].id") |
+----------------------------------------------------------------------+
| 1                                                                    |
+----------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> select json_extract(‘[5, {"id": 1, "name": "lfy"}, ["a", "b"]]‘, "$[1].name");
+------------------------------------------------------------------------+
| json_extract(‘[5, {"id": 1, "name": "lfy"}, ["a", "b"]]‘, "$[1].name") |
+------------------------------------------------------------------------+
| "lfy"                                                                  |
+------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> select json_extract(‘[5, {"id": 1, "name": "lfy"}, ["a", "b"]]‘, "$[1][0]");
+----------------------------------------------------------------------+
| json_extract(‘[5, {"id": 1, "name": "lfy"}, ["a", "b"]]‘, "$[1][0]") |
+----------------------------------------------------------------------+
| {"id": 1, "name": "lfy"}                                             |
+----------------------------------------------------------------------+
1 row in set (0.00 sec)mysql> select json_extract(‘[5, {"id": 1, "name": "lfy"}, ["a", "b"]]‘, "$[1].*"); #选择JSON对象中所有的成员的value值。+---------------------------------------------------------------------+| json_extract(‘[5, {"id": 1, "name": "lfy"}, ["a", "b"]]‘, "$[1].*") |+---------------------------------------------------------------------+| [1, "lfy"]                                                          |+---------------------------------------------------------------------+1 row in set (0.00 sec)

mysql>

mysql> select json_extract(‘[5, {"id": 1, "name": "lfy"}, ["a", "b"]]‘, "$[2]");
+-------------------------------------------------------------------+
| json_extract(‘[5, {"id": 1, "name": "lfy"}, ["a", "b"]]‘, "$[2]") |
+-------------------------------------------------------------------+
| ["a", "b"]                                                        |
+-------------------------------------------------------------------+
1 row in set (0.00 sec)
  • JSON_SET替换JSON文档中某个位置得数值,若是这个位置不存在,则在这个位置添加数值。
mysql> select userinfo from json_test WHERE id = 5;
+-------------------------------------------+
| userinfo                                  |
+-------------------------------------------+
| [5, {"id": 1, "name": "lfy"}, ["a", "b"]] |
+-------------------------------------------+
1 row in set (0.00 sec)

#表中有如上数据,我们把name的值改为wxz,最后一个数值中加入“c”
mysql> select json_set(userinfo, "$[1].name", "wxz", "$[2][2]", "c") from json_test WHERE id = 5;
+--------------------------------------------------------+
| json_set(userinfo, "$[1].name", "wxz", "$[2][2]", "c") |
+--------------------------------------------------------+
| [5, {"id": 1, "name": "wxz"}, ["a", "b", "c"]]         |
+--------------------------------------------------------+
1 row in set (0.00 sec)
  • JSON_INSERT添加新的数值,但是不替换旧数值!
mysql> select userinfo from json_test WHERE id in (5,11);
+-------------------------------------------+
| userinfo                                  |
+-------------------------------------------+
| [5, {"id": 1, "name": "lfy"}, ["a", "b"]] |
+-------------------------------------------+
1 row in set (0.01 sec)
#注意insert的作用,只是添加了字符“c”,并没有更改name键的值
mysql> select json_insert(userinfo, "$[1].name", "wxz", "$[2][2]", "c") from json_test WHERE id = 5;
+-----------------------------------------------------------+
| json_insert(userinfo, "$[1].name", "wxz", "$[2][2]", "c") |
+-----------------------------------------------------------+
| [5, {"id": 1, "name": "lfy"}, ["a", "b", "c"]]            |
+-----------------------------------------------------------+
1 row in set (0.00 sec)
  • JSON_REPLACE:替换旧值,但是不能添加新值。
mysql> select json_replace(userinfo, "$[1].name", "wxz", "$[2][2]", "c") from json_test WHERE id = 5;
+------------------------------------------------------------+
| json_replace(userinfo, "$[1].name", "wxz", "$[2][2]", "c") |
+------------------------------------------------------------+
| [5, {"id": 1, "name": "wxz"}, ["a", "b"]]                  |
+------------------------------------------------------------+
1 row in set (0.00 sec)

mysql>

JSON_REMOVE删除选择的数值。

mysql> select json_remove(userinfo, "$[1].name", "$[2][1]") from json_test WHERE id = 5;
+-----------------------------------------------+
| json_remove(userinfo, "$[1].name", "$[2][1]") |
+-----------------------------------------------+
| [5, {"id": 1}, ["a"]]                         |
+-----------------------------------------------+
1 row in set (0.00 sec)

mysql>

原文地址:https://www.cnblogs.com/wxzhe/p/9741660.html

时间: 2024-08-09 18:56:51

mysql的数据类型和字符集的相关文章

mysql修行练级之字符集,数据类型与存储引擎选择

如何选择合适的存储引擎 几个常用存储引擎的特点 下面我们重点介绍几种常用的存储引擎并对比各个存储引擎之间的区别和推荐使用方式. 特点 Myisam BDB Memory InnoDB Archive 存储限制 没有 没有 有 64TB 没有 事务安全 支持 支持 锁机制 表锁 页锁 表锁 行锁 行锁 B树索引 支持 支持 支持 支持 哈希索引 支持 支持 全文索引 支持 集群索引 支持 数据缓存 支持 支持 索引缓存 支持 支持 支持 数据可压缩 支持 支持 空间使用 低 低 N/A 高 非常低

MySQL的数据类型及其常用修饰符详解

MySQL的数据类型及其常用修饰符详解 ================================================================================ 概述: ========================================================================================== Mysql的数据类型     在mysql数据库当中,每一个库都是有多张表来组成的,每一个表都是由行和列来组

mysql 常见数据类型

---恢复内容开始--- MySQL常见的数据类型 一.数据类型是什么? 数据类型是指列.存储过程参数.表达式和局部变量的数据特征,它决定了数据的存储格式,代表了不同的信息类型. 有一些数据是要存储为数字的,数字当中有些是要存储为整数.小数.日期型等... 二.MYSQL常见数据类型 MySQL支持多种类型,大致可以分为四类:数值型.浮点型.日期/时间和字符串(字符)类型. 1.数值类型 MySQL支持所有标准SQL数值数据类型. 这些数值类型包括严格数值数据类型(INTEGER.SMALLIN

MYSQL中数据类型介绍

一.MySQL的数据类型 主要包括以下五大类: 整数类型:BIT.BOOL.TINY INT.SMALL INT.MEDIUM INT. INT. BIG INT 浮点数类型:FLOAT.DOUBLE.DECIMAL 字符串类型:CHAR.VARCHAR.TINY TEXT.TEXT.MEDIUM TEXT.LONGTEXT.TINY BLOB.BLOB.MEDIUM BLOB.LONG BLOB 日期类型:Date.DateTime.TimeStamp.Time.Year 其他数据类型:BIN

MySQL基础数据类型

一 介绍 存储引擎决定了表的类型,而表内存放的数据也要有不同的类型,每种数据类型都有自己的宽度,但宽度是可选的 详细参考: http://www.runoob.com/mysql/mysql-data-types.html http://dev.mysql.com/doc/refman/5.7/en/data-type-overview.html mysql常用数据类型概览: #1. 数字: 整型:tinyinit int bigint 小数: float :在位数比较短的情况下不精准 doub

mysql之数据类型以及操作数据表

数据类型: 数据类型是指列.存储过程的参数.表达式和局部变量的数据特征,它决定了数据的存储格式,代表了不同的信息类型. —————————————————————————————————————————————————————————— 在mysql当中数据类型大概有以下几类: ———————————————————————————————————————————— 1.整型: ———————————————————————————————————————————————————————————

mysql配置命令 CHARACTER_SET_%字符集设置

参照: http://blog.csdn.net/mzlqh/article/details/7621307点击打开链接 其实现在的ubuntu12.04 直接sudo apt-get install MySQL 就可以了,mysql-client会自动地为你装上 #查看mysql是否正在运行 sudo netstat -tap | grep mysql 如果是正在运行,则 tcp 0 0 localhost.localdomain:mysql *:* LISTEN - 重启mysql sudo

mysql之数据类型

 所谓建表,就是声明列的过程: 数据是以文件的形式放在硬盘中(也有放在内存里的) 列:不同的列类型占的空间不一样 选列的原则:够用又不浪费: mysql的数据类型: 整形:Tinyint(1字节) Smallint(2个字节)  Mediumint(3个字节) int(4个字节) bigint(8个字节): Tinyint在mysql默认是有符号的(-128----127): Tinyint(M) unsigned zerofill unsigned : 是无符号,影响存储范围:M代表宽度,(必

2Python全栈之路系列之MysQl基本数据类型

Python全栈之路系列之MySQL基本数据类型 MySQL中定义数据字段的类型对你数据库的优化是非常重要的. MySQL支持多种类型,大致可以分为三类: 数字类型 日期和时间类型 字符串类型 数字类型 类型 大小 用途 BIT - 二进制 TINYINT 1字节 小整数值 INT or INTEGER 4字节 大整数值 BIGINT 8字节 极大整数值 DECIMAL 对DECIMAL(M,D) ,如果M>D,为M+2否则为D+2 小数值 FLOAT 4字节 单精度浮点数值 DOUBLE 8字