为什么聚类密钥在cassandra中被命名为“聚类密钥”?

时间:2018-07-05 12:44:13

标签: cassandra data-modeling

表1

create table mylistofitems (listid int, 
  itemid int, 
  quantity int, 
  itemdesc text, 
  primary key ((listid, itemid), itemdesc));

在上表中,我正在执行以下插入操作:

insert into mylistofitems (listid, itemid, itemdesc, quantity) values (1, 1000, 'apple', 5);
insert into mylistofitems (listid, itemid, itemdesc, quantity) values (1, 1000, 'banana', 10);
insert into mylistofitems (listid, itemid, itemdesc, quantity) values (1, 1000, 'orange', 6);
insert into mylistofitems (listid, itemid, itemdesc, quantity) values (1, 1000, 'orange', 50);

当我从mylistofitems中选择*时,我得到以下信息:

 listid | itemid | itemdesc | quantity
--------+--------+----------+----------
      1 |   1000 |    apple |        5
      1 |   1000 |   banana |       10
      1 |   1000 |   orange |       50

第二个insert语句未覆盖第一行。但是第四插入语句已覆盖第三行。

在这种情况下,聚簇键是什么意思?

表2:

create table myitems (listid int,
  itemid int, 
  idesc text, 
  qty int,
  primary key (listid, itemid));

我将以下记录插入表2:

insert into myitems (listid, itemid, idesc, qty) values (1, 1000,
'apple', 5);
insert into myitems (listid, itemid, idesc, qty) values (1, 1000, 'banana', 10);
insert into myitems (listid, itemid, idesc, qty) values (1, 1000, 'orange', 6);
insert into myitems (listid, itemid, idesc, qty) values (1, 1000, 'orange', 50);

在表2中插入查询与表1完全相同。 但是当我从项目中选择*时,我很惊讶地看到最后插入的只有一行。其余所有行均丢失。即,每个插入语句将覆盖先前的记录。

 listid | itemid | idesc  | qty
--------+--------+--------+-----
      1 |   1000 | orange |  50

问题: 为什么表2中的行为与表1中的行为不同? 在这种情况下,聚簇键是什么意思?为什么将集群键命名为“集群键”。它与cassandra集群有关系吗?

有关更新的问题: 我尝试对表1进行更新:

update mylistofitems set quantity = 100 where listid = 1 and itemid = 1000;

这表示错误2200,缺少某些群集密钥。为什么要限制呢?

2 个答案:

答案 0 :(得分:0)

什么是群集密钥?

群集键指示数据如何在磁盘上存储。这就是Cassandra表现出色的原因之一。因为列的顺序会更改数据的存储方式,所以重要的是要知道它们是在Cassandra的内部文件中管理的。

将磁盘上的数据可视化为数组。这实际上是Cassandra将如何存储您的数据的方式。这是前三个查询后的第一个表:

table1 =
(listid(1) - itemid(1000)) // Partition key
    idesc('apple') // Clustering key
        = {listid: 1, itemid: 1000, idesc: apple, qty: 5}
    idesc('banana') // Clustering key
        = {listid: 1, itemid: 1000, idesc: banana, qty: 10}
    idesc('orange') // Clustering key
        = {listid: 1, itemid: 1000, idesc: orange, qty: 6}

在第四个插入中,将使用每个聚类键(在本示例中为索引)遍历数据,以查找要覆盖的最终数据。因此,在第四次插入后,它将如下所示:

table1 =
(listid(1) - itemid(1000)) // Partition key
    idesc('apple') // Clustering key
        = {listid: 1, itemid: 1000, idesc: apple, qty: 5}
    idesc('banana') // Clustering key
        = {listid: 1, itemid: 1000, idesc: banana, qty: 10}
    idesc('orange') // Clustering key
        = {listid: 1, itemid: 1000, idesc: orange, qty: 50}

缺少分区/集群键

进行以下查询,以及我像Cassandra这样的访问数据的示例。

  1. WHERE listid IN (1, 2) and itemid = 1000

    result = (data[1-1000], data[2-1000])

  2. WHERE listid = 1 AND itemid = 1000 AND idesc = 'apple'

    result = data[1-1000]['apple']

  3. WHERE idesc = 'apple'

    result = data[????]['apple']

    C *不知道要搜索apple的索引。

重要的是要注意,插入或更新数据时这是相同的。让我们以您的UPDATE查询为例。

UPDATE mylistofitems SET quantity = 100 WHERE listid = 1 AND itemid = 1000;

使用此查询,您正在尝试执行以下操作:

`data[1-1000][????] = {listid: 1, itemid: 1000, idesc:????, qty: 1000}`

C *不知道将数据存储在哪个索引中。

您应该将查询更新为以下内容:

UPDATE mylistofitems SET quantity = 100 WHERE listid = 1 AND itemid = 1000 AND idesc = 'orange';

以数组形式看起来像:

`data[1-1000]['orange'] = {listid: 1, itemid: 1000, idesc: 'orange', qty: 1000}`

将数量添加为聚类键

如果将quantity添加为聚簇键,则数据结构将如下所示:

table1 =
(listid(1) - itemid(1000)) // Partition key
    idesc('apple') // Clustering key
        quantity(5) // Clustering key
            = {listid: 1, itemid: 1000, idesc: 'apple', qty: 5}
    idesc('banana') // Clustering key
        quantity(10) // Clustering key
            = {listid: 1, itemid: 1000, idesc: 'banana', qty: 10}
    idesc('orange') // Clustering key
        quantity(6) // Clustering key
            = {listid: 1, itemid: 1000, idesc: 'orange', qty: 6}
        quantity(50 // Clustering key
            = {listid: 1, itemid: 1000, idesc: 'orange', qty: 50}

这将允许您为每个组合包含多个行,尽管您将无法具有相同数据的多个行。

一般规则

  1. 分区+集群键是每一行的 unique 字段
  2. 如果不在查询中包含先前的键,则无法通过键进行查询
  3. Cassandra没有插入/更新-只有upserts
  4. 插入行时,必须指定所有键

答案 1 :(得分:0)

我想回答自己的问题以关闭此线程。还要帮助那些会有相同困惑的人:

基本上,我正在研究主键,分区键,集群键的概念。

表1的主键是:

primary key ((listid, itemid), itemdesc));

这意味着listid + itemid只是一个分区键,可以帮助记录找到要登陆的节点。

仅对于listid + itemid + itemdesc的组合,才会保留实际的唯一性。

总结:

listid+itemid = composite partition key
listid+itemid+itemdesc = composite primary key
itemdesc = clustering key 

(集群键仅用于对每个分区下的项目进行排序,这有助于使用各种关系运算符对此列进行查询)

在这种情况下,群集只是将记录按分区键分组,并在每个分区键下的ASC(默认情况下)中对其进行排序。换句话说,它是一个分组依据和排序依据。

这与RDBMS完全不同。在RDBMS世界中,您可以根据需要在检索时使用分组和排序。在Cassandra中,我们在插入时会使用分组和排序,以便您的检索更快(取决于所使用的查询)

表2被定义为主键(listid,itemid),这意味着:

listid = standalone partition key
itemid = standalone clustering key
listid + itemid = composite primary key
相关问题