为不同的用户创建多个表是否更有效?
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, ...)
标题不是很具体,所以我会详细说明。
我正在开发一个数据库系统,用户可以通过 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, ...)