Cassandra:非规范化和分页

Posted

技术标签:

【中文标题】Cassandra:非规范化和分页【英文标题】:Cassandra: denormalization and paging 【发布时间】:2018-07-31 08:24:05 【问题描述】:

我正在尝试了解并熟悉 cassandra 数据模型。 本文解释了一些基本的建模规则:

https://www.ebayinc.com/stories/blogs/tech/cassandra-data-modeling-best-practices-part-1/

选项 3 显示非规范化数据模型:

我做对了吗,“user_by_item”表具有以下结构?

CREATE TABLE "user_by_item" (
    item_id int,
    users list<User>
    PRIMARY KEY (item_id)
)

如果是:很明显,我可以通过 item_id 一次查询获取所有用户。但是这样就不可能翻阅用户列表了。

我是否正确理解了表格结构以及如何管理项目列表,尤其是当它们变得非常大时?

【问题讨论】:

【参考方案1】:

首先,那篇文章已有 6 年历史。在当时,这是一篇很棒的文章,但 Cassandra 从那时起发生了显着的变化。例如,Cassandra 1.1 中不存在集合,我认为是撰写本文时的最新版本。

我做对了吗,“user_by_item”表具有以下结构?

是的,我想你已经理解了。将 item_id 用作 users_by_item 上的单个 PRIMARY KEY,同时将用户存储为集合是您可以执行此操作的一种方法。但是,它限制了您的查询灵活性,无法一次性拉回所有用户。

构建该查询表的最查询友好方法可能是使用user_id 上的集群键:

CREATE TABLE user_by_item (
  item_id int,
  user_id int,
  email text,
  name text,
  PRIMARY KEY ((item_id),user_id)
);

这样,我就可以查询到与项目 111 相关的所有用户:

aploetz@cqlsh:***> SELECT * FROM user_by_item WHERE item_id=111;

 item_id | user_id | email   | name
---------+---------+---------+------
     111 |     123 | jp@ebay |  Jay
     111 |     456 | jd@ebay | John

(2 rows)

如果我知道他的user_id,我也可以只查询 Jay:

aploetz@cqlsh:***> SELECT * FROM user_by_item WHERE item_id=111
                               AND user_id=123;

 item_id | user_id | email   | name
---------+---------+---------+------
     111 |     123 | jp@ebay |  Jay

(1 rows)

这给了我更多的查询灵活性,同时还通过item_id 存储所有用户数据。

专业提示:

除非必须,否则不要将表名用双引号括起来。它迫使 Cassandra 维持其案例,但可能使数据检索在以后成为令人沮丧的体验。 为 Cassandra 建模时,通常使用自然键,例如 name = "Jay"。像_id 这样的代理键的全部意义在于,可以从主表中引用某些内容,而不会冒每次需要/存储时都会拼写错误的风险。在 Cassandra 中,我们没有外键之类的东西,因此自然键可以帮助您删除一些不必要的列。 Cassandra 中的主键无法更改。因此,上述规则的例外情况是,如果预计主键值会发生变化(例如,Jay 合法地更改了他的 name),那么使用代理键将成为一个好主意。

【讨论】:

以上是关于Cassandra:非规范化和分页的主要内容,如果未能解决你的问题,请参考以下文章

具有非规范化的 cassandra 数据建模

更新 Cassandra 中的非规范化数据

更新Cassandra中的大型非规范化数据

Cassandra 3.0 的新特性: 物化视图

约束和分页

使用连接表存储库的@manytomany 中的 Spring 数据 jpa 规范和可分页