动态创建表来存储用户内容是一个好主意吗?

4
我目前正在设计一个应用程序,用户可以创建/加入群组,然后在群组内发布内容。我正在尝试弄清楚如何将此内容存储在关系型数据库中的最佳方法。
选项1:为所有用户内容创建一个单独的表。该表中的一列将是groupID,指定发布内容所在的群组。使用groupID创建索引,以便快速搜索特定群组内的内容。所有内容读取/写入都将命中此单个表。
选项2:每当用户创建新群组时,我们动态创建一个新表。类似于group_content_{groupName}。所有内容读取/写入将路由到特定于群组的动态创建表。
选项1的优点:
  1. 使用单个简单查询操作单个表更容易跨多个群组搜索内容。
  2. 由于内容表是静态且定义明确的,因此更容易构建简单的跨表查询。
  3. 由于只有一个表需要维护,因此更容易实现模式更改和索引/触发器等更改。
选项2的优点:
  1. 所有读取和写入将分布在众多表中,从而避免了大量流量命中单个表可能导致的任何瓶颈(尽管所有这些表仍在单个DB中)。
  2. 每个表的大小都要小得多,可以更快地进行查找、模式更改、索引等操作。
  3. 如果将来想要分片数据库,则如果所有数据已经在不同的表中“分片”,则过渡将更容易。
从性能/开发/维护角度来看,上述2个选项的一般建议是什么?

我选择选项1。但如果您担心性能问题,请使用分区 https://www.postgresql.org/docs/10/static/ddl-partitioning.html - Juan Carlos Oropeza
3个回答

7

计算机领域中的一个重要错误是过早进行优化。本文作者是一位有20多年经验的DBA,他认为你正在高估这些组中将会发生的IO操作。关系型数据库(RDBMS)非常擅长在标准的表格集合内查询和写入此类信息。最坏的情况是,您可以稍后对它们进行分区。使用单个表格集合,您将拥有更多的搜索功能和管理便利性,而不是每个用户都有一组表格。

如果模式需要更改,您想要更新数百或数千个表格或编写一些长脚本来解决琐碎问题吗?坚持使用单个表格集合,并忽略分片(sharding)。相反,考虑“也许我们将来某天会对表格进行分区,如果必要”的想法。


4

这很简单, (1) 是正确的方法。

您将这些列为第二种方法的优化。所有这些都是误解。请参见下面的评论:

所有读取和写入将分布在众多表中,从而避免因大量流量击中单个表而导致的任何瓶颈(尽管可以承认,所有这些表仍在单个DB中)

读取和写入也可以轻松地在一个表中分布。唯一的问题可能是页面内的写冲突。那可能是相当微小的考虑,除非您处理每秒超过几十个事务。

由于下一项(部分填充的页面),使用单个表和大多数填充页面实际上更好。

每个表的大小都要小得多,可以更快地查找,更快地更改模式,更快地索引等

较小的表可能会导致性能灾难。表存储在数据页上。然后,每个表都是部分填充的页面。你最终会得到:

  • 在磁盘上浪费了很多空间。
  • 在页面缓存中浪费了很多空间--可以用来存储记录的空间。
  • 浪费了很多I / O读取部分填充的页面。

如果我们将来想要划分DB,则如果所有数据已经在不同的表中“分片”,转换会更容易。

Postgres支持表分区,因此您可以将表的不同部分存储在不同的位置。这应该足以实现扩展I / O负载的目的。


0

选项1:性能=正常 开发=简单 维护=容易

选项2:性能=快 开发=复杂 维护=困难

我建议选择选项1,对于大表格,您可以通过更好的索引或缓存索引(对于某些数据库)来管理性能,最后一件事是没有什么帮助使选项2成为可能,因为开发和维护时间是致命因素。


我怀疑选项2的性能不会比选项1更好。 - David Aldridge
我同意。在99%的情况下,我怀疑#2的性能不会明显更快。 - Joe Love

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接