Cassandra IN vs许多查询vs不断变化的模型



我有一个cassandra表

CREATE TABLE users_by_id (
id bigint PRIMARY KEY,
name text,
email text,
password text,
);

CREATE TABLE members_by_org_id_user_id (
organisation bigint,
user bigint,
roles set<bigint>,
PRIMARY KEY (organisation, user)
) WITH CLUSTERING ORDER BY (user DESC);

如果我想检索组织中每个成员的name,我可以:

  1. SELECT user FROM members_by_org_id_user_id WHERE organisation = ?,然后执行SELECT name FROM users_by_id WHERE id in ?(协调器必须联系许多节点=坏Cassandra中的IN关系不适合查询吗?)
  2. SELECT user from MEMBERS_by_org_id_user_id WHERE organisation = ?,然后对每个用户执行查询SELECT name FROM users_by_id WHERE id = ?(应用程序必须联系许多节点,因为用户的主键不同=不太坏?不完美)
  3. members_by_org_id_user_id更改为
CREATE TABLE members_by_org_id_user_id (
organisation bigint,
user bigint,
name text,
email text,
PRIMARY KEY (organisation, user)
) WITH CLUSTERING ORDER BY (user DESC);

第三种方法的问题是,如果更新了用户,则与该用户相关的所有成员行也需要更新,这虽然允许应用程序只联系一个节点,但意味着每次更新可能需要进行多次写入

我如何对我的数据进行建模,以减少或完全消除这些问题?

理论上,一个组织最多可以由2000名成员组成,一个用户最多可以在20个组织中。

将name列放在members_by_org_id_user_id表中可以解决当前的问题,但如果将来需要获取用户的email或任何其他可能添加的列,则这可能不是正确的方法。

应用程序必须联系许多节点

由于您在users_by_id表中使用user id作为主键(id列),因此Cassandra不会逐个遍历每个节点,它知道在哪里可以找到您的用户。由于您使用的是单个主键,所以它也是分区键。这是在Cassandra中查询表最有效的方法之一。

在我看来,选项2是数据建模的最佳方法,但正如@Alex Ott的问题所指出的,这些表的大小可能是使用"where In"子句解决方案的关键因素。

编辑:

数据税的读取请求是如何完成的?这篇文章是了解卡桑德拉阅读策略的绝佳资源。

最新更新