首页 > 数据库 >第02期:MySQL 数据类型的艺术-大对象字段

第02期:MySQL 数据类型的艺术-大对象字段

时间:2022-12-20 15:01:27浏览次数:60  
标签:02 rw 4.0 -- MySQL 数据类型 12 mysql root


第02期:MySQL 数据类型的艺术-大对象字段_mysql


我以前分享过一篇​​《MySQL 大对象一例》​​,今天就来详细说下大对象的优缺点以及使用场景。

我们把 MySQL 的大对象类型分 TEXT / BLOB 和 JSON 两部分来说明。

 

一、TEXT / BLOB 类型

TEXT 和 BLOB 的区别非常简单。TEXT 存储以明文存储,有对应的字符集和校验规则;BLOB 则以二进制存储,没有字符集和排序规则,所有的对比都是以二进制来进行。

 

示例 1

创建一张表 c1 字段 f1,f2 分别为 tinytext 和 tinyblob。

mysql> create table c1 (f1 tinytext, f2 tinyblob);
Query OK, 0 rows affected (0.03 sec)

插入示例数据。

insert into c1 values ('a','a'),('b','b'),('B','B'),('d','d'),('F','F'),('你','你'),('我','我'),('是吧','是吧');

根据字段 f1 排序。

mysql> select * from c1 order by f1;
+--------+--------+
| f1 | f2 |
+--------+--------+
| a | a |
| b | b |
| B | B |
| d | d |
| F | F |
| 你 | 你 |
| 我 | 我 |
| 是吧 | 是吧 |
+--------+--------+
8 rows in set (0.01 sec)

根据字段 f2 排序。

mysql> select * from c1 order by f2;
+--------+--------+
| f1 | f2 |
+--------+--------+
| B | B |
| F | F |
| a | a |
| b | b |
| d | d |
| 你 | 你 |
| 我 | 我 |
| 是吧 | 是吧 |
+--------+--------+
8 rows in set (0.00 sec)

f1,f2 字段各自排序的结果都不一致。f1 是按照不区分大小写的校验规则,f2 直接二进制检验。

MySQL 的大对象类型,我从以下几类详细说明:

1.1 磁盘空间占用

第02期:MySQL 数据类型的艺术-大对象字段_mysql_02

1.2 表的存储格式

1.2.1 redundant/compact

    对 redundant 格式来说,保存大对象的前 768 字节在 InnoDB 数据页,多出来的放在溢出页。如果有多个 TEXT/BLOB 字段,那数据页将会变得臃肿不堪,性能影响很大。数据页里几乎全是无用的数据,导致额外的资源消耗。同时如果是主从架构,也会把数据全部同步到从机,对网络也是额外的消耗。所以这种场景下,一般都只是保存大对象的路径到数据库,真实的数据则放在磁盘上。

1.2.2 dynamic/compressed

    对 dynamic 格式来说,如果大对象字段存储数据大小小于 40 字节,那全部放在数据页,剩余的场景,数据页只保留一个 20 字节的指针指向溢出页。 这种场景下,如果每个大对象字段保存的数据小于 40 个字节,也就和 varchar(40),效果一样。所以用不用大对象不能一概而论。

 

1.3 表引擎相关

NDB 引擎不推荐使用大对象。涉及的细节比较多,比如含有大对象的关联字段不支持引擎关联数据下推;含有大对象的表需要额外的加锁等等。

 

1.4 索引相关

在大对象字段上建立索引必须是前缀,比如字段 f1 为 text,给前 10 个字符建立索引 idx_f1(f1(10))。

mysql> alter table t2 add key idx_f100(f100);
ERROR 1170 (42000): BLOB/TEXT column 'f100' used in key specification without a key length

 

1.5 分区表相关

分区表分区字段不支持大对象。

mysql> create table p1(f1 text) partition by list columns(f1) (partition p0 values in ('1','2'));
ERROR 1502 (HY000): A BLOB field is not allowed in partition function

 

1.6 参数相关

mysql_allowed_packet,这个参数代表 MySQL 服务端和客户端传输的单次数据包上限,如果有 text/blob 字段,此参数设置为最大值 1GB。当然了,必须同时设置客户端和服务端。

 

1.7 如何插入/获取

示例 2

