如何在 Cassandra 中为多个 "many to many" 关系建模?

How do I model multiple "many to many" relationships in Cassandra?

我一直在阅读 Cassandra,完成了一些教程并使用了 CQL,但现在是我设计模式的时候了,我遇到了一些困难。

我正在尝试创建一个架构来处理以下用例。我需要跟踪参加会议的员工以及他们在这些会议上讨论的主题。所以一个会议可以有多个工作人员参加,每次会议讨论多个主题,每个工作人员可以创建多个主题。这些是数据字段:

Worker: Worker ID, Worker Name

会议:会议ID、会议名称、会议时间

主题:主题ID、主题名称、创建者

我需要查询才能看到:

  1. 谁在开会?
  2. 工人过去参加过哪些会议?
  3. 工作人员创建了哪些主题?
  4. 哪些会议讨论了特定主题?

那么架构应该是什么样子来处理这个问题的呢?我觉得这不应该那么难,但是当我开始制作表格时我无法理解它。

请务必记住,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 的频率和方式。最后两个你用类似的方法应该很容易解决。