REST API 的完美数据模型

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

我创建了一个 REST API,其架构如下所示:

type Todo struct {
    ID          gocql.UUID    `json:"id"`
    User_ID     string        `json:"user_id"`
    Title       string        `json:"title"`
    Description string        `json:"description"`
    Status      string        `json:"status"`
    Created     time.Time     `json:"created"`
    Updated     time.Time     `json:"updated"`
}

因此,当我使用 CQL 时,主要所有函数查询都根据 ID 进行过滤,但在一个查询中,我必须使用 DESC 中的“Status”上的 where 子句和“Created”排序,如下所示:

SELECT id, user_id, title, description, status, created, updated FROM todos WHERE status = ? ORDER BY created

目前我正在使用以下型号:

CREATE TABLE todos (
    id UUID,
    user_id TEXT,
    title TEXT,
    description TEXT,
    status TEXT,
    created TIMESTAMP,
    updated TIMESTAMP,
    PRIMARY KEY((status, created), id)
);

但是使用这个我遇到了过滤错误。完美的表创建应该是什么,这样我就可以毫无问题地执行所需的操作

期待一些好的回应来解决我的问题

rest go cassandra cql scylla
1个回答
0
投票

过滤错误是因为分区键是状态和创建这两个值的复合键。因此,从分区的角度来看,它们被散列为单个值。通过仅提供密钥的 1 部分,它将被迫扫描所有分区。

您的最初反应是将主键更改为:

PRIMARY KEY((status), created, id)

双括号不是必需的,但我保留它们是为了让变化显而易见。不过,状态的基数值很可能非常低,这会导致单个分区内的记录数量非常多 - 这是不可取的。

您可能会想使用二级索引 - 但这会遇到同样的问题(物化视图也是如此)。基数问题需要解决。

我希望以某种形式使用时间桶,例如:

  PRIMARY KEY((status, time_bucket), created, id)

其中 time_bucket 是时间戳字段,它是应用程序提供的已创建字段的截断版本,例如周、天甚至小时。您应该知道要在哪个时间段内搜索,或者要并行搜索的多个时间段,并在应用程序代码中构建最终的有序答案。要使用的截断级别应基于您期望在一段时间内每个状态的数据量。

这增加了分区键的基数并将其分布在集群内的节点上。

如果没有更新,TWCS 将是一个可行的选择,但结构中更新字段的存在表明情况并非如此。

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