插入一个 `/var/lib/mysql-files` 目录下的所有文件内容。

root@ytt-pc:/var/lib/mysql-files# ll
总用量 32M
1324681 14M -rw-r--r-- 1 root root 14M 12月 30 17:23 test3
1311598 6.6M -rw-r--r-- 1 root root 6.6M 12月 30 17:23 test
1316840 6.6M -rw-r--r-- 1 root root 6.6M 12月 30 17:23 test2
1316693 5.5M -rw-r--r-- 1 root root 5.4M 12月 30 17:26 random_test
1315066 4.0K -rw-r--r-- 1 root root 1.9K 12月 30 14:56 sample_y1.txt.nl
1311256 4.0K -rw-r----- 1 mysql mysql 1.7K 12月 30 16:23 y1.txt
1316129 4.0K -rw-r--r-- 1 root root 1.5K 12月 30 15:28 sample_y1.txt.nl2
1312042 4.0K -rw-r--r-- 1 root root 1.5K 12月 30 15:07 sample_y1.txt.awk
1316691 4.0K -rw-rw-rw- 1 mysql mysql 1.4K 12月 30 16:25 y1_older.txt
1316168 4.0K -rw-r----- 1 mysql mysql 874 12月 30 14:41 sample_y1.txt
1315893 4.0K -rw-r----- 1 root root 874 12月 30 14:45 sample_y1.txt.bak
1311076 4.0K -rw-r----- 1 mysql mysql 662 12月 30 13:56 ascii.txt
1312152 4.0K -rw-r--r-- 1 root root 648 12月 30 14:37 sample.txt
1325161 4.0K -rw-r--r-- 1 root root 403 12月 31 10:59 y1111.txt.10
1312256 4.0K -rw-r----- 1 mysql mysql 164 12月 31 09:49 y111.txt
1311248 4.0K -rw-r----- 1 mysql mysql 159 12月 31 09:42 y11.txt
1327711 4.0K -rw-r--r-- 1 root root 126 12月 5 09:56 performance_schema_enable.sql
1326639 4.0K -rw-r--r-- 1 root root 22 1月 10 11:32 系统名称

存放文件内容的表结构。

mysql-(ytt/3305)->create table file_list_upload_dir(file_name varchar(100) not null primary key,content longtext, updated datetime);
Query OK, 0 rows affected (0.03 sec)

插入文件内容。

root@ytt-pc:/var/lib/mysql-files# for i in $(ls); \
do mysql -uytt -pytt -P3305 -h127.0.0.1 \
-e "use ytt;insert into file_list_upload_dir \
values ('$i',load_file('$(pwd)/$i'),now())";done;

 

二、JSON 类型

JSON 类型相比大家都非常熟悉了,轻量级的文本交互格式,不依赖于任何语句。

制定信息参考:
​​ https://tools.ietf.org/html/rfc7159​​​ https://tools.ietf.org/html/rfc7396​

JSON 类型在 MySQL 内部以特殊的二进制方式存放,类似于 PostgreSQL 的 JSONB 类型。最大占用空间和 longtext 或者 longblob 一样。text 其实也能存储 JSON 对象,但是没有 JSON 类型的格式校验以及内部提供的众多函数。比如以下例子:

示例 3

变量 @a 和 @b 分别为标准 JSON 格式和非 JSON 格式。创建 json1 表。

mysql-(ytt/3305)->set @a='{"a":1,"b":2,"c":3,"d":4}';
Query OK, 0 rows affected (0.00 sec)

mysql-(ytt/3305)->set @b="{'a':1,'b':2,'c':3,'d':4}";
Query OK, 0 rows affected (0.00 sec)

mysql-(ytt/3305)->create table json1 (str1 json,str2 longtext);
Query OK, 0 rows affected (0.02 sec)

给 str1 插入 @a 成功,@b 失败;str2 任何字符都能插入。

mysql-(ytt/3305)->insert into json1 values (@a,@a);
Query OK, 1 row affected (0.00 sec)

mysql-(ytt/3305)->insert into json1 values (@b,@b);
ERROR 3140 (22032): Invalid JSON text: "Missing a name for object member." at position 1 in value for column 'json1.str1'.

mysql-(ytt/3305)->insert into json1 values (@a,@b);
Query OK, 1 row affected (0.01 sec)

