1

我有一个要重建的会员数据库。每个成员在主成员表中都有 1 行。从那里我将使用 JOIN 来引用其他表中的信息。我的问题是,什么对以下性能更好:

1 个数据表,指定数据类型,然后指定数据。例子:

数据ID | 会员编号 | 数据类型 | 数据
1 | 1 | 电子邮件 | test@domain.com
2 | 1 | 电话 | 1234567890
3 | 2 | 电子邮件 | test@domain2.com

或者

制作一个包含所有电子邮件地址的表格,然后制作一个包含所有电话号码等的表格,然后使用具有多个连接的 select 语句会更好吗

请记住,此数据库将从成员表中的 75000 多行开始,实际上将包括电话、电子邮件、传真、名字和姓氏、公司名称、地址城市州邮编(意味着每个成员至少有一个其中但可以有多个(通常每个成员 1-3 个),因此超过 75000 个电话号码、电子邮件地址等)

所以基本上,加入 1 个超过 750,000 行的表或加入 7-10 个超过 75,000 行的表

编辑:当我们插入需要与数据库中现有数据匹配的销售数据时,该数据库的性能成为一个问题,因此获取 10k 行销售和联系数据的 CSV 文件并查询数据库以尝试查找哪个成员CSV 中哪个销售行的属性?哦,是的,这是在网络服务器上完成的,而不是本地机器(不是我的选择)

4

4 回答 4

1

构建此结构的明显方法是为您需要跟踪的每个数据项(电子邮件、电话等)创建一个包含一列的表。如果一个特定的数据项可以在每个成员中出现不止一次,那么这取决于该项目与该成员之间关系的确切性质:如果该项目可以自然地出现可变次数,则将它们放入其中是有意义的具有成员表外键的单独表。但是,如果数据项可以在一组有限的、固定的角色(例如,家庭电话号码和手机号码)中多次出现,那么在成员表中为每个角色创建一个不同的列会更有意义。

如果您在此设计中遇到性能问题(我个人认为 75000 并没有那么多 - 如果您有索引来正确支持您的查询,它应该不会出现问题),那么您可以对数据进行分区。Mysql 支持本地分区 (http://dev.mysql.com/doc/refman/5.1/en/partitioning.html),它本质上将行集合分布在单独的物理隔间(分区)上,同时维护一个逻辑隔间(表)。这里的明显优势是您可以继续查询逻辑表,而无需手动将多个地方的数据捆绑在一起。

如果您仍然认为这不是一个选项,您可以考虑垂直分区:也就是说,将列组甚至单个列放在自己的表中。如果您有一些查询总是需要一组特定的列,而其他查询倾向于使用另一组列,那么这是有道理的。只有这样,应用这种垂直分区才有意义,因为连接本身会降低性能。

(如果你真的需要数十亿,那么你可以考虑分片——也就是说,使用单独的数据库服务器来保持行的分区。只有当你可以快速限制需要查询的分片数量时,这才有意义查找特定的成员行,或者您是否可以有效地并行查询所有分片。就我个人而言,您似乎不需要这个。)

我强烈建议不要制作单个“数据”表。这基本上会将自然是一列的每一件事分散到一行。这需要一大堆连接,并使编写原本非常简单的查询变得复杂。不仅如此,它还使得几乎不可能为您的数据创建适当、有效的索引。最重要的是,它很难对数据应用约束(例如根据数据类型强制执行数据类型和数据项的长度)。

在少数情况下,这样的设计可能有意义,但提高性能并不是其中之一。(参见:实体属性值反模式http://karwin.blogspot.com/2009/05/eav-fail.html

于 2012-04-12T00:00:22.283 回答
0

您应该研究scaling outscaling up数据库有关的情况。除了上述研究之外,如果您不期望大量数据,我建议您在我们的案例中使用一张表。dimensions如果你是,那么在数据库设计中查找。

于 2012-04-11T23:50:46.167 回答
0

75k对于数据库来说真的不算什么。您甚至可能没有注意到具有这么多索引的好处(无论如何索引:))。

重点是,尽管您应该了解“横向扩展”系统,但大多数数据库 MySQL 都可以通过分区来解决这个问题,从而允许您的数据访问代码仍然是真正的声明性与编程性,以确定您正在寻址/查询的对象。重要的是要注意分片与分区,但老实说,当您开始超过接近 9+ 位而不是 5+ 位计数的记录时,对话就是对话。

于 2012-04-12T00:22:13.783 回答
0

两者都不使用尽管第一个选项的变体是正确的方法。创建一个“查找”表,用于存储数据类型(邮件、电话等)的值。然后在“数据”表中使用查找表中的 id。这样你实际上有 3 张桌子而不是 2 张桌子。对于这样的经典多对多关系的最佳实践

于 2013-06-03T01:51:05.053 回答