ChatGPT解决这个技术问题 Extra ChatGPT

Cassandra中分区键,复合键和集群键之间的区别?

我一直在网上阅读文章以了解以下 key 类型之间的区别。但这对我来说似乎很难掌握。示例肯定有助于更好地理解。

primary key,
partition key, 
composite key 
clustering key
我发现 this article 包含围绕这些概念的许多详细解释。
This article 还清楚地指出了这些术语。
您在上面分享的@duong_dajgja URL 已损坏,您能否使用有效/有用的 URL 编辑评论?
@realPK 链接不知何故消失了。但我在这里为您找到了另一个链接 quora.com/…

F
Federico Navarrete

对此有很多困惑,我将尝试使其尽可能简单。

主键是一个通用概念,表示用于从表中检索数据的一个或多个列。

主键可能很简单,甚至可以内联声明:

 create table stackoverflow_simple (
      key text PRIMARY KEY,
      data text      
  );

这意味着它是由单列组成的。

但主键也可以是 COMPOSITE(又名 COMPOUND),由更多列生成。

 create table stackoverflow_composite (
      key_part_one text,
      key_part_two int,
      data text,
      PRIMARY KEY(key_part_one, key_part_two)      
  );

在 COMPOSITE 主键的情况下,键的“第一部分”称为 PARTITION KEY(在本例中 key_part_one 是分区键),键的第二部分是 CLUSTERING KEY(在本例中为 key_part_two)

请注意,分区键和集群键都可以由更多列组成,方法如下:

 create table stackoverflow_multiple (
      k_part_one text,
      k_part_two int,
      k_clust_one text,
      k_clust_two int,
      k_clust_three uuid,
      data text,
      PRIMARY KEY((k_part_one, k_part_two), k_clust_one, k_clust_two, k_clust_three)      
  );

这些名字的背后...

分区键负责跨节点分发数据。

Clustering Key 负责分区内的数据排序。

主键相当于单字段键表中的分区键(即简单)。

复合/复合键只是任何多列键

更多使用信息:DATASTAX DOCUMENTATION

insert into stackoverflow_simple (key, data) VALUES ('han', 'solo');
select * from stackoverflow_simple where key='han';

表格内容

key | data
----+------
han | solo

COMPOSITE/COMPOUND KEY 可以检索“宽行”(即您可以仅通过分区键查询,即使您定义了集群键)

insert into stackoverflow_composite (key_part_one, key_part_two, data) VALUES ('ronaldo', 9, 'football player');
insert into stackoverflow_composite (key_part_one, key_part_two, data) VALUES ('ronaldo', 10, 'ex-football player');
select * from stackoverflow_composite where key_part_one = 'ronaldo';

表格内容

 key_part_one | key_part_two | data
--------------+--------------+--------------------
      ronaldo |            9 |    football player
      ronaldo |           10 | ex-football player

但是您可以使用所有键(分区和集群)进行查询...

select * from stackoverflow_composite 
   where key_part_one = 'ronaldo' and key_part_two  = 10;

查询输出

 key_part_one | key_part_two | data
--------------+--------------+--------------------
      ronaldo |           10 | ex-football player

重要提示:分区键是使用 where clause 执行查询所需的最小说明符。如果您有复合分区键,如下所示

例如:PRIMARY KEY((col1, col2), col10, col4))

您只能通过至少传递 col1 和 col2 来执行查询,这是定义分区键的 2 列。进行查询的“一般”规则是您必须至少传递所有分区键列,然后您可以选择按照设置的顺序添加每个集群键。

所以,有效的查询是(不包括二级索引)

col1 和 col2

col1 和 col2 和 col10

col1 和 col2 和 col10 和 col 4

无效的:

col1 和 col2 和 col4

不包含 col1 和 col2 的任何内容


