我有一个我想要重建的会员数据库。每个成员在主成员表中有1行。从那里我将使用JOIN来引用其他表中的信息。我的问题是,对于以下方面的表现会更好:
1个数据表,指定数据类型,然后指定数据。例如:
data_id | member_id | data_type |数据
1 | 1 |电子邮件| test@domain.com
2 | 1 |电话| 1234567890个
3 | 2 |电子邮件| test@domain2.com
或
最好是制作一张包含所有电子邮件地址的表格,然后是所有电话号码的表格等,然后使用具有多个连接的select语句
请记住,此数据库将从成员表中的超过75000行开始,实际上将包括电话,电子邮件,传真,名字和姓氏,公司名称,地址城市状态zip(意味着每个成员至少会有)每个中的一个但可以有多个(通常每个成员1-3个),所以超过75000个电话号码,电子邮件地址等)
所以基本上,加入超过750,000行的1个表或加入7-10个超过75,000行的表
编辑:当我们插入需要与数据库中的现有数据匹配的销售数据时,此数据库的性能会成为一个问题,因此请获取10k行销售和联系人数据的CSV文件并查询数据库以尝试查找CSV中哪个销售行的成员属性?哦,是的,这是在网络服务器上完成的,而不是本地机器(不是我的选择)
答案 0 :(得分:1)
这种结构的明显方法是为每个数据项(电子邮件,电话等)设置一个表,您需要跟踪它。如果某个特定数据项每个成员可以出现多次,那么它取决于该项与该成员之间关系的确切性质:如果该项可以自然发生多次,那么将它们放入其中是有意义的。一个单独的表,其中包含成员表的外键。但是,如果数据项可以在有限的固定角色集(例如,家庭电话号码和移动电话号码)中多次出现,那么在成员表中为每个角色创建一个不同的列更有意义。
如果您遇到此设计的性能问题(个人而言,我认为75000不是那么多 - 如果您有索引来正确支持您的查询,则不会出现问题),那么您可以对数据进行分区。 Mysql支持本机分区(http://dev.mysql.com/doc/refman/5.1/en/partitioning.html),它基本上将行集合分布在不同的物理隔离专区(分区)上,同时保留一个逻辑隔离专区(表格) )。这里的一个明显优势是你可以继续查询逻辑表,而不需要从几个地方手动汇总数据。
如果您仍然不认为这是一个选项,您可以考虑垂直分区:即,将列组甚至单个列放在它们自己的表中。如果您有一些查询始终需要一组特定的列,而其他查询倾向于使用另一组列,则这是有意义的。只有这样才能应用这种垂直分区,因为连接本身会降低性能。
(如果你真的遇到了数十亿,那么你可以考虑分片 - 也就是说,使用单独的数据库服务器来保留行的分区。这只有在你可以快速限制你的分片数量时才有意义需要查询以查找特定的成员行,或者您是否可以有效地并行查询所有分片。就我个人而言,您似乎不需要这样。)
我强烈建议不要制作单个“数据”表。这基本上会将每个自然地分成一列的东西展开。这需要一大堆连接,并且复杂化写入否则将是非常简单的查询。不仅如此,它还几乎不可能为您的数据创建适当,高效的索引。最重要的是,它使得很难对数据应用约束(比如根据类型强制执行数据类型和数据项的长度)。
有一些极端情况下这样的设计可能有意义,但提高性能不是其中之一。 (参见:entity attribute value antipattern http://karwin.blogspot.com/2009/05/eav-fail.html)
答案 1 :(得分:0)
在谈到数据库时,你应该研究scaling out
vs scaling up
。除了上述研究之外,如果您不期待大量数据,我建议您在我们的案例中使用一个表格。如果是,请在数据库设计中查找dimensions
。
答案 2 :(得分:0)
对于数据库来说,75k真的没什么。您可能甚至没有注意到那些索引的好处(索引无论如何:))。
重点是,尽管您应该了解“横向扩展”系统,但大多数包含MySQL的数据库都可以通过分区来解决这个问题,从而使您的数据访问代码仍然可以真正声明,而不是编程,因为您要解决的是哪个对象/查询。重要的是要注意分片与分区,但老实说,当你开始超过接近9+位数而不是5 +位数的记录时会进行对话。
答案 3 :(得分:0)
两者都不使用 虽然第一种选择的变体是正确的方法。 创建一个“查找”表,用于存储数据类型的值(邮件,电话等...)。然后使用“数据”表中查找表中的id。 这样你实际上有3个表而不是2个。 它是一种经典的多种关系的最佳实践,例如