Cassandra 文档

版本

您正在查看预发布版本的文档。

CREATE CUSTOM INDEX

Cassandra 5.0 是目前唯一支持的数据库。

创建存储附加索引 (SAI) 索引。您可以在同一个数据库表上创建多个辅助索引,每个 SAI 索引基于表中的任何列。除以下列外,所有列数据类型都支持 SAI 索引

  • 计数器

  • 地理空间类型:PointTypeLineStringTypePolygonType

  • 非冻结用户定义类型 (UDT)

一个例外

当分区键仅包含一列时,您无法定义基于分区键的 SAI 索引。如果您尝试在这种情况下创建 SAI 索引,SAI 会发出错误消息。

但是,您可以定义表复合分区键中的一列的 SAI 索引,即包含多列的分区键。如果您需要根据这些列之一进行查询,SAI 索引是一个有用的选择。实际上,如果需要,您可以在复合分区键中的每一列上定义 SAI 索引。

在数据库表中的任何列上定义一个或多个 SAI 索引(遵循上述规则)随后使您能够运行使用索引列过滤结果的性能良好的查询。

请参阅 SAI 部分

概要

CREATE [CUSTOM] INDEX [ IF NOT EXISTS ] [ <index_name> ]
  ON [ <keyspace_name>.]<table_name> (<column_name>)
    | [ (KEYS(<map_name>)) ]
    | [ (VALUES(<map_name>)) ]
    | [ (ENTRIES(<map_name>)) ]
  USING 'sai'
  [ WITH OPTIONS = { <option_map> } ] ;
语法图例
图例
语法约定 描述

大写

文字关键字。

小写

非文字。

< >

变量值。用用户定义的值替换。

[]

可选。方括号 ([]) 围绕可选命令参数。不要输入方括号。

( )

组。圆括号 ( ( ) ) 标识要从中选择的组。不要输入圆括号。

|

或。竖线 (|) 分隔备选元素。键入任何一个元素。不要输入竖线。

...

可重复。省略号 ( ... ) 表示您可以根据需要重复语法元素。

'<文字字符串>'

