1. 概述
在这个教程中,我们将讨论 Apache Cassandra 数据库中的 frozen
关键字。首先,我们将展示如何声明冷冻集合或用户自定义类型(UDT)。接下来,我们将讨论使用示例以及它如何影响持久化存储的基本操作。
2. Cassandra 数据库配置
让我们使用 Docker 镜像创建一个数据库,并通过 cqlsh
连接到该数据库。然后,我们应该创建一个 键空间:
CREATE KEYSPACE mykeyspace WITH replication = {'class':'SimpleStrategy', 'replication_factor' : 1};
对于这个教程,我们创建了一个只有一份数据副本的 键空间。现在,让我们连接客户端会话到 键空间:
USE mykeyspace;
3. 冻结集合类型
一个类型为冷冻集合(如 set、map 或 list)的列只能整体替换其值。换句话说,我们不能像非冷冻集合类型那样添加、更新或删除集合中的单个元素。因此,frozen
关键字在我们想要保护集合免受单值更新时特别有用。
此外,由于冻结,我们可以将冷冻集合用作表的主键。我们可以通过使用集合类型(如 set、list 或 map)声明集合列,然后添加集合类型。
要声明一个冷冻集合,我们需要在集合定义之前添加关键字:
CREATE TABLE mykeyspace.users
(
id uuid PRIMARY KEY,
ip_numbers frozen<set<inet>>,
addresses frozen<map<text, tuple<text>>>,
emails frozen<list<varchar>>,
);
让我们插入一些数据:
INSERT INTO mykeyspace.users (id, ip_numbers)
VALUES (6ab09bec-e68e-48d9-a5f8-97e6fb4c9b47, {'10.10.11.1', '10.10.10.1', '10.10.12.1'});
重要的是,正如上面所述,冷冻集合只能整体替换。这意味着我们不能添加或删除元素。让我们尝试向 ip_numbers
集合中添加一个新的元素:
UPDATE mykeyspace.users
SET ip_numbers = ip_numbers + {'10.10.14.1'}
WHERE id = 6ab09bec-e68e-48d9-a5f8-97e6fb4c9b47;
执行更新后,我们将收到错误:
InvalidRequest: Error from server: code=2200 [Invalid query] message="Invalid operation (ip_numbers = ip_numbers + {'10.10.14.1'}) for frozen collection column ip_numbers"
如果我们想更新数据集中的数据,我们需要更新整个集合:
UPDATE mykeyspace.users
SET ip_numbers = {'11.10.11.1', '11.10.10.1', '11.10.12.1'}
WHERE id = 6ab09bec-e68e-48d9-a5f8-97e6fb4c9b47;
3.1. 嵌套集合
有时我们需要在 Cassandra 数据库中使用嵌套集合。只有标记为 frozen
的嵌套集合才是可能的,这意味着这个集合是不可变的。我们可以在冷冻和非冷冻集合中冻结嵌套集合。让我们看一个例子:
CREATE TABLE mykeyspace.users_score
(
id uuid PRIMARY KEY,
score set<frozen<set<int>>>
);
4. 冻结用户自定义类型
用户自定义类型(UDT)可以将多个命名和类型的字段附加到单个列上。创建用户自定义类型的字段可以是任何有效的数据类型,包括集合或其他 UDT。让我们创建我们的 UDT:
CREATE TYPE mykeyspace.address (
city text,
street text,
streetNo int,
zipcode text
);
让我们看看冷冻用户自定义类型的声明:
CREATE TABLE mykeyspace.building
(
id uuid PRIMARY KEY,
address frozen<address>
);
当我们对用户自定义类型使用 frozen
时,Cassandra 将其值视为一个blob。这个 blob 是通过将我们的 UDT 序列化为单个值获得的。所以,我们不能更新用户自定义类型值的一部分。我们必须覆盖整个值。
首先,让我们插入一些数据:
INSERT INTO mykeyspace.building (id, address)
VALUES (6ab09bec-e68e-48d9-a5f8-97e6fb4c9b48,
{city: 'City', street: 'Street', streetNo: 2,zipcode: '02-212'});
让我们看看当我们仅尝试更新一个字段时会发生什么:
UPDATE mykeyspace.building
SET address.city = 'City2'
WHERE id = 6ab09bec-e68e-48d9-a5f8-97e6fb4c9b48;
我们又会收到错误:
InvalidRequest: Error from server: code=2200 [Invalid query] message="Invalid operation (address.city = 'City2') for frozen UDT column address"
所以,让我们更新整个值:
UPDATE mykeyspace.building
SET address = {city : 'City2', street : 'Street2'}
WHERE id = 6ab09bec-e68e-48d9-a5f8-97e6fb4c9b48;
这次,地址将被更新。查询中未包含的字段将用 null
值完成。
5. 元组
与其他组合类型不同,元组始终是冷冻的。因此,我们不需要在元组上使用 frozen
关键字。因此,我们不能仅更新元组中的某些元素。就像冷冻集合或 UDT 一样,我们必须覆盖整个值。
6. 总结
在这篇简短的教程中,我们探讨了 Cassandra 数据库中冻结组件的基本概念。接着,我们创建了冷冻集合和用户自定义类型,并检查了这些数据结构的行为。然后,我们讨论了元组数据类型。如往常一样,文章的完整源代码可在 GitHub 上找到。