Cassandra:反规范化和分页

Cassandra: denormalization and paging

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

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

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

我做对了吗,"user_by_item" table 具有以下结构?

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

如果是:很明显我可以通过 item_id 通过一次查询获得所有用户。但是那时不可能翻阅用户列表。

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

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

Am I getting the things right, that the "user_by_item" table has the following structure?

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

构建该查询 table 的最 query-friendly 方法可能是在 user_id:[=21= 上使用聚簇键]

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

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

aploetz@cqlsh:Whosebug> 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)

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

aploetz@cqlsh:Whosebug> 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 的所有用户数据。

亲提示:

  • 除非万不得已,否则不要将您的 table 名称用双引号引起来。它迫使 Cassandra 维持它的大小写,但会使以后的数据检索成为一种令人沮丧的体验。
  • 在为 Cassandra 建模时,通常的做法是使用像 name = "Jay." 这样的自然键从主 table 中引用,而不会冒着每次 needed/stored 都被拼错的风险。在 Cassandra 中我们没有外键之类的东西,所以自然键可以帮你剪掉一些不需要的列。
  • Cassandra 中的主键无法更改。因此,上述规则的例外情况是,如果预测主键值会发生变化(例如,Jay 合法地更改了他的 name),那么使用代理键就成了一个好主意。