【问题标题】:Database architecture question: 1 table per customer or 1 unique table for all customers数据库架构问题:每个客户 1 个表或所有客户 1 个唯一表
【发布时间】:2019-04-14 05:21:23
【问题描述】:

我们需要知道使用哪种数据库架构更有意义以及为什么。

我们有一个客户列表,他们都将使用相同的表结构(极少数例外)。

我们将有大约 10,000 个客户,每个客户可能都拥有大约 50,000 种产品。

每个客户对产品的处理可能并不相同,我们还希望提供一个计划,让客户可以通过 API 访问他们的数据。

我们的客户确实销售产品,他们的 SQL 表结构都将包含以下列:

  • Feed_ID
  • Product_ID
  • 产品描述
  • 价格
  • 重量
  • 等等...

Feed_ID 用于区分这些产品的来源,并且对于每个客户来说都是独一无二的 - 当然。

我们想过的关系表结构的3种选择:

  1. 每个客户都有自己的数据库,在该数据库中,每个产品馈送都有 1 个表

  2. 所有客户都托管在 1 个唯一的数据库下,所有客户在该数据库下每个提要都有 1 个表 - 在这种情况下,如果 1 个客户作为 2 个不同的产品提要,他可以有 2 个表。

  3. 所有客户都托管在 1 个唯一的数据库中,但是,在第 3 个解决方案中,我们只有 1 个唯一的表来托管所有客户的所有产品提要。

您会使用哪种解决方案以及为什么您认为您选择的解决方案更好?

谢谢。

【问题讨论】:

  • 选项 #3 是唯一有意义且可远程扩展的选项。不要使用前两个选项。
  • 没有好坏之分。这一切都取决于您的要求。客户的数量是多少,他们的生命周期是什么(是否会添加),您是否始终为所有客户提供相同的功能,您将如何管理每个客户的错误修复等等。虽然 @TimBiegeleisen 是针对选项 #3 作为默认设置,例如,如果是多租户设置,客户应该只能访问他们的数据,您也可以选择选项 #2。例如,这将使您的客户管理彼此独立。
  • 谢谢你们两位的cmets。我们将有 10,000 个客户,每个客户可能都拥有全部 50,000 种产品。解决方案 3 中的 1 个巨大的 SQL 表很有吸引力,但是总是为任何客户访问同一个表可能会带来一些性能问题,而且如果由于某种原因该表被损坏,那么所有客户都会失去访问权限。此外,如果该唯一 SQL 表被黑客入侵,黑客就可以访问该表的所有客户数据。即使这样,我仍然不确定哪种解决方案最好?
  • 嗨。这是一个常见问题解答。请始终在谷歌上搜索您的问题/问题/目标的许多清晰、简洁和特定的版本/措辞,带和不带您的特定字符串/名称,并阅读许多答案。将您发现的相关关键字添加到搜索中。如果您没有找到答案,请发布,使用 1 个变体搜索作为标签的标题和关键字。请参阅向下投票箭头鼠标悬停文本。如果您确实有要发布的非重复代码问题,请阅读并在minimal reproducible example 上采取行动。 PS请通过帖子编辑澄清,而不是评论。

标签: sql database-design product


【解决方案1】:

您没有提供足够的信息。在几乎所有情况下(请参阅下文了解例外情况),您都需要为所有客户提供一组表格。以下是一些原因:

  • 性能。表的激增意味着数据分布在更多的数据页中,因此您有许多部分填充的数据页。数据库更大,处理速度更慢。
  • 编码效率。如果客户的表都有不同的名称,那么所有代码​​都是动态 SQL。这更难维护。
  • 维护。当有无数类似的表时,添加列或索引是非常困难的。
  • 分析。当类似的数据通过表格传播时,很难回答诸如“哪个客户的产品最多?”之类的问题。
  • 安全。授予对一组表的访问权限比授予数以万计的表更不容易出错。

毫无疑问,我错过了几个原因。您可以看到,拥有一个包含少量表的单一数据库几乎是不费吹灰之力。

在某些情况下可能需要单独的数据库。我想不出一个很好的理由来为单个数据库中的每个客户端提供单独的表。

