我一直在阅读网络上的文章,以了解以下key
类型之间的差异。但这对我来说似乎很难掌握。这些例子肯定有助于更好地理解。
primary key,
partition key,
composite key
clustering key
答案 0 :(得分:1029)
围绕这个有很多困惑,我会尽量让它变得简单。
主键是一般概念,用于指示用于从表中检索数据的一个或多个列。
主键可以是 SIMPLE ,甚至可以内联声明:
create table stackoverflow_simple (
key text PRIMARY KEY,
data text
);
这意味着它是由一个列组成的。
但主键也可以是 COMPOSITE (又名 COMPOUND ),从更多列生成。< / p>
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来执行查询,这些是定义分区键的2列。要进行查询的“常规”规则是您必须至少传递所有分区键列,然后您可以按照它们设置的顺序可选地添加每个聚类键。
所以有效查询是(不包括二级索引)
无效:
希望这有帮助。
答案 1 :(得分:96)
添加redux答案作为已接受的答案很长。术语&#34; row&#34;和&#34;列&#34;在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 :(得分:13)
在cassandra中,主键,分区键,复合键,聚类键之间的区别总是会产生一些混乱。所以我将在下面解释并与其他人联系起来。我们使用CQL(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 :(得分:7)
主键:由分区键[和可选的群集键(或列)]组成
分区键:分区键的哈希值用于确定群集中的特定节点以存储数据
群集密钥:用于对每个分区(或负责节点及其副本)中的数据进行排序
复合主键:如上所述,群集密钥在主键中是可选的。如果没有提到它们,它就是一个简单的主键。如果提到了聚类键,则它是复合主键。
复合分区键:仅使用一列作为分区键,可能会导致广泛行问题(取决于用例/数据建模)。因此,分区键有时被指定为多个列的组合。
关于哪一个是强制性的混淆 ,在查询中可以跳过哪一个,尝试 将Cassandra想象成一个巨大的HashMap 有帮助。因此,在HashMap中,如果没有Key,则无法检索值。
这里,分区键扮演该键的角色。因此每个查询都需要指定它们。没有它,Cassandra将不知道要搜索哪个节点
群集密钥(列,可选)有助于在Cassandra找到负责该特定分区键的特定节点(及其副本)后进一步缩小查询搜索范围。
答案 4 :(得分:3)
简单来说:
分区键只是行的标识,该标识大部分时间都是单列(称为主键)多列的组合(称为复合分区键)。
群集密钥只不过是索引&amp;的排序即可。群集密钥取决于几个方面:
您在除主键列之外的where子句中使用哪些列。
如果您有非常大的记录,那么我可以分配日期以便于管理。例如,我有一百万个县人口记录的数据。因此,为了便于管理,我基于状态和PIN码后对数据进行聚类等。
答案 5 :(得分:0)
值得注意的是,在关系世界(复合键)中,你可能会使用那些相似的概念。
示例 - 假设您必须找到最近加入用户组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天那些共享相同的哈希,因此可以在同一个分区中使用!
答案 6 :(得分:0)
Cassandra中的主键通常由两部分组成-分区键和群集列。
primary_key(((partition_key),clustering_col)
分区键-主键的第一部分。分区键的主要目的是识别存储特定行的节点。
创建表格电话簿( phone_num int, 命名文字, 年龄, 城市文字, 主键((phone_num,name),age);
此处,(phone_num,名称)是分区键。插入数据时,将生成分区键的哈希值,该值决定该行应进入的节点。
考虑一个4节点群集,每个节点都有一个可以存储的哈希值范围。 (写) INSERT INTO phone_book VALUES(7826573732,'Joey',25,'New York');
现在,分区键的哈希值由Cassandra分区程序计算。 例如,哈希值(7826573732,“ Joey”)→12,现在,此行将插入到节点C中。
(已读) 选择*来自phone_book WHERE phone_num = 7826573732和名称=“ Joey”;
现在,再次计算分区键的哈希值(7826573732,“ Joey”),在我们的示例中为12,它位于节点C中,从中进行读取。
根据要解决的查询,主键中可以有多个分区键和群集列。
primary_key((pk1,pk2),col 1,col2)
答案 7 :(得分:0)
免责声明:这是特定于 DynamoDB 的答案,但是这些概念也适用于 Cassandra,因为两者都是 NoSQL 数据库。
创建表时,除了表名外,还必须指定表的主键。 主键唯一标识表中的每个项目,因此没有两个项目可以具有相同的键。
DynamoDB 支持两种不同的主键:
分区键 – 简单主键,由一个称为分区键的属性组成。
DynamoDB 使用分区键的值作为内部哈希函数的输入。哈希函数的输出决定了项目将存储在哪个分区(DynamoDB 内部的物理存储)。
在只有一个分区键的表中,没有两个项目可以具有相同的分区键值。
分区键和排序键 – 称为复合主键,这种类型的键由两个属性组成。第一个属性是分区键,第二个属性是排序键。
DynamoDB 使用分区键值作为内部哈希函数的输入。哈希函数的输出决定了项目将存储在的分区(DynamoDB 内部的物理存储)。具有相同分区键值的所有项目存储在一起,按排序键值排序。
在具有分区键和排序键的表中,两个项目可能具有相同的分区键值。但是,这两个项目必须具有不同的排序键值。
复合主键在查询数据时为您提供了额外的灵活性。例如,如果您只提供 Artist 的值,DynamoDB 将检索该艺术家的所有歌曲。要仅检索特定艺术家的歌曲子集,您可以提供 Artist 的值以及 SongTitle 的一系列值。
<块引用>注意:项目的分区键也称为它的哈希 属性。术语哈希属性源自使用内部 DynamoDB 中的散列函数,可将数据项均匀分布在 分区,基于它们的分区键值。
项目的排序键也称为范围属性。术语范围属性源自 DynamoDB 将具有相同分区键的项目存储在物理上靠近在一起的方式,按排序键值排序。
答案 8 :(得分:-3)
在数据库设计中,复合键是一组非最小的超级键。
复合键是一个包含复合键和至少一个不是超级键的属性的集合
给定表:员工{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})的属性。