@brain Storm:对于可能做的事情,我添加了一些信息和使用示例。在单个帖子中表示数据并不容易
创建二级索引: CREATE INDEX myindex ON mytable(acolumn);
正如我所写 -- <<进行查询的“一般”规则是您必须至少传递所有分区键列,然后您可以按照设置的顺序添加每个键。>> -- 因为之前定义了 col10 col4 你必须将它传递给查询 col4
您可以添加二级索引,但这并不意味着您可以执行“任何”cql 查询——以及更多:在创建二级索引之前,您应该数到 10 ... 000 ..... :)
二级索引被实现为本地索引——它们不分布在集群中。集群的每个节点都负责存储它所拥有的数据的二级索引。因此,对 sec.index 的查询可能涉及集群中的所有节点
O
OrangeDog

添加一个摘要答案作为接受的答案很长。术语“行”和“列”在 CQL 的上下文中使用,而不是 Cassandra 的实际实现方式。

主键唯一标识一行。

复合键是由多列组成的键。

分区键是查找一组行(即分区)的主要查找。

集群键是主键中不是分区键的部分(并且定义了分区内的顺序)。

例子:

PRIMARY KEY (a):分区键是 a。

PRIMARY KEY (a, b):分区键是a,集群键是b。

PRIMARY KEY ((a, b)):复合分区键是(a, b)。

PRIMARY KEY (a, b, c):分区键为a,复合聚类键为(b, c)。

PRIMARY KEY ((a, b), c):复合分区键为(a, b),聚类键为c。

PRIMARY KEY ((a, b), c, d):复合分区键为(a, b),复合聚类键为(c, d)。


这实际上回答了我一段时间以来的一个查询,你如何定义没有集群键的复合分区键(多列),诀窍是使用双括号! PRIMARY KEY ((a, b))
F
Federico Navarrete

在 Cassandra 中,主键、分区键、复合键、集群键之间的区别总是让人有些困惑。所以,我将在下面解释并相互关联。我们使用 CQL(Cassandra 查询语言)来访问 Cassandra 数据库。注意: - 答案是根据 Cassandra 的更新版本。

主键: - 在 Cassandra 中有 2 种不同的方式来使用主键。

CREATE TABLE Cass (
    id int PRIMARY KEY,
    name text 
);

Create Table Cass (
   id int,
   name text,
   PRIMARY KEY(id) 
);

在 CQL 中,为 PRIMARY KEY 定义列的顺序很重要。键的第一列称为分区键,具有共享相同分区键的所有行(实际上甚至跨表)都存储在同一物理节点上的属性。此外,对给定表共享相同分区键的行的插入/更新/删除是原子地和隔离地执行的。请注意,可以使用复合分区键,即由多个列组成的分区键,使用一组额外的括号来定义哪些列形成分区键。

分区和集群 PRIMARY KEY 定义由两部分组成:分区键和集群列。第一部分映射到存储引擎行键,而第二部分用于对一行中的列进行分组。

CREATE TABLE device_check (
  device_id   int,
  checked_at  timestamp,
  is_power    boolean,
  is_locked   boolean,
  PRIMARY KEY (device_id, checked_at)
);

这里 device_id 是分区键,checked_at 是 cluster_key。

我们也可以有多个集群键以及分区键,这取决于声明。


您本可以对您的消息来源(2013 年 = 比您的帖子更早)表示赞赏:thelastpickle.com/blog/2013/01/11/primary-keys-in-cql.html
F
Federico Navarrete

主键:由分区键[和可选的集群键(或列)]组成分区键:分区键的哈希值用于确定集群中的特定节点来存储数据

Clustering Key:用于对每个分区(或负责节点及其副本)中的数据进行排序

复合主键:如上所述,集群键在主键中是可选的。如果没有提到它们,它就是一个简单的主键。如果提到集群键,它是一个复合主键。

复合分区键:仅使用一列作为分区键,可能会导致宽行问题(取决于用例/数据建模)。因此,有时将分区键指定为多个列的组合。

关于在查询中混淆哪个是强制性的,哪个可以跳过等等,试图将 Cassandra 想象成一个巨大的 HashMap 会有所帮助。因此,在 HashMap 中,您无法在没有 Key 的情况下检索值。

