了解混合数据模型
关系型数据库存在的时间最长,使其成为全球开发者使用的最流行的数据模型。它将处理和存储数据的方式从用户那里抽象出来。
由于这个原因,开发人员发现在他们的应用程序中使用它是灵活和直接的。
然而,在现代社会中,应用程序更多的是数据密集型的,没有那么简单。应用程序在许多领域都发生了革命性的变化,如数据爆炸、社交网络、互联网、人工智能等等。
这导致应用程序要处理大量的非结构化数据,使得处理只处理固定的表格结构化数据的关系型数据库成为挑战。出于这个原因,开发人员选择了其他选择,如非关系型数据库,通常被称为NoSQL数据库。
每个NoSQL数据库都被设计用来处理关系型数据库失败的应用中的特定功能。
现代应用程序很难依赖一种类型的数据库,因为它可能无法完全满足应用程序的需求。因此,混合数据库模型经常被采用。
混合数据库模型包括包含在一个应用程序中的几个数据库。
混合模型中使用的数据库的选择取决于应用需求和规格。数据库的选择是由给定的数据库提供的优势和限制决定的。这意味着这些数据库必须相互补充。
在本指南中,我们将使用MariaDB提供的一些JSON功能来演示混合数据模型的概念。
前提条件
- 安装了[MariaDB]。
- 对[MariaDB]和[JSON]命令的了解。
- 对[关系型数据库]和[SQL命令]有清晰的认识。
如何对结构化和半结构化的数据进行建模
众所周知,MariaDB的核心是RDMS。然而,除此之外,它还提供了许多功能。它可以处理JavaScript Object Notation(JSON)格式的数据。JSON也被NoSQL数据库所支持。
现在,JSON与关系型数据库合作良好,使得创建结构化和半结构化的数据模型变得容易。现在,即使不包括关系型数据库提供的优势,应用程序也可以利用JSON提供的好处。
MariaDB和JSON都支持可以用来实现共同目标的功能。我们将使用一个假设的应用程序来介绍其中的一些功能。
我们将假设该应用程序只包含一个名为computers 的表,我们将用它来存储计算机的详细信息。我们将不关注前端,因为我们对数据库方面感兴趣。
Computers 表可以包含不同的字段,如: , , , 和 。同时,它可以包含不同的属性,可以用JSON格式定义,如下图所示。type brand price stock

创建表
我们首先使用以下SQL命令创建一个computers 表。
CREATE TABLE IF NOT EXISTS computers
( c_id INT(10) NOT NULL AUTO_INCREMENT,
type VARCHAR(25) NOT NULL,
brand VARCHAR(25) NOT NULL,
price DECIMAL(5,2) NOT NULL,
stock INT(10) NOT NULL,
properties JSON,
CONSTRAINT C_id_pk PRIMARY KEY (c_id)
);
注意,computers 表中的列properties 被定义为JSON数据类型。该列已被指定为JSON数据类型,但在真正意义上没有这样的数据类型。因此,它将被转换为MariaDB支持的现有数据类型。
我们可以通过运行这个命令来检查我们使用上面的命令所创建的细节。
SHOW CREATE TABLE computers;
将会显示以下结果。

从上面的图片来看,列properties 的数据类型已经分配给了LONGTEXT 。更多的约束已经被添加到字段中,特别是CHECK 约束,每当properties 列数据被更新或修改时,都会调用JSON_VALID() 函数。
JSON_VALID() 函数验证JSON数据,如下图所示。

插入数据
插入JSON数据很容易,因为它包含在引号中,只要字符串是有效的。我们将执行下面的语句来插入数据。
INSERT INTO computers (type, brand, price, stock, properties) VALUES
('Laptop', 'HP', 536.67, 288,
'{"details": {"RAM": "8GB", "Processor": "Core i3"},
"store": [{"location": "Nairobi", "Address": 1025},
{"location": "Mombasa", "Address": 152}]}');
需要注意的是,在同一个表中的同一插入语句中,有可能使用不同结构的JSON数据,如下图所示。
INSERT INTO computers (type, brand, price, stock, properties) VALUES
('Desktop', 'LENOVO', 602.25, 187,
'{"class": "PC", "PurchaseDate": "14/01/2022"}');
数据将被插入到表中;表将出现如下图所示。

查询JSON数据
在MariaDB中处理JSON数据时,我们使用预定义的函数来执行大多数操作。我们将在本文的最后使用这些函数。
查询标量数据
为了查询标量数据,我们使用函数JSON_VALUE() 。该函数从选择语句中指定的路径和数据中输出JSON数据。在我们的例子中,properties 列成为我们指定的数据。选择语句将显示如下。
SELECT brand, price, stock,
JSON_VALUE(properties, '$.details.RAM') AS Specs
FROM computers
WHERE type = 'Laptop';
根据最初插入到computers 表的数据,将显示以下结果。

函数JSON_VALUE() 可以处理构成半结构化数据一部分的空值和不存在的值。
查询对象数据
为了返回JSON数据,函数JSON_QUERY() 接受JSON数据和一个JSON路径。JSON_QUERY() 和JSON_VALUE() 之间的区别是,JSON_QUERY() 返回整个JSON对象数据。查询会像下面显示的那样。
SELECT brand, price,
JSON_QUERY(properties, '$.details') AS CPU
FROM computers
WHERE type = 'Laptop'
结果会出现如下图所示。

