如何在 Cassandra 中为多个 "many to many" 关系建模?
How do I model multiple "many to many" relationships in Cassandra?
我一直在阅读 Cassandra,完成了一些教程并使用了 CQL,但现在是我设计模式的时候了,我遇到了一些困难。
我正在尝试创建一个架构来处理以下用例。我需要跟踪参加会议的员工以及他们在这些会议上讨论的主题。所以一个会议可以有多个工作人员参加,每次会议讨论多个主题,每个工作人员可以创建多个主题。这些是数据字段:
Worker: Worker ID, Worker Name
会议:会议ID、会议名称、会议时间
主题:主题ID、主题名称、创建者
我需要查询才能看到:
- 谁在开会?
- 工人过去参加过哪些会议?
- 工作人员创建了哪些主题?
- 哪些会议讨论了特定主题?
那么架构应该是什么样子来处理这个问题的呢?我觉得这不应该那么难,但是当我开始制作表格时我无法理解它。
请务必记住,Cassandra 数据建模是一项 query-driven 练习。由于上面有四个查询要完成,您可以 end-up 创建四个 table:每个查询一个。
我希望你能学会,所以我不会为你做这一切。但这里是我将如何解决查询 #1 和 #2。对于#1,我会创建一个 table 这样的:
CREATE TABLE meetingAttendance (
meetingID uuid,
meetingName text,
meetingTime timestamp,
workerID uuid,
workerName text,
PRIMARY KEY ((meetingID),workerName));
我将使用 meetingID
作为分区键,我将按 workerName
聚类,以便它们按顺序返回。
对于查询 #2,我将创建一个这样的查询 table:
CREATE TABLE meetingsByWorker (
workerID uuid,
workerName text,
meetingID uuid,
meetingName text,
meetingTime timestamp,
topicID uuid,
topicName text,
PRIMARY KEY ((workerID),meetingTime))
WITH CLUSTERING ORDER BY (meetingtime DESC);
当我们查询某个特定工作人员参加的会议时,我将在 workerID
上进行分区。由于会议是 time-based,按 meetingTime
排序是有意义的。默认情况下,它们会按 ASC
结束顺序排序,但历史数据通常以 DESC
结束顺序查看是有意义的,因此我将定义特定的 CLUSTERING ORDER 和排序方向(DESC
).
将一些行插入到两个 table 之后,我可以像这样查询特定会议的出席情况:
aploetz@cqlsh:Whosebug2> SELECT * FROM meetingattendance
WHERE meetingid=031e457b-2660-448b-a1d5-68c6cce3a820;
meetingid | workername | meetingname | meetingtime | workerid
--------------------------------------+---------------+--------------------+--------------------------+--------------------------------------
031e457b-2660-448b-a1d5-68c6cce3a820 | David | Project Prometheus | 2093-12-25 08:08:00-0600 | b83cbec4-95e5-4457-b037-c28c51d00418
031e457b-2660-448b-a1d5-68c6cce3a820 | Holloway, Dr. | Project Prometheus | 2093-12-25 08:08:00-0600 | d28b4ee8-b1b9-401a-88d4-bc6b9727d712
031e457b-2660-448b-a1d5-68c6cce3a820 | Janek, Capt. | Project Prometheus | 2093-12-25 08:08:00-0600 | ebccf3ba-c1d2-4503-b717-897c7e89d968
031e457b-2660-448b-a1d5-68c6cce3a820 | Shaw, Dr. | Project Prometheus | 2093-12-25 08:08:00-0600 | c0e3e560-2332-4a46-9fdf-68bdb31abcb2
031e457b-2660-448b-a1d5-68c6cce3a820 | Vickers | Project Prometheus | 2093-12-25 08:08:00-0600 | 77cb9f64-3cb8-43f9-ab0c-b907b01c4404
(5 rows)
aploetz@cqlsh:Whosebug2> SELECT * FROM meetingattendance
WHERE meetingid=c7cea773-4c99-445f-928d-5b8a511c843b;
meetingid | workername | meetingname | meetingtime | workerid
--------------------------------------+------------+------------------+--------------------------+--------------------------------------
c7cea773-4c99-445f-928d-5b8a511c843b | David | Wake Mr. Weyland | 2093-12-29 13:01:00-0600 | b83cbec4-95e5-4457-b037-c28c51d00418
c7cea773-4c99-445f-928d-5b8a511c843b | Ford, Dr. | Wake Mr. Weyland | 2093-12-29 13:01:00-0600 | 939657c2-e0cb-4a61-87d8-2a1739161d2a
c7cea773-4c99-445f-928d-5b8a511c843b | Vickers | Wake Mr. Weyland | 2093-12-29 13:01:00-0600 | 77cb9f64-3cb8-43f9-ab0c-b907b01c4404
c7cea773-4c99-445f-928d-5b8a511c843b | Weyland | Wake Mr. Weyland | 2093-12-29 13:01:00-0600 | 306955b8-c7ee-4350-8aa4-4c5d64487d74
(4 rows)
现在,如果我想查看特定员工参加了哪些会议,我也可以通过 workerID
:
查询
aploetz@cqlsh:Whosebug2> SELECT workername, meetingtime, meetingid, meetingname
FROM meetingsbyworker WHERE workerid=77cb9f64-3cb8-43f9-ab0c-b907b01c4404;
workername | meetingtime | meetingid | meetingname
------------+--------------------------+--------------------------------------+--------------------
Vickers | 2093-12-29 13:01:00-0600 | c7cea773-4c99-445f-928d-5b8a511c843b | Wake Mr. Weyland
Vickers | 2093-12-26 18:22:00-0600 | 3ea1282b-a465-4626-bd76-c65dd17b9f26 | Head Examination
Vickers | 2093-12-25 08:08:00-0600 | 031e457b-2660-448b-a1d5-68c6cce3a820 | Project Prometheus
(3 rows)
aploetz@cqlsh:Whosebug2> SELECT workername, meetingtime, meetingid, meetingname
FROM meetingsbyworker WHERE workerid=939657c2-e0cb-4a61-87d8-2a1739161d2a;
workername | meetingtime | meetingid | meetingname
------------+--------------------------+--------------------------------------+------------------
Ford, Dr. | 2093-12-29 13:01:00-0600 | c7cea773-4c99-445f-928d-5b8a511c843b | Wake Mr. Weyland
Ford, Dr. | 2093-12-26 18:22:00-0600 | 3ea1282b-a465-4626-bd76-c65dd17b9f26 | Head Examination
(2 rows)
请注意,数据已被非规范化,一些列值出现冗余。如果您决定仍然需要实体 table 来处理 worker 之类的东西,那也没关系。但再次问问自己,您计划查询这些 table 的频率和方式。最后两个你用类似的方法应该很容易解决。
我一直在阅读 Cassandra,完成了一些教程并使用了 CQL,但现在是我设计模式的时候了,我遇到了一些困难。
我正在尝试创建一个架构来处理以下用例。我需要跟踪参加会议的员工以及他们在这些会议上讨论的主题。所以一个会议可以有多个工作人员参加,每次会议讨论多个主题,每个工作人员可以创建多个主题。这些是数据字段:
Worker: Worker ID, Worker Name
会议:会议ID、会议名称、会议时间
主题:主题ID、主题名称、创建者
我需要查询才能看到:
- 谁在开会?
- 工人过去参加过哪些会议?
- 工作人员创建了哪些主题?
- 哪些会议讨论了特定主题?
那么架构应该是什么样子来处理这个问题的呢?我觉得这不应该那么难,但是当我开始制作表格时我无法理解它。
请务必记住,Cassandra 数据建模是一项 query-driven 练习。由于上面有四个查询要完成,您可以 end-up 创建四个 table:每个查询一个。
我希望你能学会,所以我不会为你做这一切。但这里是我将如何解决查询 #1 和 #2。对于#1,我会创建一个 table 这样的:
CREATE TABLE meetingAttendance (
meetingID uuid,
meetingName text,
meetingTime timestamp,
workerID uuid,
workerName text,
PRIMARY KEY ((meetingID),workerName));
我将使用 meetingID
作为分区键,我将按 workerName
聚类,以便它们按顺序返回。
对于查询 #2,我将创建一个这样的查询 table:
CREATE TABLE meetingsByWorker (
workerID uuid,
workerName text,
meetingID uuid,
meetingName text,
meetingTime timestamp,
topicID uuid,
topicName text,
PRIMARY KEY ((workerID),meetingTime))
WITH CLUSTERING ORDER BY (meetingtime DESC);
当我们查询某个特定工作人员参加的会议时,我将在 workerID
上进行分区。由于会议是 time-based,按 meetingTime
排序是有意义的。默认情况下,它们会按 ASC
结束顺序排序,但历史数据通常以 DESC
结束顺序查看是有意义的,因此我将定义特定的 CLUSTERING ORDER 和排序方向(DESC
).
将一些行插入到两个 table 之后,我可以像这样查询特定会议的出席情况:
aploetz@cqlsh:Whosebug2> SELECT * FROM meetingattendance
WHERE meetingid=031e457b-2660-448b-a1d5-68c6cce3a820;
meetingid | workername | meetingname | meetingtime | workerid
--------------------------------------+---------------+--------------------+--------------------------+--------------------------------------
031e457b-2660-448b-a1d5-68c6cce3a820 | David | Project Prometheus | 2093-12-25 08:08:00-0600 | b83cbec4-95e5-4457-b037-c28c51d00418
031e457b-2660-448b-a1d5-68c6cce3a820 | Holloway, Dr. | Project Prometheus | 2093-12-25 08:08:00-0600 | d28b4ee8-b1b9-401a-88d4-bc6b9727d712
031e457b-2660-448b-a1d5-68c6cce3a820 | Janek, Capt. | Project Prometheus | 2093-12-25 08:08:00-0600 | ebccf3ba-c1d2-4503-b717-897c7e89d968
031e457b-2660-448b-a1d5-68c6cce3a820 | Shaw, Dr. | Project Prometheus | 2093-12-25 08:08:00-0600 | c0e3e560-2332-4a46-9fdf-68bdb31abcb2
031e457b-2660-448b-a1d5-68c6cce3a820 | Vickers | Project Prometheus | 2093-12-25 08:08:00-0600 | 77cb9f64-3cb8-43f9-ab0c-b907b01c4404
(5 rows)
aploetz@cqlsh:Whosebug2> SELECT * FROM meetingattendance
WHERE meetingid=c7cea773-4c99-445f-928d-5b8a511c843b;
meetingid | workername | meetingname | meetingtime | workerid
--------------------------------------+------------+------------------+--------------------------+--------------------------------------
c7cea773-4c99-445f-928d-5b8a511c843b | David | Wake Mr. Weyland | 2093-12-29 13:01:00-0600 | b83cbec4-95e5-4457-b037-c28c51d00418
c7cea773-4c99-445f-928d-5b8a511c843b | Ford, Dr. | Wake Mr. Weyland | 2093-12-29 13:01:00-0600 | 939657c2-e0cb-4a61-87d8-2a1739161d2a
c7cea773-4c99-445f-928d-5b8a511c843b | Vickers | Wake Mr. Weyland | 2093-12-29 13:01:00-0600 | 77cb9f64-3cb8-43f9-ab0c-b907b01c4404
c7cea773-4c99-445f-928d-5b8a511c843b | Weyland | Wake Mr. Weyland | 2093-12-29 13:01:00-0600 | 306955b8-c7ee-4350-8aa4-4c5d64487d74
(4 rows)
现在,如果我想查看特定员工参加了哪些会议,我也可以通过 workerID
:
aploetz@cqlsh:Whosebug2> SELECT workername, meetingtime, meetingid, meetingname
FROM meetingsbyworker WHERE workerid=77cb9f64-3cb8-43f9-ab0c-b907b01c4404;
workername | meetingtime | meetingid | meetingname
------------+--------------------------+--------------------------------------+--------------------
Vickers | 2093-12-29 13:01:00-0600 | c7cea773-4c99-445f-928d-5b8a511c843b | Wake Mr. Weyland
Vickers | 2093-12-26 18:22:00-0600 | 3ea1282b-a465-4626-bd76-c65dd17b9f26 | Head Examination
Vickers | 2093-12-25 08:08:00-0600 | 031e457b-2660-448b-a1d5-68c6cce3a820 | Project Prometheus
(3 rows)
aploetz@cqlsh:Whosebug2> SELECT workername, meetingtime, meetingid, meetingname
FROM meetingsbyworker WHERE workerid=939657c2-e0cb-4a61-87d8-2a1739161d2a;
workername | meetingtime | meetingid | meetingname
------------+--------------------------+--------------------------------------+------------------
Ford, Dr. | 2093-12-29 13:01:00-0600 | c7cea773-4c99-445f-928d-5b8a511c843b | Wake Mr. Weyland
Ford, Dr. | 2093-12-26 18:22:00-0600 | 3ea1282b-a465-4626-bd76-c65dd17b9f26 | Head Examination
(2 rows)
请注意,数据已被非规范化,一些列值出现冗余。如果您决定仍然需要实体 table 来处理 worker 之类的东西,那也没关系。但再次问问自己,您计划查询这些 table 的频率和方式。最后两个你用类似的方法应该很容易解决。