我需要在 cassandra 中为用户、角色、组织和权限设计数据模型。
- 每个组织都可以有用户和角色
- 每个用户可以属于多个角色
- 每个角色可以有多个用户和权限。
因此,基于上述设计要求,以下将是我的查询:
- 对于一个组织,获取所有用户/角色
- 对于用户获取所有角色
- 对于角色获取所有用户/权限
任何人都可以帮助我为上述要求设计数据模型。
Cassandra 不像关系数据库那样具有外键关系(参见此处和此处),这意味着您无法加入多个列族来满足给定的查询请求。
以下是两种可能的解决方案:
解决方案 1:非规范化组织和用户。
只需创建一个Users
类似于以下内容的表(即非规范化表):
create table Users (
... organization ascii,
... uid int primary key,
... role set<ascii>,
... permission set<ascii>);
并为组织创建索引以允许查询非键列:
create index demo_users_organization on users (organization);
这可以满足您的前两个要求:
查询 1 --- 对于一个组织,获取所有用户/角色:
cqlsh:demo> select * from users where organization='stack overflow';
uid | organization | permission | role
-----+----------------+------------------------------------------+-----------------------------
1 | stack overflow | {down-vote, up-vote} | {end user}
2 | stack overflow | {close-vote, down-vote, up-vote} | {end user, moderator}
3 | stack overflow | {close-vote, down-vote, reboot, up-vote} | {end user, moderator, root}
查询 2 --- 对于用户获取所有角色
cqlsh:demo> select role from users where uid = 2;
role
-----------------------
{end user, moderator}
但是,由于尚不支持集合索引,因此此非规范化表无法处理您的第三个要求:
cqlsh:demo> create index demo_users_role on users (role);
Bad Request: Indexes on collections are no yet supported
解决方案 2:非规范化组织、用户和角色。
解决方案 1 的一种解决方法是进一步非规范化用户和角色,其中每个(用户、角色)对在表中都有一行:
cqlsh:demo> create table RoleUsers (
... uid int,
... organization ascii,
... role ascii,
... permission set<ascii>,
... primary key(uid, role));
再次为organization
.
以下是示例行:
uid | role | organization | permission
-----+-----------+----------------+------------------------------------------
1 | end user | stack overflow | {down-vote, up-vote}
2 | end user | stack overflow | {close-vote, down-vote, up-vote}
2 | moderator | stack overflow | {close-vote, down-vote, up-vote}
3 | end user | stack overflow | {close-vote, down-vote, reboot, up-vote}
3 | moderator | stack overflow | {close-vote, down-vote, reboot, up-vote}
3 | root | stack overflow | {close-vote, down-vote, reboot, up-vote}
现在,您可以执行第三个查询。
查询 3 --- 对于一个角色,获取所有用户/权限:
cqlsh:demo> select uid from roleusers where role='moderator' allow filtering;
uid | permission
-----+------------------------------------------
2 | {close-vote, down-vote, up-vote}
3 | {close-vote, down-vote, reboot, up-vote}