从rdmbs到cassandra-当前用户喜欢被查询的帖子吗?

zfciruhq  于 2021-06-10  发布在  Cassandra
关注(0)|答案(1)|浏览(325)

我正在尝试解决如何在cassandra中创建模型,以便以某种有效的方式(可能是单个查询)获取信息当前登录的用户是否喜欢post以及post数据。在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"
zbq4xfa0

zbq4xfa01#

实现这一点的最简单方法是通过\u post创建类似于\u的表:

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 是一个合成字段,负责为同一个post的不同用户生成不同的分区密钥。 bucked_id 应该是基于 user_id 现场。一致性哈希提供了基于指定用户id在指定范围内生成一些数字的能力(例如guava java库提供了一致性哈希函数)
在将数据插入到 likes_buckets_by_post 需要计算的表 bucket_id 通过使用一致的哈希函数和指定数量的bucket:

var bucket = consistentHash(user_id, N)

其中n是bucket的总数,这个数字将取决于您的条件:您有多少cassandra节点,每个post您期望有多少个like,这个数字越大,用于存储的分区就越多。
请注意,如果你需要为一篇文章请求所有like,你将不得不执行n个请求,但对于你的情况,只需要一个请求就可以为一篇文章检查单个用户like。

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)

然后你可以检查一个用户,比如post:

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

相关问题