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

n53p2ov0  于 2023-01-13  发布在  Cassandra
关注(0)|答案(8)|浏览(167)

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

primary key,
partition key, 
composite key 
clustering key
d6kp6zgx

d6kp6zgx1#

有很多混乱围绕这一点,我会尽量使它尽可能简单。
主键是一个一般概念,它指示用于从表中检索数据的一个或多个列。
主键可以是***SIMPLE***,甚至可以内联声明:

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

这意味着它是由一根柱子构成的。
但是主键也可以是从多个列生成的***COMPOSITE***(aka***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)      
  );

在这些名字背后...

      • 分区键**负责跨节点分发数据。
      • 群集键**负责分区内的数据排序。
      • 主键等效于单字段键表(即简单**)中的分区键
  • 组合键**就是任何多列键

更多使用信息: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来执行查询,这两个列定义了分区键。进行查询的"一般"规则是您必须至少传递所有分区键列,然后您可以选择性地按照设置的顺序添加每个聚类键。
因此,有效查询为(不包括辅助索引

  • 列1和列2
  • 列1、列2和列10
  • 列1、列2、列10和列4

无效:

  • 列1列2列4
  • 不同时包含col1和col2的任何值
bnl4lu3b

bnl4lu3b2#

添加一个摘要答案作为可接受的答案是相当长的。术语"行"和"列"是在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)
zbwhf8kr

zbwhf8kr3#

在Cassandra中,主键、分区键、组合键、聚类键的区别经常会造成一些混淆。因此,我将在下面进行解释并相互关联。我们使用CQL(Cassandra查询语言)进行Cassandra数据库访问。注意:- 答案是根据更新版本的 cassandra 。

    • 主键:-**在Cassandra中有两种不同的方法来使用主键。
CREATE TABLE Cass (
    id int PRIMARY KEY,
    name text 
);
Create Table Cass (
   id int,
   name text,
   PRIMARY KEY(id) 
);

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

    • 分区和群集**PRIMARY KEY定义由两部分组成:分区键和聚类列。第一部分Map到存储引擎行键,而第二部分用于将列分组到行中。
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是群集键。
我们可以有多个簇键以及分区键,这取决于声明。

mbjcgjjk

mbjcgjjk4#

主键:由分区键[和可选的群集键(或列)]组成
分区密钥:分区键的哈希值用于确定群集中存储数据的特定节点
群集关键字:用于对每个分区(或负责节点及其副本)中的数据进行排序
复合主键:如前所述,聚簇键在主键中是可选的。如果没有提到聚簇键,则它是简单主键。如果提到聚簇键,则它是复合主键。
组合分区密钥:仅使用一列作为分区键可能会导致宽行问题(取决于用例/数据建模)。因此,分区键有时被指定为多列的组合。
关于在查询中哪个是强制的,哪个可以跳过等等的混淆,尝试***将Cassandra想象成一个巨大的HashMap***会有所帮助。因此,在HashMap中,没有Key就无法检索值。

在这里,分区键扮演了那个键的角色。所以,每个查询都需要指定它们。没有它们,Cassandra就不知道要搜索哪个节点。

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

q3qa4bjr

q3qa4bjr5#

简而言之:

分区键只是行的标识,该标识大多数情况下是单个列(称为主键),有时是多个列的组合(称为复合分区键)。
簇关键字只是索引&排序。簇关键字依赖于以下几个方面:

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

gdx19jrr

gdx19jrr6#

值得注意的是,与关系世界中的类似概念(组合键)相比,您可能会更多地使用这些概念。
示例-假设您必须查找最近加入用户组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天,这些数据通常共享相同的散列,因此可以从同一分区获得!

f1tvaqid

f1tvaqid7#

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

创建表时,除表名外,还必须指定表的主键。主键唯一标识表中的每一项,因此任何两项都不能具有相同的键。
DynamoDB支持两种不同类型的主键:

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

DynamoDB使用分区键的值作为内部哈希函数的输入。哈希函数的输出确定将存储项的分区(DynamoDB内部的物理存储)。
在只有一个分区键的表中,任何两个项都不能具有相同的分区键值。

分区关键字和排序关键字-此类型的关键字称为组合主键,由两个属性组成。第一个属性是分区关键字,第二个属性是排序关键字。

DynamoDB使用分区键值作为内部哈希函数的输入。哈希函数的输出确定将存储项的分区(DynamoDB内部的物理存储)。具有相同分区键值的所有项将按排序键值的排序顺序存储在一起。
在具有分区键和排序键的表中,两个项可以具有相同的分区键值,但是这两个项必须具有不同的排序键值。

复合主键在查询数据时为您提供了额外的灵活性。例如,如果只提供Artist的值,DynamoDB将检索该艺术家的所有歌曲。要只检索特定艺术家的歌曲子集,可以提供Artist的值沿着SongTitle的值范围。
**注意:**项的分区键也称为其散列属性。术语散列属性源于DynamoDB中内部散列函数的使用,该函数基于数据项的分区键值在分区之间均匀分布数据项。

项的排序键也称为其range属性。术语range属性源于DynamoDB存储具有相同分区键的项的方式,这些项在物理上靠得很近,按排序键值排序。
参考资料-https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.PrimaryKey

2mbi3lxu

2mbi3lxu8#

主键:像在许多数据库中一样,它是表中的唯一键,本质上它意味着,对于表中的任何两个记录,主键不能相同。数据库,在这种情况下,Cassandra的设计是为了确保这个条件在所有情况下都是真的。因此,如果你试图写一个记录,PK1作为主键,如果已经有一个记录具有相同的键PK1,它将被覆盖。否则将创建新记录。
分区密钥:它是一种分布式数据库结构(其中单个表的数据被划分为多个部分,称为分区)。然后,使用分布策略将分区分布到节点之间(通常是分区键的散列)来获得无限的伸缩能力。话虽如此,分区键是记录的一组列,它决定了该记录将属于哪个分区。因此,分区键决定记录在分布式节点群集上的物理位置。
聚类键:聚簇关键字决定记录在特定分区中的顺序。因此,如果分区中有10K条记录,聚簇关键字将决定这10K条记录以排序方式进行物理存储的顺序。
示例:
假设您在Cassandra有一个表,用于存储电子商务网站的销售事件。

[order_id, item_id, quantity, amount, payment_id, status, order_time, PRIMARY KEY( (order_id, item_id), order_time)] with clustering ORDER BY (order_time DESC);

所以在这里
主键是((order_id, item_id), order_time),它将决定表中记录的唯一性。
Partition Key为(order_id, item_id),该元组的哈希将决定该记录的分区及其在分布式集群上的位置。
集群关键字是order_time,对于特定分区,记录将按order_time降序排序。因此,如果您对特定分区执行Limit 1 cql查询,您将始终获得具有最大时间戳的记录。
复合键只是一个术语,用来说明表的主键不是单列,而是多列。
主键是分区键和聚类键的组合。

相关问题