我有一个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
,我可以:
SELECT user FROM members_by_org_id_user_id WHERE organisation = ?
,然后执行SELECT name FROM users_by_id WHERE id in ?
(协调器必须联系许多节点=坏Cassandra中的IN关系不适合查询吗?)SELECT user from MEMBERS_by_org_id_user_id WHERE organisation = ?
,然后对每个用户执行查询SELECT name FROM users_by_id WHERE id = ?
(应用程序必须联系许多节点,因为用户的主键不同=不太坏?不完美)- 将
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"子句解决方案的关键因素。
编辑:
数据税的读取请求是如何完成的?这篇文章是了解卡桑德拉阅读策略的绝佳资源。