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

问题描述 投票:0回答:1

我正在尝试研究如何在Cassandra中创建模型,以便以一种有效的方式(可能是单个查询)获取信息,无论当前登录的用户是否喜欢发布以及发布数据。在RDMBS中它很容易,但我无法理解如何在Cassandra中完成它。

以下是我在Cassandra上尝试在RDBMS上实现的示例:

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"
database-design cassandra nosql cql
1个回答
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'; 

但这个approch有一个缺点 - 如果你期望很多用户喜欢每个帖子(数百万或数十亿),这个表将有太大的分区,它将导致糟糕的性能和残疾存储这么多喜欢每个帖子。 Cassandra每个分区键限制为2亿行。

在这种情况下,您可以使用复合主键将此单个帖子的相关信息传播到多个分区(此方法通常称为Consistent Hashing):

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' );

在选择数据之前,您需要使用与insert相同的参数计算哈希值:

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';
© www.soinside.com 2019 - 2024. All rights reserved.