【问题标题】:Difference between partition key, composite key and clustering key in Cassandra?Cassandra中分区键,复合键和集群键之间的区别?
【发布时间】:2014-09-16 22:49:15
【问题描述】:

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

primary key,
partition key, 
composite key 
clustering key

【问题讨论】:

  • 我找到了this article,其中包含许多关于这些概念的详细解释。
  • This article 也明确指出了这些术语。
  • @duong_dajgja 以上您分享的 URL 已损坏,您能否使用有效/有用的 URL 编辑评论?
  • @realPK 链接不知何故消失了。但我在这里为您找到了另一个链接quora.com/…

标签: database cassandra cql


【解决方案1】:

这方面有很多困惑,我会尽量简化。

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

主键可能是SIMPLE,甚至可以声明为内联:

 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 的查询可能涉及集群中的所有节点
【解决方案2】:

添加一个摘要答案作为接受的答案很长。术语“行”和“列”在 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))
【解决方案3】:

在 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 定义由两部分组成:Partition Key 和 Clustering Columns。第一部分映射到存储引擎的行键,而第二部分用于对一行中的列进行分组。

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。

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

【讨论】:

【解决方案4】:

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

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

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

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

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

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

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

【讨论】:

    【解决方案5】:

    简而言之:

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

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

    1. 除了主键列之外,您在 where 子句中使用了哪些列。

    2. 如果您有非常大的记录,那么我可以划分日期以便于管理。例如,我有一个县的 100 万人口记录的数据。所以,为了便于管理,我根据状态和经过pincode等对数据进行聚类。

    【讨论】:

    • 分区键不是 A 行的标识...它标识了一堆行,所有这些行都具有相同的分区键
    • @wmac,如果没有clustering key,如果只有一个partition key,那不就是row的partition key标识吗?
    【解决方案6】:

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

    示例 - 假设您必须找到最近加入用户组 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)
    

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

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

    【讨论】:

      【解决方案7】:

      免责声明:这是特定于 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

      【讨论】:

        猜你喜欢
        • 2019-09-07
        • 1970-01-01
        • 2014-09-23
        • 1970-01-01
        • 1970-01-01
        • 2018-06-20
        • 2018-03-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多