Cassandra中分区键、组合键和聚类键的区别?

我一直在网上阅读文章,以了解以下key类型之间的差异。但我似乎很难理解。举例肯定有助于更好地理解。

primary key,
partition key,
composite key
clustering key
263981 次浏览

关于这一点有很多困惑,我会尽量让它简单一些。

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

主键可以是简单<强> < / >强,甚至可以声明为内联:

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

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

但是主键也可以是< >强复合< / >强(又名< >强复合< / >强),由更多列生成。

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

< >强复合< / >强主键的情况下,“第一部分”;该键的第一部分被称为< >强分区键< / >强(在本例中key_part_one是分区键),该键的第二部分是< >强集群关键< / >强(在本例中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)
);

在这些名字背后…

  • 分区键负责跨节点的数据分布。
  • 聚类的关键负责分区内的数据排序。
  • 主键相当于单字段键表中的分区键(即简单的)。
  • 复合材料/复合键是任意多列键

进一步的使用信息:DATASTAX文档


小用法和内容示例
* * * * * *简单的关键:
insert into stackoverflow_simple (key, data) VALUES ('han', 'solo');
select * from stackoverflow_simple where key='han';

表内容

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

< >强复合/复合键< / >强可以检索“宽行”;(也就是说,你可以通过分区键来查询,即使你已经定义了集群键)

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执行查询所需的最小说明符。 如果您有一个组合分区键,如下所示

如:# EYZ0

你可以通过至少传递col1和col2来执行查询,这是定义分区键的两列。“general"进行查询的规则是必须至少传递所有分区键列,然后可以按照设置的顺序随意添加每个集群键。

因此,有效的查询是(不包括二级指标)

  • Col1和col2
  • Col1 col2 col10
  • Col1 col2 col10 col4

无效:

  • Col1 col2 col4
  • 任何不同时包含col1和col2的元素
在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定义列的顺序很重要。键的第一列称为分区键,其属性是共享相同分区键的所有行(甚至跨表)都存储在相同的物理节点上。此外,对于给定表,对共享相同分区键的行插入/更新/删除是原子地和隔离地执行的。注意,可以有一个组合分区键,即由多列组成的分区键,使用一组额外的括号来定义哪些列构成分区键。

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

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。

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

由于已接受的答案相当长,所以添加一个摘要答案。术语“行”和“列”是在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)

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

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

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

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

关于哪一个是强制的混淆,在查询中可以跳过,尝试使用想象Cassandra是一个巨大的HashMap会有所帮助。在HashMap中,你不能在没有Key的情况下检索值。

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

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

简而言之:

分区键只是一行的识别,大多数情况下标识是单列(称为主键),有时是多个列的组合(称为组合分区键)。

集群的关键只是索引 &# EYZ2。集群键依赖于以下几点:

  1. where子句中除了主键列外还使用哪些列。

  2. 如果你有非常大的记录,那么关于什么问题,我可以划分日期,以便管理。例如,我有一个县100万的人口记录数据。因此,为了便于管理,我基于状态和pincode之后对数据进行了聚类。

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

示例-假设您必须找到最近加入用户组x的最后N个用户,在这种情况下,如果读取占优势,您将如何有效地完成此工作?就像这样(来自官方卡桑德拉指南):

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)

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

事实上,在极端情况下,您还需要使用join_date的散列,而不是单独使用join_date—这样,如果您查询最近3天的数据,这些散列通常共享相同的散列,因此可以从同一个分区使用!

这个答案是特定于DynamoDB的,但是这个概念也适用于Cassandra,因为两者都是NoSQL数据库。

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

DynamoDB支持两种不同的主键:

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

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

在只有一个分区键的表中,不能有两个项具有相同的分区键值。

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

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

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

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

项目的分区键也称为它的哈希值 属性。术语哈希属性派生自内部 在DynamoDB中均匀分布数据项的哈希函数 分区,基于它们的分区键值

项目的排序关键字也称为它的范围属性。术语range属性来源于DynamoDB将具有相同分区键的项物理地存储在一起的方式,按排序键值排序。

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