RDMBS到Cassandra-当前用户是否喜欢查询的帖子?

时间:2019-03-21 08:18:45

标签: database-design cassandra nosql cql

我正在尝试锻炼如何在Cassandra中创建模型,以便以某种有效的方式(可能是单个查询)获取信息,即当前登录的用户是否喜欢帖子以及帖子数据。在RDMBS中,这很容易,但是我只是不敢在Cassandra中做到这一点。

以下是我要在RDMBS上的Cassandra中实现的示例:

SELECT 
    x.post_id, 
    x.content, 
    x.created_at,
    (
    SELECT CASE
        WHEN EXISTS (
            SELECT 1
            FROM post_likes AS p1
            WHERE (p1.user_id = @currentUserId) AND (x.post_id = p1.post_id))
        THEN TRUE::bool ELSE FALSE::bool
    END
) AS "has_current_user_liked_post"

1 个答案:

答案 0 :(得分:0)

最简单的方法是创建表likes_by_post:

CREATE TABLE likes_by_post (
    post_id text,
    user_id text,
    PRIMARY KEY (post_id, user_id)
);

此表将使您获得喜欢某个帖子的所有用户:

SELECT * FROM likes_by_post WHERE post_id='post_1';

检查用户喜欢的帖子:

SELECT * FROM likes_by_post WHERE post_id='post_1' AND user_id='user_1'; 

但是此方法有一个缺点-如果您希望每个帖子有很多用户喜欢(数百万或数十亿),则该表的分区太大,将导致性能不佳和无法存储每个帖子如此多的喜欢。 Cassandra的每个分区键限制为20亿行。

在这种情况下,您可以使用复合主键将有关单个帖子的喜欢信息分散到多个分区(这种方法通常称为“一致性哈希”):

CREATE TABLE likes_buckets_by_post (
    post_id text,
    bucket_id int,
    user_id text,
    PRIMARY KEY (( post_id, bucket_id ), user_id)
);

bucket_id是一个综合字段,负责为同一帖子的不同用户生成不同的分区键。

bucked_id应该是基于user_id字段的某种哈希。 一致的哈希提供了根据指定的用户ID在指定范围内生成一些数字的能力。 (例如Guava Java库提供了consistent hashing function

在将数据插入likes_buckets_by_post表之前,您需要使用一致的哈希函数和指定数量的存储桶来计算bucket_id

var bucket = consistentHash(user_id, N)

在N是存储桶总数的情况下,该数目取决于您的条件:您拥有多少个Cassandra节点,您希望每个帖子有多少喜欢,这个数字越大,将散布用于存储的更多分区。

请注意,如果您需要为帖子要求所有赞,则必须执行N次请求,但对于您的情况,只需要一个请求即可检查单个用户(如一篇帖子)。

INSERT INTO likes_buckets_by_post (post_id, bucket_id, user_id) VALUES ('post_1', bucket, 'user_1' );

在选择数据之前,还需要使用与插入相同的参数来计算哈希值:

var bucket = consistentHash(user_id, N)

然后您可以检查喜欢发贴的用户:

SELECT * FROM likes_buckets_by_post WHERE post_id='post_1' AND bucket_id=bucket AND user_id='user_1';