Cassandra Frozen Keyword – 卡桑德拉 冻结关键词

最后修改: 2021年 10月 9日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this tutorial, we’ll be talking about the frozen keyword in the Apache Cassandra database. First, we’ll show how to declare the frozen collections or user-defined types (UDTs). Next, we’ll discuss examples of usage and how it affects the basic operations of persistent storage.

在本教程中,我们将讨论Apache Cassandra 数据库中的frozen关键字。首先,我们将展示如何声明冻结集合或用户定义的类型(UDT)接下来我们将讨论使用实例以及它如何影响持久性存储的基本操作。

2. Cassandra Database Configuration

2.卡桑德拉数据库配置

Let’s create a database using a docker image and connect it to the database using cqlsh. Next, we should create a keyspace:

让我们使用docker镜像创建一个数据库,并使用cqlsh连接到数据库。接下来,我们应该创建一个钥匙空间

CREATE KEYSPACE mykeyspace WITH replication = {'class':'SimpleStrategy', 'replication_factor' : 1};

For this tutorial, we created a keyspace with only one copy of the data. Now, let’s connect the client session to a keyspace:

在本教程中,我们创建了一个只有一份数据的钥匙空间。现在,让我们把客户会话连接到一个钥匙空间

USE mykeyspace;

3. Freezing Collection Types

3.冻结采集类型

A column whose type is a frozen collection (set, map, or list) can only have its value replaced as a whole. In other words, we can’t add, update, or delete individual elements from the collection as we can in non-frozen collection types. So, the frozen keyword can be useful, for example, when we want to protect collections against single-value updates.

类型为frozen集合(setmaplist)的列只能将其值作为一个整体来替换。换句话说,我们不能像在非冻结集合类型中那样从集合中添加、更新或删除单个元素。因此,frozen关键字可能很有用,例如,当我们想要保护集合免受单值更新时。

Moreover, thanks to freezing, we can use a frozen collection as the primary key in a table. We can declare collection columns by using collection types like set, list, or map. Then we add the type of collection.

此外,t由于冻结,我们可以使用一个冻结的集合作为表的主键。我们可以通过使用集合类型(如set, list, 或map)来声明集合列。然后我们添加集合的类型。

To declare a frozen collection, we have to add the keyword before the collection definition:

为了声明一个frozen集合,我们必须在集合定义前添加关键字。

CREATE TABLE mykeyspace.users
(
    id         uuid PRIMARY KEY,
    ip_numbers frozen<set<inet>>,
    addresses  frozen<map<text, tuple<text>>>,
    emails     frozen<list<varchar>>,
);

Let’s insert some data:

让我们插入一些数据。

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'});

Importantly, as we mentioned above, a frozen collection can be replaced only as a whole. This means that we can’t add or remove elements. Let’s try to add a new element to the ip_numbers set:

重要的是,正如我们上面提到的,一个frozen集合只能作为一个整体被替换。这意味着我们不能添加或删除元素。让我们试着给ip_numbers集合添加一个新元素。

UPDATE mykeyspace.users
SET ip_numbers = ip_numbers + {'10.10.14.1'}
WHERE id = 6ab09bec-e68e-48d9-a5f8-97e6fb4c9b47;

After executing the update, we’ll get the error:

执行更新后,我们会得到错误。

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"

If we want to update the data in our collection, we need to update the whole collection:

如果我们想更新我们集合中的数据,我们需要更新整个集合。

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. Nested Collections

3.1.嵌套集合

Sometimes we have to use nested collections in the Cassandra database. Nested collections are possible only if we mark them as frozen. This means that this collection will be immutable. We can freeze nested collections in both frozen and non-frozen collections. Let’s see an example:

有时我们必须在Cassandra数据库中使用嵌套的集合。只有当我们将其标记为frozen时,嵌套集合才有可能。这意味着这个集合将是不可改变的。我们可以在冻结非冻结集合中冻结嵌套集合。让我们看一个例子。

CREATE TABLE mykeyspace.users_score
(
    id    uuid PRIMARY KEY,
    score set<frozen<set<int>>>
);

4. Freezing User-Defined Type

4.冻结用户定义的类型

User-defined types (UDTs) can attach multiple data fields, each named and typed, to a single column. The fields that are used to create user-defined types may be any valid data type, including collection or other UDTs. Let’s create our UDT:

用户定义类型(UDT)可以将多个数据字段附加到一个列上,每个字段都是命名和类型的。用于创建用户定义类型的字段可以是任何有效的数据类型,包括集合或其他UDTs。让我们来创建我们的UDT。

CREATE TYPE mykeyspace.address (
    city text,
    street text,
    streetNo int,
    zipcode text
);

Let’s see the declaration of a frozen user-defined type:

让我们看看一个冻结的用户定义的类型的声明。

CREATE TABLE mykeyspace.building
(
    id      uuid PRIMARY KEY,
    address frozen<address>
);

When we use frozen on a user-defined type, Cassandra treats the value like a blob. This blob is obtained by serializing our UDT to a single value. So, we can’t update parts of a user-defined type value. We have to overwrite the entire value.

当我们在一个用户定义的类型上使用frozen时,Cassandra会把这个值当作一个blob。这个blob是通过将我们的UDT序列化为一个单一的值而获得的。所以,我们不能更新用户定义类型值的一部分。我们必须覆盖整个值。

Firstly, let’s insert some data:

首先,让我们插入一些数据。

INSERT INTO mykeyspace.building (id, address)
VALUES (6ab09bec-e68e-48d9-a5f8-97e6fb4c9b48,
  {city: 'City', street: 'Street', streetNo: 2,zipcode: '02-212'});

Let’s see what happen when we try to update only one field:

让我们看看当我们试图只更新一个字段时会发生什么。

UPDATE mykeyspace.building
SET address.city = 'City2'
WHERE id = 6ab09bec-e68e-48d9-a5f8-97e6fb4c9b48;

We’ll get the error again:

我们会再次得到错误。

InvalidRequest: Error from server: code=2200 [Invalid query] message="Invalid operation (address.city = 'City2') for frozen UDT column address"

So, let’s update the entire value:

因此,让我们更新整个价值。

UPDATE mykeyspace.building
SET address = {city : 'City2', street : 'Street2'}
WHERE id = 6ab09bec-e68e-48d9-a5f8-97e6fb4c9b48;

This time, the address will be updated. Fields not included in the query are completed with the null value.

这一次,地址将被更新。不包括在查询中的字段将以null值完成。

5. Tuples

5.图元

Unlike other composing types, a tuple is always frozen. Therefore, we don’t have to mark tuples with the frozen keyword. Consequently, it is not possible to update only some elements of a tuple. As is the case with frozen collections or UDTs, we have to overwrite the entire value.

与其他组成类型不同,元组总是被冻结的。因此,我们不需要用frozen关键字来标记元组。因此,不可能只更新一个元组的某些元素。与冻结的集合或UDT的情况一样,我们必须覆盖整个值。

6. Conclusion

6.结语

In this quick tutorial, we explored the basic concept of freezing components in the Cassandra database. Next, we created frozen collections and user-defined types. Then, we checked the behavior of these data structures. After that, we talked about the tuples data type. As always, the complete source code of the article is available over on GitHub.

在这个快速教程中,我们探讨了Cassandra数据库中冻结组件的基本概念。接下来,我们创建了冻结的集合和用户定义的类型。然后,我们检查了这些数据结构的行为。之后,我们谈到了tuples数据类型。一如既往,本文的完整源代码可在GitHub上查阅