又比如说检索部分。对 JSON 的检索比对 text 的检索容易太多。还是拿刚才的例子,需要拿出对应的值 1,对 @b 来说,可能比较麻烦,但是换成 @a 就容易多了。json_extract 函数即可。

mysql-(ytt/3305)->select json_extract(@a,'$.a') as 'a';
+------+
| a |
+------+
| 1 |
+------+
1 row in set (0.00 sec)

但是有一点比较幸运的时,针对 @b 这种格式,可以把单个字段拆分为多个,这样就可以利用 SQL 语句简单的检索出结果来了。关于拆或者不拆的优劣暂时不在本篇讨论范围内,将会在表设计理念篇来详细介绍。好了,本篇关于 MySQL 的大对象类型就介绍就到此为止,希望对大家有所帮助。


关于 MySQL 的技术内容,你们还有什么想知道的吗?赶紧留言告诉小编吧!

第02期:MySQL 数据类型的艺术-大对象字段_JSON_03

标签:02,rw,4.0,--,MySQL,数据类型,12,mysql,root
From: https://blog.51cto.com/u_15077536/5955426

相关文章

  • 技术分享 | MySQL中一个聚类增量统计 SQL 的需求
    作者:刘晨网名bisal,具有十年以上的应用运维工作经验,目前主要从事数据库应用研发能力提升和技术管理相关的工作,OracleACE,腾讯云TVP,拥有OracleOCM&OCP、EXINDevOpsM......
  • 【Mysql系列】- SQL语句优化
    前言Sql语句优化是Mysql性能优化的一部分,我们看下常见Sql语句优化及注意的有哪些。 一、查询SQL尽量不要使用select*,而是具体字段1.反例SELECT*FROMuser......
  • C语言各数据类型所占字节数
      编写C程序时需要考虑每种数据类型在内存中所占的内存大小,即使同一种数据类型在不同平台下所占内存大小亦不相同。为了得到某个类型在特定平台上的准确大写,可以使用s......
  • mysql 分组后的数据显示和实际数据有差别
    SELECT*,count(1),SUM(if(ARRIVE.ARRIVE_TIME!='无',1,0))assFROMlt_cleanroute_point_arriveASARRIVEWHEREDATE_FORMAT(data_dt,'%Y-%m'......
  • 2022.12.20 线段树复习笔记(未完待续)
    线段树原理及存储:如图,1即为根节点,存储着[1,5]的整个区间和,‘1’为左边界,‘5’为右边界,所以此节点表示的是[1,5]这个区间。线段树的每个节点向下二分,左儿子的编号为此节......
  • 我的2022年-总结、感悟、碎碎念
    我的2022年-总结、感悟、碎碎念 又到年底了,总结下2022吧,今年还是蛮多收获和感悟的,感觉越发活的通透了些,有些事情我们无法把握,有些事情我们能把握。淡然面对无法把握的......
  • 2023年元旦放假安排来了!放假通知模板提前保存到备忘录中
    2023年元旦很快就要如约而至,那么元旦放假吗?放几天假呢?元旦放假安排来了:新的一年元旦放假时间是从2022年的12月31日-2023年的1月2日共三天时间,没有其他调休安排,大家可以利......
  • 2022圣诞节手抄报模板怎么高清打印出来?手机在线打印很简单
    2022年圣诞节马上就要到了,有很多中小学生都被英语老师要求画一张圣诞节手抄报,对于比较有画画天赋的人来说,画一张手抄报不是什么难事,但是对于一些不会画画的孩子来说,这就又......
  • 最新版Photoshop 2023更新 (ps 2023) for Mac 支持M1 v24.0激活版
    Photoshop2023是一款电脑必备修图工具,该版本已经更新到ps2023版!最新的ps2023帮助你组合、修饰和重新混合您的照片,为您的旧黑白添加新颜色,或者让不需要的东西消失,也或者将......
  • 面试官:MySQL一千万数据,怎么快速查询?
    前言面试官:来说说,一千万的数据,你是怎么查询的?me:直接分页查询,使用limit分页。面试官:有实操过吗?me:肯定有呀此刻献上一首《凉凉》也许有些人没遇过上千万数据量的表,也不清楚查......