1

我目前正在开发一个多租户系统,该系统的核心功能允许用户定义自定义类型。例如,他们将定义一个事件、帐户、订单、发货,无论他们选择什么。系统中的每个用户都将根据字段对他们想要管理的内容有不同的定义。因此,对于一个用户,一个订单可能有一个订单号、状态和截止日期,而对于另一个用户,它可能有 10 个字段。

与我合作的开发人员希望使用 EAV 来存储这些数据。我反对这个想法。我已经阅读了这个网站以及整个互联网上的许多文章,列出了这种反设计模式的缺点,但没有提到我正在考虑采用的方法。我正在尝试构建此应用程序,使其从一开始就具有可扩展性。

当我做数学时,如果我有 1000 个租户,每个租户平均有 5 种类型(5000 种类型)。例如,每种类型都有 1000 条记录(5,000,000 条记录)。每条记录平均有 5 个字段,在 EAV 模型的最低级别,我总共有 25,000,000 行。

下游流程还将每个单独的用户数据绑定到 jquery 网格,因此首先获取这些数据并转置数据对我来说似乎成本很高。当你有 10k 租户或 50k 租户时会发生什么......我知道 MySQL 在优化后可以处理这种类型的事情,但它似乎就像我在自找麻烦。

我想用另一种方式来做。然而,我对我的提议有一种不好的直觉,因为它违背了我所知道的一切,所以我希望一些真正的具有实践知识的专家来验证或批评我的方法。如果您验证,请告诉我我需要做些什么来支持它并让它工作。如果你批评,请告诉我我在短期和长期会遇到的陷阱。

我的建议。

  1. 使用域分区对系统进行分片,以便在任何特定分片中都有最大的租户集。主目录将引用哪个租户属于哪个分片
  2. 对于每个 Shard,当用户定义一个类型时,创建一个新表来保存该类型。在分片中保存一个映射表,它将用户链接到他定义的类型(自定义表)。

这实质上意味着我将在一个分片中拥有一些核心表和 1000 个自定义表。

现在对我来说,通常在数据库中有这么多表通常会告诉我架构有问题或者设计不正确,但是对于这种情况,我只是想知道这是否是一种可行的方法。在我之前的示例中,这意味着我在分片中有 5000 个表,每个表只有 1000 行。在我看来,这似乎比使用 EAV 更好。根据用户,您可以找到类型并将数据绑定到网格。

需要考虑的一些注意事项

  1. 多租户架构允许用户拥有自己的用户。所以可能我有 1000 个订阅者,但有 5000 个用户。所以需要管理数据库连接。我会遇到管理连接的问题吗?

  2. 我会遇到与表缓存相关的问题吗?我会在刷新表时遇到问题吗?

  3. 这种设计在哪里可以解决性能问题?我知道主目录数据库可能是一个瓶颈,但是这个数据库的负载不会太重。

  4. 已经开始开发了,别叫我换NoSQL数据库!

另一个建议是在分片内继续使用 EAV。你觉得这个想法怎么样?

请不要拉任何拳!我需要听到这一切。提前致谢。

4

1 回答 1

1

我认为在扩展数据方面,您会发现管理数千个相对较小的自定义表会比使用 EAV 做得更好。我曾为在单个 MySQL 实例上拥有超过 100,000 个表的客户提供咨询。

当您在一个实例上拥有数以万计的表时,您会遇到不同的可伸缩性问题,但是如果您已经拥有支持分片的架构,您就可以进一步细分用户,这样您就不会拥有太多任何一个实例。

目录表非常适合放入缓存(例如 memcached),因为用户到分片实例的映射很少更改。这将减少目录上的负载。

我还将研究 MySQL 的目录分区,以及将用户映射到他们的自定义表的表。以及任何其他常见(非自定义)表。您可以通过用户 ID 对其中的任何一个进行分区,并依靠分区修剪来使多租户表像小得多的表一样工作。

于 2013-03-05T05:02:16.597 回答