从表格设计开始,您似乎正在倒退。在 Cassandra 中对数据建模时,这听起来违反直觉,但您需要先从应用程序查询开始,然后针对这些查询设计表。
让我通过列出您的所有应用查询并为每个查询设计一个表格来进行说明。
APP QUERY 1 - 查询所有数据(findByAll)
如果您打算检索所有记录以显示它们,那么这在 Cassandra 中是个坏主意,因为它需要进行全表扫描。我知道开发人员习惯于在具有少量数据的玩具应用程序上执行此操作,但在 Cassandra 中,数据分布在节点之间,因此全表扫描无法扩展。
考虑一下集群中包含数百个节点的百万或更多记录的情况。应用程序等待查询完成检索所有记录是没有意义的。
APP QUERY 2 - 根据专业查询所有数据,计划在此列添加二级索引
如果性能对您很重要,那么在 major 上添加索引并不是一个好主意。您应该设计一个专门为此查询优化的表。例如:
CREATE TABLE students_by_major (
major text,
studentid text,
department text,
updatedon timestamp,
PRIMARY KEY (major, studentid)
)
在此表中,每个major 分区都有1 行或多行studentid。例如:
major | studentid | department | updatedon
------------------------+-----------+-------------+---------------------------------
computer science | 321 | science | 2020-01-23 00:00:00.000000+0000
electrical engineering | 321 | engineering | 2020-02-24 00:00:00.000000+0000
electrical engineering | 654 | engineering | 2019-05-06 00:00:00.000000+0000
chemical engineering | 654 | engineering | 2019-07-08 00:00:00.000000+0000
arts | 987 | law | 2020-09-12 00:00:00.000000+0000
civil engineering | 654 | engineering | 2019-02-04 00:00:00.000000+0000
APP QUERY 3 - 根据时间范围查询数据,即按列更新
如果列在主键中定义,您将只能对 updatedon 执行范围查询。
APP QUERY 4 - 如果学生要选择不同的专业?
您可以有一个表格,其中每个学生都有多行专业:
CREATE TABLE majors_by_student (
studentid text,
major text,
department text,
updatedon timestamp,
PRIMARY KEY (studentid, major)
)
例如,学生ID654已更新专业3次:
cqlsh> SELECT * FROM majors_by_student WHERE studentid = '654';
studentid | updatedon | department | major
-----------+---------------------------------+-------------+------------------------
654 | 2019-07-08 00:00:00.000000+0000 | engineering | chemical engineering
654 | 2019-05-06 00:00:00.000000+0000 | engineering | electrical engineering
654 | 2019-02-04 00:00:00.000000+0000 | engineering | civil engineering
QUERY 5 - 您希望对 updatedon 执行范围查询,其中行仅由 studentid 唯一标识。
CREATE TABLE community.updated_majors_by_student (
studentid text,
updatedon timestamp,
department text,
major text,
PRIMARY KEY (studentid, updatedon)
)
以上面的学生654 为例,您可以对 4 月 30 日之后的任何更新进行范围查询:
SELECT * FROM updated_majors_by_student WHERE studentid = '654' AND updatedon > '2019-04-30 +0000';
请注意,由于updatedon 是时间戳,因此您需要指定精确时区,+0000 是 UTC 的 TZ。
studentid | updatedon | department | major
-----------+---------------------------------+-------------+------------------------
654 | 2019-07-08 00:00:00.000000+0000 | engineering | chemical engineering
654 | 2019-05-06 00:00:00.000000+0000 | engineering | electrical engineering
要保持上述表格同步,您需要使用我在本文中描述的 CQL BATCH 语句 -- https://community.datastax.com/articles/2744/。干杯!