社交媒体与Cassandra的数据模型不同

时间:2016-06-06 18:20:35

标签: database cassandra datastax datastax-enterprise datastax-startup

想象一下,有一个社交网络,这里有一个用于存储喜欢(喜欢)动作的表,不像是从这个表中删除:

CREATE TABLE IF NOT EXISTS post_likes(
  post_id timeuuid,
  liker_id uuid, //liker user_id
    like_time timestamp,
    PRIMARY KEY ((post_id) ,liker_id, like_time)
) WITH CLUSTERING ORDER BY (like_time DESC);

上表在Cassandra中存在问题,因为当liker_id是第一个clustering_key时,我们无法按第二个聚类键like_time进行排序。

我们需要按like_time对表格数据进行排序,我们会在用户想要查看谁喜欢这篇文章时使用它,并显示喜欢该帖子按时间排序的人员列表({{ 1}})

我们还需要删除(不像),我们需要再次like_time DESCpost_id

你的建议是什么?我们如何按liker_id对此表格进行排序?

1 个答案:

答案 0 :(得分:1)

经过更多研究,我发现了这个解决方案: 选择正确的数据模型是使用Cassandra最困难的部分,这里是我们在Cassandra中为喜欢的表找到的解决方案,首先,我不得不说Cassandra的readwrite路径非常快,你不必担心在你的Cassandra表上写字,你需要围绕你的查询建模并且记住,数据复制是可以的。您的许多表格可能会重复相同的数据。并且不要忘记在群集周围均匀分布数据最大限度地减少读取的分区数量

由于我们使用的是NoSQL的Cassandra,我们知道NoSQL中的一个规则是非规范化,我们必须对数据进行非规范化,只考虑你想要的查询;这里对于类似的表数据建模我们将有两个表,这些表主要集中在易读或更容易说我们专注于我们想要的查询

CREATE TABLE IF NOT EXISTS post_likes(
    post_id timeuuid,
    liker_id uuid, //liker user_id
    like_time timestamp,
    PRIMARY KEY ((post_id) ,liker_id)
);

CREATE TABLE IF NOT EXISTS post_likes_by_time(
    post_id timeuuid,
    liker_id uuid, //liker user_id
    like_time timestamp,
    PRIMARY KEY ((post_id), like_time, liker_id)
) WITH CLUSTERING ORDER BY (like_time DESC);

当用户喜欢帖子时,我们只需插入上述两个表格。

为什么我们有post_likes_by_time表?

在社交网络中,您应该显示喜欢帖子的用户列表,通常您必须按like_time DESC排序喜欢,因为您要按like_time排序喜欢需要like_time作为聚类键才能按时间排序喜欢。

那么我们为什么还有post_likes表?

post_likes_by_time中,我们的群集密钥为like_time,我们还需要删除之类的!当群集密钥为 like_time 时,我们在表格中对数据进行排序时,我们无法做到这一点。这就是我们也有post_likes

的原因

为什么你不仅可以有一个表并同时执行这两个操作,排序和删除?

要从post_likes表格中删除一个,我们需要提供user_id(此处为liker_id)和post_id(一起),post_likes_by_time我们需要like_time like_time作为聚类键,我们需要按liker_id对表进行排序,然后它应该是第一个聚类键,第二个聚类键可能是like_time,这就是重点! liker_id是第一个群集密钥,然后按like_time选择或删除,您还需要提供like_time,但大部分时间都没有#include <time.h> #include <stdio.h> struct date { int month; int day; int year; }; struct date addSeven(struct date addSev) { addSev.day += 7; // Months with 31 days if ((addSev.month == 1 || // January addSev.month == 3 || // March addSev.month == 5 || // May addSev.month == 7 || // July addSev.month == 8 || // August addSev.month == 10 || // October addSev.month == 12) // December && addSev.day > 31) { addSev.day -= 31; // Equivalent to addSev.day = addSev.day - 31; addSev.month += 1; } // Months with 30 days else if ((addSev.month == 4 || // April addSev.month == 6 || // June addSev.month == 9 || // September addSev.month == 11) // November && addSev.day > 30) { addSev.day -= 30; addSev.month += 1; } // February else { if (addSev.year % 4 == 0 && addSev.day > 29) { // Leap year addSev.day -= 29; addSev.month += 1; } else if (addSev.day > 28) { addSev.day -= 28; addSev.month += 1; } } if ((addSev.day == 25) && addSev.day > 31) { addSev.day -= 31; // Equivalent to addSev.day = addSev.day - 31; addSev.month += 1; } else if ((addSev.day == 24) && addSev.day > 30) { addSev.day -= 30; addSev.month += 1; } else { if (addSev.year % 4 == 0 && addSev.day > 29) { // Leap year addSev.day -= 29; addSev.month += 1; } else if (addSev.day > 28) { addSev.day -= 28; addSev.month += 1; } if (addSev.month > 12) { addSev.month = 1; addSev.year += 1; } return addSev; } } int main () { struct date origDate, newDate; newDate = addSeven (origDate); printf("Enter a date in mm/dd/yyyy format:"); scanf("%d/%d/%d",&origDate.month,&origDate.day,&origDate.year); printf("\n%d/%d/%d\n", origDate); printf("\n%d/%d/%d\n", newDate); return 0; }