在没有物化视图或二级索引支持的情况下,使用另一个查找表是否会对性能产生影响?

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

我有 2 个关于 AWS Keyspaces 的问题。

  1. 我有一个重要的表“帖子”,其结构如下:

    CREATE TABLE IF NOT EXISTS social_platform.posts (
        id UUID,
        user_id UUID,
        title TEXT,
        content TEXT,
        created_at TIMESTAMP,
        updated_at TIMESTAMP,
        content_media_url TEXT,
        user_username TEXT,
        user_first_name TEXT,
        user_last_name TEXT,
        user_profile_picture TEXT,
        user_role TEXT,
        PRIMARY KEY (id)
    );
    

    因为 AWS Keyspaces 目前不支持物化视图或索引,所以我想出了这样的解决方案:

    CREATE TABLE IF NOT EXISTS social_platform.posts_user_id_lookup (
        id UUID,
        user_id UUID,
        PRIMARY KEY ((user_id), id)
    ) WITH CLUSTERING ORDER BY (id ASC);
    
    

    现在我还可以搜索用户特定的帖子。

    这在性能方面是否有意义,或者是否有更好的解决方案来允许查询多个键?

  2. 显然帖子应该按created_at排序。目前我有另一个查找表:

    CREATE TABLE IF NOT EXISTS social_platform.posts_created_at_lookup (
        date_partition DATE,
        id UUID,
        created_at TIMESTAMP,
        PRIMARY KEY ((date_partition), created_at, id)
    ) WITH CLUSTERING ORDER BY (created_at DESC, id ASC);
    

    但是有了这个结构,我需要像这样获取它:

    const pageSize = parseInt(req.query.limit as string) || 10;
    const lastTimestamp = req.query.lastTimestamp ? new Date(req.query.lastTimestamp as string) : new Date();
    const datePartition = lastTimestamp.toISOString().split('T')[0]; // YYYY-MM-DD
    console.log('Date partition:', lastTimestamp);
    let query = 'SELECT id FROM posts_created_at_lookup';
    let params = [];
    
    if (lastTimestamp) {
        query += ' WHERE date_partition = ? AND created_at <= ? ORDER BY created_at DESC, id ASC LIMIT ?';
        params = [datePartition, lastTimestamp, pageSize];
    } else {
        query += ' WHERE date_partition = ? ORDER BY created_at DESC, id ASC LIMIT ?';
        params = [datePartition, pageSize];
    }
    
    const timeResult = await client.execute(query, params, { prepare: true });
    
    const orderedIds = timeResult.rows.map(row => row.id);
    
    if (orderedIds.length === 0) {
        return res.status(200).json([]);
    }
    const postsResult = await client.execute(
        'SELECT * FROM posts WHERE id IN ?',
        [orderedIds],
        { prepare: true }
    );
    
    const orderedPosts = orderedIds.map(id =>
        postsResult.rows.find(post => post.id.equals(id))
    );
    
    const lastPost = orderedPosts[orderedPosts.length - 1];
    const nextTimestamp = lastPost?.created_at || null;
    console.log('Next timestamp:', nextTimestamp);
    

    对我来说这似乎不是很聪明和快速。 但因为这是一种常见的做法,所以必须已经设计良好的逻辑,对吧?

amazon-web-services next.js cassandra cql amazon-keyspaces
1个回答
0
投票

从 Apache Cassandra 的角度来看,物化视图的更新是异步的,因此基表中写入的数据可能无法立即从视图中获得。

此外,使用 MV 也有一些注意事项,包括视图可能与基表不同步的风险,因此此功能始终被归类为实验性功能。我已经在 我们应该重新考虑在 Cassandra 中使用物化视图吗?.

中更详细地解释了这些内容。

相对于 Cassandra 的本机二级索引,如果您担心性能,特别是当您拥有大型数据集(大量帖子、大量用户)时,它可能并不理想。

您设计另一个表来检索用户的帖子的想法是正确的。您的数据模型很接近,但设计可以简单得多。

获取按用户 ID 分区的帖子表,按时间倒序排序:

CREATE TABLE posts_by_userid (
    userid uuid,
    created timestamp,
    postid uuid,
    title text,
    content text,
    ...
    PRIMARY KEY (userid, created)
) WITH CLUSTERING ORDER BY (created DESC)

要检索特定用户的帖子,请运行:

SELECT postid, title, content FROM posts_by_userid
    WHERE userid = ?

此查询将首先返回最新的帖子,然后您可以翻阅结果以检索较旧的条目。

当然,每当用户创建新帖子时,您的应用程序都必须更新多个表,但这只是批处理

INSERT
的简单问题。有关详细信息,请参阅我的另一篇文章“如何使非规范化表中的数据保持同步”。干杯!

© www.soinside.com 2019 - 2024. All rights reserved.