提问



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


primary key,
partition key, 
composite key 
clustering key

最佳参考


围绕这个有很多困惑,我会尽量让它变得简单。


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


主键可能是 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文件[36]




小用途和内容示例

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和col4



无效:



  • col1和col2和col4

  • 任何不包含col1和col2
  • 的内容


希望这可以帮助。

其它参考1


添加redux答案作为可接受的答案是很长的。术语行和列在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)


其它参考2


在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。


我们可以有多个集群密钥以及依赖于声明的分区密钥。

其它参考3


主键:由分区键[[和可选的群集键(或列)]]组成]]

分区键:分区键的哈希值用于确定群集中的特定节点以存储数据

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


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


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


关于哪一个是强制性的混淆 ,在查询中可以跳过哪一个,尝试 将Cassandra想象成一个巨大的HashMap 有帮助。所以在HashMap中,你不能在没有Key的情况下检索值。这里,分区键扮演着那个键的角色。所以每个查询都需要指定它们。没有它Cassandra不知道要搜索哪个节点。

群集密钥(列,可选)有助于在Cassandra找到负责该特定分区键。

其它参考4


简而言之:


分区键只是行的标识,该标识大部分时间都是单列(称为主键),有时是组合多列(称为复合分区键)。


群集密钥只不过是索引&的排序即可。群集密钥取决于以下几点:



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

  2. 如果你有非常大的记录,那么我可以分开日期以便于管理。例如,我有一百万个县人口记录的数据。因此,为了便于管理,我基于状态和PIN码后对数据进行聚类等。


其它参考5


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


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


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天,通常会分享相同的哈希,因此可以从相同的分区!

其它参考6


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


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


给定表:EMPLOYEES {employee_id,firstname,surname}


可能的超级键是:


{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,surname},因为该键包含复合键({employee_id,firstname})和不是超级键({surname})的属性。