结构化和非结构化数据

  • 结构化

    • 二维表结构(行和列)
    • 使用SQL语句进行操作
  • 非结构化(schema-free)

    • 使用Key-Value格式定义数据,无结构定义
    • Value可以嵌套Key-Value格式的数据
    • 使用JSON进行实现

例如 MongoDB 是这样定义表和插入数据的:

定义表:

db.createCollection("user")

插入数据:

db.user.insert({
 user_name:"tom",
 age:30
}) 

JSON介绍

  • JSON( Java Script Object Notation)是一种轻量级的数据交换语言,并且是独立于语言的文本格式。
  • 一些 NoSQL 数据库选择 JSON 作为其数据存储格式,比如:MongoDB、CouchDB 等。
  • MySQL 5.7.x 开始支持JSON数据类型。

5.7之前,只能把JSON当作BLOB进行存储。数据库层面无法对JSON数据做一些操作,只能由应用程序处理。换句话说,就是数据库不认识JSON格式的数据。

JSON VS BLOB

  • JSON

    • JSON 数据可以做有效性检查;
    • JSON 使得查询性能提升;
    • JSON 支持部分属性索引,通过虚拟列的功能可以对JSON中的部分数据进行索引;
  • BLOB

    • BLOB 类型无法在数据库层做约束性检查;
    • BLOB 进行查询,需要遍历所有字符串;
    • BLOB 做只能做指定长度的索引;

MySQL中的JSON数据存取

按照传统方式创建一个用户表 users,表有 id, name, email, address 等属性。在业备初期,列的设计可能并不能确定,如果业务跑了一段时间后,需要增长其它的列,是很痛苦的。

我们现在设计一个有 JSON 字段的表,将用户的属性列放到 JSON 中去:

mysql> CREATE TABLE UserJson(
    uid BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    data JSON
);

可以在 insert 记录的时候,传入 JSON 格式的值,也可以将现有 users 表中的数据查询出来保存到 UserJson 表中:

mysql> insert into UserJson 
SELECT 
    uid,JSON_OBJECT('name',name,'email',email,'address',address) AS data
FROM
    User;

mysql> select * from UserJson;
+-----+----------------------------------------------------------------------+
| uid | data                                                                 |
+-----+----------------------------------------------------------------------+
|   1 | {"name": "David", "email": "david@gmail.com", "address": "Shanghai"} |
|   2 | {"name": "Amy", "email": "amy@gmail.com", "address": "Beijing"}      |
|   3 | {"name": "Tom", "email": "tom@gmail.com", "address": "Guangzhou"}    |
+-----+----------------------------------------------------------------------+

JSON_OBJECT 函数的作用,就是将传入的值以 key-value 的方式组成 Json 格式。

可以使用 JSON_EXTRACT 来提取 key-value 中的值。例如,我想知道 uid 为 1 的员工的地址:

SQL> SELECT uid,JSON_EXTRACT(data,'$.address') 
        from UserJson 
        where uid=1;
        
+-----+--------------------------------+
| uid | JSON_EXTRACT(data,'$.address') |
+-----+--------------------------------+
|   1 | "Shanghai ..."                 |
+-----+--------------------------------+
1 row in set (0.00 sec)

同样,JSON_EXTRACT 也可以用于 where 子句,例如,想查寻 Tom 的地址:

mysql> SELECT JSON_EXTRACT(data,'$.address') 
        from UserJson 
        where JSON_EXTRACT(data,'$.name')='Tom';
        
+-----+--------------------------------+
| uid | JSON_EXTRACT(data,'$.address') |
+-----+--------------------------------+
|   3 | "Guangzhou ..."                |
+-----+--------------------------------+
1 row in set (0.00 sec)

EXTRACT 时,如果指定的列不存在,则返回 NULL。

使用了 JASON 后,如果想增加一个属性,就非常方便:

mysql> UPDATE UserJson
set data = json_insert(data,"$.address2","gaoxin")
where uid = 1;

这样一来, UID=1的记录里,data 字段就会多一个 "address2": "gaoxin"。

JSON创建索引

JSON 类型数据本身无法直接创建索引,需要将需要索引的JSON数据重新生成虚拟列(Virtual Columns)之后,对该列进行索引。

-- By 许望(RHCA、OCM、VCP)
最后修改:2020 年 01 月 03 日 02 : 19 PM
如果觉得我的文章对你有用,请随意赞赏