创建索引
我们能够创建增强性能的索引。但首先我们要在我们的表中创建一个虚拟列。
ALTER TABLE computers ADD COLUMN
CPU VARCHAR(50) AS (JSON_VALUE(properties, '$.details.Processor')) VIRTUAL;
然后我们将通过添加一个虚拟列来创建一个新的索引,使用。
CREATE INDEX CPu ON computers(CPU);
修改JSON数据
可能会有修改数据的需要。MariaDB提供了几个JSON函数来实现这个目的。在接下来的章节中,我们将介绍这些JSON函数中的一些。
插入JSON数据
在我们的properties 字段中插入JSON数据是使用JSON_INSERT() 函数进行的。这个函数确保值或路径被添加到现有的JSON数据中。语句会如下。
UPDATE computers
SET properties = JSON_INSERT(properties,'$.RamType','DDR3')
WHERE C_id = 1;
之后,运行以下SELECT 命令,在我们的表中显示JSON数据。
SELECT properties FROM computers WHERE TYPE='Laptop';
结果将如下。

在JSON中插入数组
我们可以使用函数JSON_ARRAY() ,在JSON数据中插入数组。例如在我们的案例中,我们可以在properties 字段中插入一个数组,如下图所示。
UPDATE computers
SET properties = JSON_INSERT(properties,
'$.Processor',
JSON_ARRAY('Core i5', 'Core i7'))
WHERE c_id = 1;
运行SELECT 命令后,结果将如下所示。

添加数组元素
为了修改一个已有的数组,我们使用JSON_ARRAY_APPEND() 函数向其中添加元素。
UPDATE computers
SET properties = JSON_ARRAY_APPEND(properties,
'$.Processor', “Core 2 Duo”)
WHERE c_id = 1;
最终,更新后的结果将如下图所示。

删除数组元素
我们可以使用JSON_REMOVE() 函数来删除JSON数据中的数组元素。
UPDATE computers
SET properties = JSON_REMOVE(properties,
'$.Processor[1]')
WHERE c_id = 1;
数组元素 "Core 2 Duo "将被从JSON数据中删除,如下图所示。

混合数据查询
可以利用函数JSON_OBJECT() ,从结构化数据中创建半结构化的JSON数据,如下面的语句所示。
SELECT
JSON_OBJECT('brand', brand, 'stock', stock) AS data
FROM computers
WHERE type = 'Laptop';
输出结果将如下。

合并数据
可以将现有的JSON数据与JSON对象函数返回的数据相结合。我们使用函数JSON_MERGE() 来达到这个目的。我们将使用下面的语句来合并数据。
SELECT
JSON_MERGE(
JSON_OBJECT(
'brand', brand,
'price', price,
'stock', stock),
properties) AS data
FROM computers
WHERE type = 'Laptop';
输出将出现如下图所示。
{
"brand": "HP",
"price": 536.67,
"stock": 288,
"details": {
"RAM": "8GB",
"Processor": "Core i3"
},
"store": [
{ "location": "Nairobi", "Address": 1025 },
{ "location": "Mombasa", "Address": 152 }
],
"RamType": "DDR3",
"Processor": ["Core i5", "Core i7"]
}
JSON到表格式数据
为了将JSON数据转换为表格格式,我们使用函数JSON_TABLE() 。这个函数也可以和FROM 子句一起使用,以连接其他表格。
SELECT brand, RAM, Processor
FROM
computers,
JSON_TABLE(properties,
'$.details' COLUMNS(
RAM VARCHAR(25) PATH '$.RAM',
Processor VARCHAR(25) PATH '$.Processor')
) AS jt
WHERE c_id = 1;
输出会出现如下图所示。

强制执行数据完整性
我们可以在MariaDB中对JSON数据施加数据完整性。这意味着我们可以对允许存在于我们表中的JSON类型进行约束。
在我们的案例中,我们可以创建一个新的约束,并将其命名为check_comps 。它规定JSON数据必须满足每个计算机类型的特定条件Laptop 。它通过使用MariaDB支持的JSON函数来检查一个指定的属性是否存在。
ALTER TABLE computers ADD CONSTRAINT check_comps
CHECK (
type = 'Laptop' and
JSON_TYPE(JSON_QUERY(properties, '$.details')) = 'OBJECT' and
JSON_TYPE(JSON_QUERY(properties, '$.store')) = 'ARRAY' and
JSON_EXISTS(properties, '$.details.RAM') = 1 and
JSON_EXISTS(properties, '$.details.Processor') = 1 and
JSON_LENGTH(JSON_QUERY(properties, '$.store')) > 0);
在我们对JSON数据执行了上述约束后,我们可以尝试再次运行INSERT 命令。
INSERT INTO computers (type, brand, price, stock, properties) VALUES
('Desktop', 'LENOVO', 602.25, 187,
'{"class": "PC", "PurchaseDate": "14/01/2022"}');
下面的错误信息将弹出,这意味着我们试图插入的数据已经违反了我们施加的约束。因此,该数据将不会被插入。

总结
从上面的活动中,我们可以得出结论,在使用MariaDB的同时,也可以使用JSON来利用这两个数据库的优势。我们只介绍了其中的几个功能,因为其中有很多功能存在。