多对多 Cassandra 数据库
Many-To-Many Cassandra Database
假设我有用户。这些用户可以访问多个项目。所以一个项目也可以允许多个用户。
所以我模拟了四个 tables。用户(by_id)、项目(按 id)、projects_by_user_id 和 users_by_project_id。
----------- ------------ -------------------- --------------------
| users | | projects | | projects_by_user | | users_by_project |
|---------| |--------- | |------------------| |------------------|
| id K | | id K | | user_id K | | project_id K |
| name | | name | | project_id C | | user_id C |
----------- ------------ | project_name S | | user_name S |
-------------------- --------------------
所以将user_name存入users_by_project,将projet_name存入projects_by_usertable,以供查询。
我遇到的问题是当用户更新 project_name 时,这当然会更新项目 table。但是为了数据一致性,我还需要更新 projects_by_user table.
中的每个分区
据我所知,这只能通过查询 users_by_project table 中的所有用户并为每个用户进行更新来实现。
有没有先读取大量数据更好的方法?
我认为没有更好的方法。 Cassandra 对您可以进行的查询有很多限制。在您的情况下,您必须创建一个复合键(user_id、project_id),并且为了更新它,您必须在 where 子句中提供两个部分,这意味着您必须读取所有用户具体项目并更新其中的每一个。如果您有一个大型数据库并且这种情况经常发生,这将是很大的开销,所以我想最好从 table 中删除 projectname 字段并执行项目和 projects_by_users 的连接应用层。
顺便说一句:你在这里描述的场景对于关系数据库模型更方便,所以如果你的数据库模型的其余部分与此类似,我会考虑使用一些关系数据库。
我不明白你为什么需要四张桌子。您的用户和项目表可能包含所有数据。
如果您这样定义表格:
CREATE TABLE users (
user_id int PRIMARY KEY,
name text,
project_ids list<int> );
CREATE TABLE projects (
project_id int PRIMARY KEY,
name text,
user_ids list<int> );
然后每个用户都会有一个他们有权访问的项目 ID 列表,每个项目都会有一个有权访问它的用户列表。
要向用户 1 添加对项目 123 的访问权限,您需要 运行:
BEGIN BATCH
UPDATE users SET project_ids = project_ids + [123] WHERE user_id=1;
UPDATE projects SET user_ids = user_ids + [1] WHERE project_id=123;
APPLY BATCH;
要更改项目名称,您只需执行以下操作:
UPDATE projects SET name = 'New project name' WHERE project_id=123;
为简单起见,我将 id 字段显示为 int,但通常您会为此使用 uuid。
假设我有用户。这些用户可以访问多个项目。所以一个项目也可以允许多个用户。
所以我模拟了四个 tables。用户(by_id)、项目(按 id)、projects_by_user_id 和 users_by_project_id。
----------- ------------ -------------------- -------------------- | users | | projects | | projects_by_user | | users_by_project | |---------| |--------- | |------------------| |------------------| | id K | | id K | | user_id K | | project_id K | | name | | name | | project_id C | | user_id C | ----------- ------------ | project_name S | | user_name S | -------------------- --------------------
所以将user_name存入users_by_project,将projet_name存入projects_by_usertable,以供查询。
我遇到的问题是当用户更新 project_name 时,这当然会更新项目 table。但是为了数据一致性,我还需要更新 projects_by_user table.
中的每个分区据我所知,这只能通过查询 users_by_project table 中的所有用户并为每个用户进行更新来实现。
有没有先读取大量数据更好的方法?
我认为没有更好的方法。 Cassandra 对您可以进行的查询有很多限制。在您的情况下,您必须创建一个复合键(user_id、project_id),并且为了更新它,您必须在 where 子句中提供两个部分,这意味着您必须读取所有用户具体项目并更新其中的每一个。如果您有一个大型数据库并且这种情况经常发生,这将是很大的开销,所以我想最好从 table 中删除 projectname 字段并执行项目和 projects_by_users 的连接应用层。
顺便说一句:你在这里描述的场景对于关系数据库模型更方便,所以如果你的数据库模型的其余部分与此类似,我会考虑使用一些关系数据库。
我不明白你为什么需要四张桌子。您的用户和项目表可能包含所有数据。
如果您这样定义表格:
CREATE TABLE users (
user_id int PRIMARY KEY,
name text,
project_ids list<int> );
CREATE TABLE projects (
project_id int PRIMARY KEY,
name text,
user_ids list<int> );
然后每个用户都会有一个他们有权访问的项目 ID 列表,每个项目都会有一个有权访问它的用户列表。
要向用户 1 添加对项目 123 的访问权限,您需要 运行:
BEGIN BATCH
UPDATE users SET project_ids = project_ids + [123] WHERE user_id=1;
UPDATE projects SET user_ids = user_ids + [1] WHERE project_id=123;
APPLY BATCH;
要更改项目名称,您只需执行以下操作:
UPDATE projects SET name = 'New project name' WHERE project_id=123;
为简单起见,我将 id 字段显示为 int,但通常您会为此使用 uuid。