Nik*_*ayS 5 data-modeling denormalization cassandra nosql
假设我们有可以评论视频的用户,并且我们希望显示带有用户名的视频的所有评论。用户也可以转到他的个人资料页面并更改他的名字。
基于此答案 Cassandra非规范化数据模型中介绍的 Cassandra 数据建模实践,我创建了这样的表:
CREATE TABLE users (
user_id UUID,
first_name TEXT,
last_name TEXT,
PRIMARY KEY ((user_id))
);
CREATE TABLE comments_by_video (
video_id UUID,
added_at TIMESTAMP,
user_id UUID,
comment TEXT,
first_name TEXT,
last_name TEXT,
PRIMARY KEY ((video_id), added_at, user_id)
);
Run Code Online (Sandbox Code Playgroud)
看起来棒极了,我们只需一个查询就可以获得视频评论所需的数据。
现在,让我们考虑这样的用例。
用户创建了大量评论(例如 10 000 条),然后决定更改他的名字。我们应该更新所有评论以更改他的名字吗?有没有办法让它变得高效?
恭喜您,您刚刚进入关系型数据库专区!
更严重的是,这个要求对你的模型来说是一个痛苦。要么您必须在读取时使用来user_id查询表中的每个注释,要么您需要查看所有分区和所有注释以替换所有地方的和。没有办法让它变得高效。 last_namefirst nameusersfirst_namelast_name
然而,让我们尝试一种简单的方法。您可以创建一个用户表、一个视频表和另一个存储用户所有评论的表,如下所示:
CREATE TABLE users_videos_comment(
user_id uuid,
video_id uuid,
time timestamp,
comment text,
PRIMARY KEY ((user_id,video_id), time)
);
Run Code Online (Sandbox Code Playgroud)
这对于您的新需求非常有效,对于用户和视频,您可以获得所有评论,因此您只需查询用户即可查找名称,但您失去了“一次查询视频中所有评论”的功能。此外,您还必须存储users用户评论的视频列表和videos发表评论的用户列表。这很难维护并且需要更多代码。
也许有更好的方法来做到这一点,但请记住,使用 noSQL 时,您在写入时会失去什么,但在读取时会获得什么
如果您不介意进行大量写入来更改用户名,则保持原样。从这篇文章来看,Cassandra 似乎更适合写入,因此您应该考虑优化读取。
考虑到这一点,我们可以在users该列表中添加一个字段,列出用户发表的所有评论。这样,您就不必扫描来comments_by_video查找用户发表的每条评论。这增加了一些复杂性,因为对于用户所做的任何评论,您必须进行两次写入(并确保其一致)。但你已经满足了这两个要求。
希望能帮助到你