【问题标题】:NoSQL partitioning on non-primary key非主键上的 NoSQL 分区
【发布时间】:2024-01-19 12:48:01
【问题描述】:

我正在设计一个使用 NoSQL 数据库(如 MongoDb/Cassandra)的聊天应用程序。 对时间最敏感的查询是查找属于聊天的消息。

我知道会有一个Message 集合,但不确定如何根据 chatId 对这个集合进行分区。我想即使clustered index 也不适合这种类型的用例。

假设Message 将遵循以下结构:

{
  "chatId"  : 123,
  "messageId"      : 456,
  "text"    : "Hello World!"
}

我认为唯一的方法是在messageId 上进行分区并在所有分区中搜索聊天消息。

【问题讨论】:

  • "在所有分区中搜索聊天消息。"由于一个分区中的所有数据都保证在同一个节点上,因此查询多个分区会命中多个节点。在 NoSQL 中,查询时间就是网络时间,而在大型集群中,“搜索​​...在所有分区中”是一个糟糕的设计。事实上,我希望你是查询而不是搜索

标签: mongodb cassandra nosql partitioning


【解决方案1】:

在我看来,用于消息传递应用程序的传统 RDBMS 架构应该如下所示。

聊天

身份证
参与者ID

消息

身份证
聊天ID
来自_id
文字

我猜您可能不想使用 RDBMS 数据库,可能是因为某些基础设施限制,但我会认真建议您考虑使用它。
如果我必须为像 Cassandra 这样的 NoSQL 系统设计类似的东西,我会尝试尽可能地对数据进行非规范化,并根据最常用的查询设计模式。

我将创建一个带有架构的表:
聊天ID
message_id
消息文本
主键(chat_id,message_id)

这里 chat_id 是分区键,message_id 是集群键。您可以通过chat_id查询得到分区内所有聊天相关的消息。另外,我将使用 TimeUUID 作为消息 ID,这将有助于在聊天中获取最新的 N 条消息,因为您可以在集群键上运行限制过滤器。
如果您还希望通过消息 ID 查询消息的功能,您可以在主表上创建一个以 message_id 作为主键的视图。

【讨论】:

  • 没错! RDBMS 可以很好地处理这样的事情。
最近更新 更多