我有一个卡桑德拉桌子
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 ?
(协调器必须联系许多节点😔=错误的Is the IN relation in Cassandra bad for queries?)]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);
第三种方法的问题是,如果更新了用户,则也将需要更新与该用户有关的所有成员行,这在允许应用程序仅联系一个节点的同时,可能需要进行多次写入每次更新都要完成😔
我如何对数据建模以减少或减少所有这些问题?
在members_by_org_id_user_id
表中放置名称列将解决您当前的问题,但如果将来需要获取用户的email
或可能添加的任何其他列,则可能不是正确的方法。
应用程序必须联系多个节点
因为您在user id
表中使用id
作为主键(users_by_id
列),所以Cassandra不会一一遍历每个节点-它知道在哪里可以找到您的用户。由于您使用的是单个主键,因此它也是分区键。这是在Cassandra中查询表的最有效方法之一。
[我认为,选项2是用于数据建模的最佳方法,但是正如@Alex Ott的问题所指出的那样,这些表的大小可能是使用“ where in”子句解决方案的关键因素。