单引号 (') 必须围绕 CQL 语句中的文字字符串。使用单引号保留大写。

{ <键> : <值> }

映射集合。大括号 ({ }) 包含映射集合或键值对。冒号分隔键和值。

<数据类型2

集合、列表、映射或元组。尖括号 ( < > ) 包含集合、列表、映射或元组中的数据类型。用逗号分隔数据类型。

<cql_语句>;

结束 CQL 语句。分号 (;) 终止所有 CQL 语句。

[--]

用两个连字符 ( -- ) 分隔命令行选项和命令参数。当参数可能被误认为命令行选项时,此语法很有用。

' <<schema\> ... </schema\>> '

仅搜索 CQL:单引号 (') 围绕整个 XML 模式声明。

@<xml_实体>='<xml_实体类型>'

仅搜索 CQL:标识实体和文字值以覆盖模式和 solrConfig 文件中的 XML 元素。

index_name

索引的可选标识符。如果没有指定名称,则使用默认名称,即 <table_name>_<column_name>_idx。用引号括起来以使用特殊字符或保留大写。

column_name

正在定义 SAI 索引的表列的名称。SAI 仅允许名称中包含字母数字字符和下划线。如果您尝试在包含其他字符的列名上定义索引,SAI 会返回 InvalidRequestException,并且不会创建索引。

map_name

集合 一起使用,在 CREATE TABLE …​ map(<map_name>) 中指定的 map_name 的标识符。集合类型 listset 适用常规列语法。

option_map

以 JSON 简单格式定义选项。

选项 描述

case_sensitive

忽略匹配字符串值的大小写。默认值:true

normalize

当设置为 true 时,对索引字符串执行 Unicode 规范化。SAI 支持规范化形式 C (NFC) Unicode。当设置为 true 时,SAI 会将给定 Unicode 字符的不同版本规范化为单个版本,保留索引中的所有标记和符号。例如,SAI 会将字符 Å (U+212B) 更改为 Å (U+00C5)。

当实现将字符串保留在规范化形式中时,等效字符串具有唯一的二进制表示形式。请参阅 Unicode 标准附件 #15,Unicode 规范化形式

默认值:false

ascii

当设置为 true 时,SAI 会将不在基本拉丁 Unicode 块(前 127 个 ASCII 字符)中的字母、数字和符号字符转换为 ASCII 等效字符(如果存在)。例如,此选项会将 à 更改为 a。默认值:false

查询运算符

SAI 支持以下查询运算符,用于具有 SAI 索引的表

  • 数字:=<>>=ANDORIN

  • 字符串:=CONTAINSCONTAINS KEYANDORIN

SAI 不支持以下查询运算符,用于具有 SAI 索引的表

  • 字符串或数字:LIKE

示例

这些示例为 cycling.cyclist_semi_pro 表定义 SAI 索引,该表在 SAI 快速入门 中进行了演示。

CREATE INDEX lastname_sai_idx ON cycling.cyclist_semi_pro (lastname)
USING 'sai'
WITH OPTIONS = {'case_sensitive': 'false', 'normalize': 'true', 'ascii': 'true'};

CREATE INDEX age_sai_idx ON cycling.cyclist_semi_pro (age)
USING 'sai';

CREATE INDEX country_sai_idx ON cycling.cyclist_semi_pro (country)
USING 'sai'
WITH OPTIONS = {'case_sensitive': 'false', 'normalize': 'true', 'ascii': 'true'};

CREATE INDEX registration_sai_idx ON cycling.cyclist_semi_pro (registration)
USING 'sai';

有关通过这些示例 SAI 索引在 cycling.cyclist_semi_pro 中查找数据的示例查询,请参阅 提交 CQL 查询。另请参阅 检查 SAI 列索引和查询规则

具有键、值和条目的 SAI 集合映射示例

以下示例演示了在 SAI 索引中使用多种类型(keysvaluesentries)的集合映射。有关相关信息,请参阅 创建集合使用映射类型

另请参阅本主题中类型为 列表和集合 的 SAI 集合示例。

首先,创建键空间

CREATE KEYSPACE demo3 WITH REPLICATION =
       {'class': 'SimpleStrategy', 'replication_factor': '1'};

接下来,使用键空间

USE demo3;

创建一个名为 text_map 的集合映射的 audit

CREATE TABLE audit ( id int PRIMARY KEY , text_map map<text, text>);

在同一个 map 列上创建多个 SAI 索引,每个索引都使用 KEYSVALUESENTRIES

在 **同一列** 上创建具有不同映射类型的多个 SAI 索引需要 Cassandra 5.0 或更高版本。

CREATE INDEX ON audit (KEYS(text_map)) USING 'sai';
CREATE INDEX ON audit (VALUES(text_map)) USING 'sai';
CREATE INDEX ON audit (ENTRIES(text_map)) USING 'sai';

插入一些数据

INSERT INTO audit (id, text_map) values (1, {'Carlos':'Perotti', 'Marcel':'Silva'});
INSERT INTO audit (id, text_map) values (2, {'Giovani':'Pasi', 'Frances':'Giardello'});
INSERT INTO audit (id, text_map) values (3, {'Mark':'Pastore', 'Irene':'Cantona'});

查询所有数据

  • 查询

  • 结果

SELECT * FROM audit;
 id | text_map
----+---------------------------------------------
  1 | {'Carlos': 'Perotti', 'Marcel': 'Silva'}
  2 | {'Frances': 'Giardello', 'Giovani': 'Pasi'}
  3 | {'Irene': 'Cantona', 'Mark': 'Pastore'}

(3 rows)

使用 SAI 索引查询 map 列中的特定条目

  • 查询

  • 结果

SELECT * FROM audit WHERE text_map['Irene'] = 'Cantona' AND text_map['Mark'] = 'Pastore';
 id | text_map
----+-----------------------------------------
  3 | {'Irene': 'Cantona', 'Mark': 'Pastore'}

(1 rows)

使用 SAI 索引查询 map 列中特定键,使用 CONTAINS KEY

  • 查询

  • 结果

SELECT * FROM audit WHERE text_map CONTAINS KEY 'Giovani';
 id | text_map
----+---------------------------------------------
  2 | {'Frances': 'Giardello', 'Giovani': 'Pasi'}

(1 rows)

使用 SAI 索引查询 map 列中特定值,使用 CONTAINS

  • 查询

  • 结果

SELECT * FROM audit WHERE text_map CONTAINS 'Silva';
 id | text_map
----+------------------------------------------
  1 | {'Carlos': 'Perotti', 'Marcel': 'Silva'}

(1 rows)

请记住,在使用 SAI 索引的 CQL 查询中,CONTAINS 子句支持并特定于

  • SAI 集合映射,包含 keysvaluesentries

  • SAI 集合,包含 listset 类型

SAI 集合示例,包含列表和集合类型

这些示例演示了在 SAI 索引中使用 listset 类型的集合。有关相关信息,请参阅

CREATE KEYSPACE IF NOT EXISTS demo3 WITH REPLICATION =
       {'class': 'SimpleStrategy', 'replication_factor': '1'};
USE demo3;

使用列表类型

创建一个 calendar 表,其中包含一个 list 类型的集合。

CREATE TABLE calendar (key int PRIMARY KEY, years list<int>);

使用集合的 years 列创建一个 SAI 索引。

CREATE INDEX ON calendar(years) USING 'sai';

插入一些随机的 int 列表数据到 years 中,仅用于演示目的。

请注意 INSERT 命令中用于列表值的方括号语法。

INSERT INTO calendar (key, years) VALUES (0, [1990,1996]);
INSERT INTO calendar (key, years) VALUES (1, [2000,2010]);
INSERT INTO calendar (key, years) VALUES (2, [2001,1990]);

使用 CONTAINS 的查询示例

  • 查询

  • 结果

SELECT * FROM calendar WHERE years CONTAINS 1990;
 key | years
-----+--------------
   0 | [1990, 1996]
   2 | [2001, 1990]
(2 rows)

此示例创建了 calendar 表,其中包含 years list<int>。当然,您可以创建 years list<text> 表,例如,插入 'string' 值,并根据字符串进行查询。

使用集合类型

现在创建一个 calendar2 表,其中包含一个 set 类型的集合。

CREATE TABLE calendar2 (key int PRIMARY KEY, years set<int>);

使用集合的 years 列创建一个 SAI 索引,这次是针对 calendar2 表。

CREATE INDEX ON calendar2(years) USING 'sai';

插入一些随机的 int 集合数据到 years 中,同样仅用于演示目的。

请注意 INSERT 命令中用于集合值的波浪号语法。

INSERT INTO calendar2 (key, years) VALUES (0, {1990,1996});
INSERT INTO calendar2 (key, years) VALUES (1, {2000,2010});
INSERT INTO calendar2 (key, years) VALUES (2, {2001,1990,2020});

从列表中使用 CONTAINS 的查询示例

  • 查询

  • 结果

SELECT * FROM calendar2  WHERE years CONTAINS 1990;
 key | years
-----+--------------------
   0 |       {1990, 1996}
   2 | {1990, 2001, 2020}

(2 rows)