在这里,分区键扮演该键的角色。因此,每个查询都需要指定它们。没有它,Cassandra 将不知道要搜索哪个节点。

在 Cassandra 找到负责该特定分区键的特定节点(及其副本)后,集群键(列,可选)有助于进一步缩小查询搜索范围。


F
Federico Navarrete

简而言之:

分区键不过是对一行的标识,该标识大多数时候是单列(称为主键),有时是多列的组合(称为复合分区键)。

集群键不过是索引和排序。集群键取决于几件事:

除了主键列之外,您在 where 子句中使用了哪些列。如果您有非常大的记录,那么我可以划分日期以便于管理。例如,我有一个县的 100 万人口记录的数据。所以,为了便于管理,我根据状态和密码等对数据进行聚类。


分区键不是 A 行的标识...它标识了一堆行,所有这些行都具有相同的分区键
@wmac,如果没有集群键并且只有一个分区键,那么不是该行的分区键标识吗?
k
kboom

值得注意的是,您可能会比关系世界中的类似概念(复合键)更多地使用这些。

示例 - 假设您必须找到最近加入用户组 X 的最后 N 个用户。如果在这种情况下读取占主导地位,您将如何有效地执行此操作?像这样(来自官方 Cassandra guide):

CREATE TABLE group_join_dates (
    groupname text,
    joined timeuuid,
    join_date text,
    username text,
    email text,
    age int,
    PRIMARY KEY ((groupname, join_date), joined)
) WITH CLUSTERING ORDER BY (joined DESC)

在这里,分区键本身是复合键,而集群键是连接日期。聚类键是连接日期的原因是结果已经排序(并存储,这使得查找速度更快)。但是为什么我们使用复合键来分区键呢?因为我们总是希望读取尽可能少的分区。把 join_date 放在那里有什么帮助?现在来自同一组和相同加入日期的用户将驻留在一个分区中!这意味着我们将始终尽可能少地读取分区(首先从最新的分区开始,然后移动到较旧的分区等等,而不是在它们之间跳转)。

事实上,在极端情况下,您还需要使用 join_date 的散列而不是单独使用 join_date - 这样,如果您查询过去 3 天,通常它们共享相同的散列,因此可以从同一个分区获得!


E
Ejaz Ahmed

免责声明:这是特定于 DynamoDB 的答案,但是这些概念也适用于 Cassandra,因为两者都是 NoSQL 数据库。

创建表时,除了表名外,还必须指定表的主键。主键唯一标识表中的每个项目,因此没有两个项目可以具有相同的键。

DynamoDB 支持两种不同类型的主键:

分区键 – 一个简单的主键,由一个称为分区键的属性组成。

DynamoDB 使用分区键的值作为内部散列函数的输入。哈希函数的输出决定了存储项目的分区(DynamoDB 内部的物理存储)。

在只有一个分区键的表中,没有两个项目可以具有相同的分区键值。

分区键和排序键——称为复合主键,这种类型的键由两个属性组成。第一个属性是分区键,第二个属性是排序键。

DynamoDB 使用分区键值作为内部散列函数的输入。哈希函数的输出决定了存储项目的分区(DynamoDB 内部的物理存储)。具有相同分区键值的所有项目存储在一起,按排序键值排序。

在具有分区键和排序键的表中,两个项目可能具有相同的分区键值。但是,这两个项目必须具有不同的排序键值。

复合主键在查询数据时为您提供了额外的灵活性。例如,如果您只提供 Artist 的值,DynamoDB 会检索该艺术家的所有歌曲。要仅检索特定艺术家的歌曲子集,您可以为 Artist 提供一个值以及 SongTitle 的一系列值。

注意:项目的分区键也称为其哈希属性。术语哈希属性源自 DynamoDB 中使用内部哈希函数,该函数根据分区键值将数据项均匀分布在分区之间。

项目的排序键也称为其范围属性。术语范围属性源自 DynamoDB 存储具有相同分区键的项目的方式,这些项目物理上靠得很近,按排序键值排序。

参考 - https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.PrimaryKey