如何正确创建用户消息表?

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

我在 Apache Cassandra 数据库中有一个包含用户通道的表。查询负责获取通道列表并获取有关通道的数据。其中一个查询需要ALLOW FILTERING,我们认为最好的选择是复制表,只有它有一个主键((channel_id,bucket),user_id),然后问题就出现了,是否有类似的东西Apache Cassandra 中的链接,以便数据库不必不断写入和更新两个表中的数据。如果您知道不需要这样做的解决方案,那么我将非常感谢该解决方案

create table channels
(
    user_id     bigint,
    bucket      int,
    channel_id  bigint,
    flags       int,
    permissions bigint,
    type        int,
    primary key ((user_id, bucket), channel_id)
)
SELECT * FROM channels WHERE user_id = :user_id AND bucket = :bucket
SELECT * FROM channels WHERE channel_id = :channel_id ALLOW FILTERING
cassandra cql
1个回答
0
投票

建议创建两个表并在应用程序级别进行管理。这就是所谓的非规范化;让我解释一下。

关于允许过滤

SELECT * FROM channels WHERE channel_id = :channel_id ALLOW FILTERING

此查询会扫描整个数据集,因为

channel_id
不是分区键的一部分。
ALLOW FILTERING
是 Cassandra 反模式。它会导致集群范围内的读取、超时和高资源消耗等低效率问题。

关于复制表格的建议

复制表是正确的方法,但您似乎正在寻找“链接”(如外键)来自动同步两个表。 Cassandra 不支持这一点,因为它不是关系数据库并且支持非规范化。

关于Cassandra本身

Cassandra 专为快速写入和水平扩展(写入优化)而设计。对于不同的查询模式,鼓励跨表复制数据,因为写入成本较低,但读取成本可能很高。 想象一下您的集群中有数百个节点。您希望查询在写入和读取数据时仅涉及最少量的节点,以便您可以在需要时轻松水平扩展。 Cassandra 的架构应该针对您的查询进行设计。如果您有两个查询(

user_id
channel_id
),您将需要两个具有适当主键的表来优化这两个查询。

建议的解决方案

创建两个表:

CREATE TABLE channels_by_user (
    user_id     bigint,
    bucket      int,
    channel_id  bigint,
    flags       int,
    permissions bigint,
    type        int,
    PRIMARY KEY ((user_id, bucket), channel_id)
);

CREATE TABLE channels_by_channel_id (
    channel_id  bigint,
    bucket      int,
    user_id     bigint,
    flags       int,
    permissions bigint,
    type        int,
    PRIMARY KEY (channel_id, bucket)
);

在应用程序级别同时写入两个表。由于 Cassandra 中的写入速度很快,因此这种重复不会显着影响性能。

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