首要原因是安全和隔离。将数据存储到“物理上”独立的数据库中可能存在商业甚至法律原因,以进一步减少一个客户看到另一个客户数据的可能性(意外或通过黑客攻击)。

另一个原因是客户是否有定制的解决方案。也就是说,有每个客户端的自定义。我仍然倾向于尝试将其放入单个数据库解决方案中,但这可能是不可能的。

与此相关的是您打算在云端和本地同时支持的应用程序。在这种情况下,每个客户端单独的数据库可能会简化应用程序设计。

但是,一般来说,您会将数据存储在一个非常规范化的单一数据库中,每个实体一个表。

【讨论】:

  • 我同意我们在问题中没有提供足够的细节。我爱你的回复,我觉得/同意 1 table-for-all 方法非常有吸引力。但是:访问 1 个大表真的比 10K 表提供更好的性能吗?安全?使用 1 张桌子,您需要将其设置为创纪录的水平,这不是更具挑战性吗?关于“动态 SQL”,你真的会在所有代码中硬编码该表的名称吗?跨 10K 表更新列名或其类型将是一场真正的噩梦,是的,我同意。使用每客户一张桌子的方法有什么好处?
  • 嗯...在共享租赁中,如果您有 10 个客户端,那么拆分模式以使每个客户端都有自己的表可能是完全合理的,特别是如果每​​个客户端都在存储该表中有数亿条记录。有很多优点。例如,迁移客户端数据更简单,因为它们都分组在一个表中。您存储的数据更少,因为您不需要表中的“client-id”列......它已包含在表名中。脚本解决了“维护”问题。这些表仍然很大,单独的,所以它们没有碎片化。索引更浅。
  • 基本上,如果您有大量客户,每个客户都只有少量数据,那么这篇文章的建议是很好的。但是,如果您有少数客户,每个客户都有大量数据,这不一定是好建议。在后一种情况下,将数据分段到每个客户端每个实体的一个表中实际上可以提高性能、简化维护(迫使您以可重复的方式编写脚本,无论如何您都应该这样做)等等。您仍然希望这些客户端在同一台服务器上以及共享资源的所有要点(如果资源耗尽,显然是单独的服务器)。
  • @Triynko 。 . .您可以轻松地使用表分区来提高性能(大多数数据库都支持这种功能)。如果数据存储在单个数据库中,那么它已经被组合用于备份/恢复目的,并且可能还用于安全性(取决于数据库)。如果是这样,它可能应该在一张桌子上。如果要拆分客户端数据,请将其拆分为单独的数据库。
【解决方案2】:

我认为为每个客户提供单独的表(或理想情况下的模式)并不是一个坏主意。除了您提到的好处之外,您还可以通过这种方式轻松扩展数据库,并且可以让客户完全控制他们的数据,如果他们愿意的话。

关于缺点:

  • 管理它更复杂,但也没有那么糟糕 - 你可以写 创建列/表/索引/等的脚本。你 不必手动操作。
  • 对 10K 表执行分析将是一项挑战, 尽管无论如何将它与生产混合并不是最好的主意。 我会为分析创建一个单独的数据库(或服务器),运行 一些通宵更新报表的工作。

此外,如果您的表格将有数亿行(10Kx50k?),那么无论您选择哪个选项,都最好将其拆分为更小的部分。如果不是按客户,那么按地区或其他更大的组(假设您正在构建本地 RDBMS)

【讨论】:

  • “如果您的表将有数亿行(10Kx50k?),最好将其拆分成更小的部分”。这完全是错误的,表明对数据库及其扩展方式完全缺乏了解。
  • 在我看来,较小的表大小不会提高性能,因为没有硬盘驱动程序可以同时访问 2 个不同的 HD 空间。如果将这些“拆分”表放置在完全不同的服务器上,性能将会提高。同样,如果文件太大,则意味着太多客户使用同一个文件,意味着同时有太多请求,所以可以拆分,然后将其他文件移动到不同的服务器。
猜你喜欢
  • 1970-01-01
  • 2011-02-17
  • 2017-05-03
  • 2013-07-16
  • 1970-01-01
  • 1970-01-01
  • 2015-10-07
  • 2012-02-01
  • 1970-01-01
相关资源
最近更新 更多