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


522

我一直在网上阅读文章,以了解以下key类型之间的区别。但是我似乎很难理解。实例肯定会帮助您更好地理解。

primary key,
partition key, 
composite key 
clustering key

22
我发现本文包含有关这些概念的许多详细说明。
mynkow

本文还明确指出了这些术语。
duong_dajgja

您上面共享的@duong_dajgja URL已损坏,您可以使用有效/有用的URL编辑评论吗?
realPK '18

@realPK链接以某种方式消失了。但是我在quora.com/…上找到了另一个链接给您。
duong_dajgja

Answers:


1170

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

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

主键可以是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)      
  );

这些名字的背后...

  • 分区键是负责在您的节点的数据分发。
  • 集群主要负责数据的分区中的排序。
  • 主键相当于分区键在单场键表(即简单)。
  • 复合/复合键就是任何多列键

更多使用信息:DATASTAX文档


小用法和内容示例
SIMPLE KEY:

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的任何内容

希望这可以帮助。


7
正如我写的那样-<<进行查询的“通用”规则是,您必须至少传递所有分区键列,然后才能按照设置顺序添加每个键。>>-因为col10是在之前定义的col4,您还必须传递它以查询col4
Carlo Bertuccini

2
您可以添加二级索引,但这并不意味着您可以执行“任何” cql查询-以及更多:在创建二级索引之前,您应该数到10 ... 000 ..... :)
Carlo Bertuccini

2
二级索引被实现为本地索引-它们不分布在集群中。群集的每个节点负责存储其拥有的数据的二级索引。因此,对sec.index的查询可能涉及集群中的所有节点
Carlo Bertuccini

5
这几天让我感到困惑,感谢您的回答,现在我可以在脑海中构建数据模型了。
罗杰·杜万

2
哇。您刚刚为我节省了数小时或数天!谢谢您的精彩解释。
Andre Garcia

128

添加摘要答案作为接受答案很长。在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)

15

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

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。

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


6
您可能已经对您的消息来源表示赞赏(2013年=比帖子还早):thelastpickle.com/blog/2013/01/11/primary-keys-in-cql.html
Christophe Roussy

11

主键:由分区键[和可选的群集键(或列)组成]
分区键分区键的哈希值用于确定群集中要存储数据的特定节点
群集键:用于对每个分区(或负责节点及其副本)中的数据进行排序

复合主键:如上所述,聚类键在主键中是可选的。如果未提及它们,那是一个简单的主键。如果提到集群键,则它是复合主键。

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

关于哪些是强制性的,哪些是可以跳过的等的混淆,试图将 Cassandra想象成一个巨大的HashMap会有所帮助。因此,在HashMap中,没有键就无法检索值。
在此,分区键充当该键的角色。因此,每个查询都需要指定它们。没有它们,Cassandra将不知道要搜索哪个节点。
集群键(列,哪些是可选的),在进一步缩小您的查询搜索卡桑德拉找出特定节点之后(和它的复制品)的帮助下负责特定的分区键


5

简而言之:

分区键是什么,但鉴定为一排,即识别大部分的时间是在单个列(称为主键),有时一个多列(被称为组合复合分区键)。

群集键不过是索引排序。群集密钥取决于以下几件事:

  1. 您在where子句中使用哪些列(主键列除外)。

  2. 如果您有很多记录,那么我可以就什么问题进行划分以便于管理。例如,我有一个100万县人口记录的数据。因此,为了便于管理,我根据状态和密码后对数据进行聚类等。


3
分区键不是行的标识...它标识一堆所有行都具有相同分区键的行
wmac

1

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

示例-假设您必须找到最近加入用户组X的最后N个用户。在这种情况下,读操作占主导地位,您将如何有效地做到这一点?这样(来自正式的Cassandra指南):

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天内往往是那些有着相同的哈希值,因此可从同一分区!


0

Cassandra中的主键通常由两部分组成-分区键和群集列。

primary_key(((partition_key),clustering_col)

分区键-主键的第一部分。分区键的主要目的是识别存储特定行的节点。

创建表phone_book(phone_num int,名称文本,age int,城市文本,主键((phone_num,name),age);

在这里,(phone_num,名称)是分区键。插入数据时,将生成分区键的哈希值,该值决定该行应进入的节点。

考虑一个4节点群集,每个节点都有一个可以存储的哈希值范围。(写入)插入phone_book值(7826573732,'Joey',25,'New York');

现在,分区键的哈希值由Cassandra分区程序计算。例如,哈希值(7826573732,'Joey')→12,现在,此行将插入到节点C中。

(读取)SELECT * FROM phone_book在哪里phone_num = 7826573732和name ='Joey';

现在,再次计算分区键的哈希值(7826573732,'Joey'),在我们的情况下为12,它位于节点C中,从中进行读取。

  1. 群集列-主键的第二部分。具有聚类列的主要目的是按排序顺序存储数据。默认情况下,顺序是升序的。

根据要解决的查询,主键中可以有多个分区键和群集列。

primary_key((pk1,pk2),col 1,col2)


-3

在数据库设计中,复合键是一组不小的超级键。

复合键是一组包含复合键和至少一个不是超级键的属性的集合

给定的表:EMPLOYEES {employee_id,名字,姓氏}

可能的超级键是:

{employee_id}
{employee_id, firstname}
{employee_id, firstname, surname}

{employee_id}是唯一的最小超键,这也使其成为唯一的候选键,因为{firstname}和{surname}不能保证唯一性。由于将主键定义为选定的候选键,并且在此示例中仅存在一个候选键,因此{employee_id}是最小超键,唯一候选键和唯一可能的主键。

复合键的详尽列表为:

{employee_id, firstname}
{employee_id, surname}
{employee_id, firstname, surname}

唯一的组合键是{employee_id,firstname,firstname},因为该键包含复合键({employee_id,firstname})和非超级键({surname})的属性。


完全不问问题。请编辑答案,以解决在Cassandra中询问的地址键的问题,而不是一般性的解释。TY。
realPK '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.