为不同的用户创建多个表是否更有效?

Is it more efficient to create multiple tables for different users?

标题不是很具体,所以我会详细说明。

我正在开发一个数据库系统,用户可以通过 watered-down API.[=12= 向 postgres 数据库添加数据]

至此,所有用户的数据都汇总为一个table,结构类似这样:

CREATE TABLE UserData (
    userId int NOT NULL,
    dataId int NOT NULL PRIMARY KEY,
    key varchar(255) NOT NULL,
    data json not NOT NULL,
);

但是,我认为给每个 userId 一个它自己的可能更有效(和更快的查询)table:

CREATE TABLE UserData_{userId} (
    dataId int NOT NULL PRIMARY KEY,
    key varchar(255) NOT NULL,
    data json not NOT NULL,
);
CREATE TABLE UserData_{anotherUserId} ();
etc...

但是我担心这会阻塞数据库。

各自的优缺点是什么?在什么 load/speed 要求下每个都能很好地发挥作用?对于 high-load、high-speed 场景,您认为其中哪一个更好?

您的建议本质上是 partitioning,因此我建议您阅读相关文档。当您的每个操作都覆盖一个分区的大部分时(即 select 一个用户的所有数据,或删除一个用户的所有数据),这主要是有利的。

然而,大多数用例都可以通过正确索引 table 得到更好的服务。它的结构要简单得多,而且性能非常好。如果您的所有查询都是针对单个用户的,那么您将希望所有索引都以 userId 列开头,而 postgres 将使用它们来有效地仅访问相关行。如果有一天你想跨多个用户查询数据,这样做会容易得多。

不过,我建议您不要相信我的话。创建两个结构,生成假数据来填充它们,看看它们的行为如何!

考虑:

  • 如果每个用户有一个,您最终可能会得到 x 个 table。您期望有多少“用户”?
  • json 数据未绑定,可能会随着 solution/app 的增长而增长。您将如何处理丢失的 keys/values?
  • Users table 将水平增长(更多列),而您应该始终以垂直增长(更多行)为目标

更好的解决方案是将您的数据保存在与 user_id 相关的 table 中。 IE。一个“键”table,其中包含键 date_added、活动键和外键 (user_id)

这也将解决将数据保存为 json 的问题,在您的示例中,这将难以维护。而是将 json 打开到 table 中,您可以在其中受益于索引和集群。


如果您在单独的 table 中引用您的 user_id 作为外键,您可以在该键上对这些 table 进行分区或集群,以显着提高速度并补偿增长.这意味着您有一个 users 的 table(id、名称、活动、created_at、...)和许多链接到该用户的 table,例如。 subscriptions (id, user_id, ...), items (id, user_id, ...), things (id,user_id, ...)