我正在创建一个包含30-50列的表格。这些行大约有200K。是否建议将此数据存储在单独的表中?如果有这么多列,是否存在性能问题。
我会解释一下这张桌子。我必须存储过去10年的所有体育比赛(篮球,棒球,足球,曲棍球)。对于其中的每一个,我需要保留其他数据。其中一些数据允许我重复使用各种体育领域。例如,每个团队都有一个主客场球队和一个赛事日期。
但是,对于这些游戏中的每一个,我还会存储诸如首次下降的次数,多少三振出局以及三个指针。显然,此数据仅涉及表中的某些行。因此,我最终在每一行中都有很多NULL字段。
如有必要,我可以提供更多细节。提前感谢任何一般建议。
答案 0 :(得分:7)
要详细说明 RichardOD 的答案,在处理子类型时通常有三个选项,您选择的选项取决于您对相关数据的处理方式。
第一个选项是您当前使用的选项:将所有与不同类型相关的列保留在一个表中,使用标志和空值来指示给定记录的类型。这是管理子类型的最简单方法,当您只有几种类型或者不同类型不是很不同时,它通常很有效。在你的情况下,似乎类型可能会有很大差异。
第二个选项是保留一个包含子类型之间所有公共列的中央表,并与包含这些类型的特定于类型的详细信息的其他表具有一对一的关系。
第三种选择是根本不考虑不同的类型作为子类型,只是将所有类型的记录保存在不同的表中。因此,在保存公共数据的类型之间没有公用表,并且每个表都有一些在表之间重复的列。
现在,每个选项都有它的位置。当不同类型之间没有太多差异时,您可以使用第一个选项。如果您需要独立于特定于类型的字段操作公共字段,则可以使用第二个选项;例如,如果您想在一个包含一般信息的大网格中列出所有体育比赛,然后让用户点击查看该游戏的特定类型细节。当类型根本不是非常相关时你会使用第三个选项而你只是为了方便而将它们存储在一起;不同的模式,即使它共享一些字段,也不应该合并。
那么请考虑一下您需要对数据做些什么,以及它如何适应这三个选项并自行决定哪个是最好的。如果您无法决定,请使用有关您计划如何使用数据的详细信息更新您的问题,我或其他人应该能够为您提供更多帮助。
答案 1 :(得分:6)
我认为问题是你有一个model like this(存储一个表中的所有方法)。 This approach以及this approach是您可以选择的两种选择 - 我相信其他人会有更多建议。
他们都有自己的优点和缺点。我不能在MySql中评论它们的性能特征,但肯定其他方法减少了null的使用,这只能是一件好事。
如果您真的对3种方法之间的差异感兴趣,我建议您购买Martin Fowler的企业应用程序架构模式书。
就性能特征而言,您可能希望查看问题like this one和also this one。
答案 2 :(得分:2)
是的,如果有意义,请使用大量列。如果你没有使用像“field1,field2,field3”等反模式,那就没关系了。
很多NULL很好,它们不会伤害太多。另外200k是如此微小的行数,你不太可能看到许多性能问题。我不知道你打算在这个表中做多少个插入,但如果它是<每秒100,我没有看到任何问题。
你想要以某种方式索引它。索引的数量会影响插入性能,但我想大多数列都不需要编入索引。
有了这么小的桌子,它并不重要 - 没有一个。您可以无数次复制数据,而不会遇到任何空间问题 - 您处于特权位置。
答案 3 :(得分:2)
200K次50个值并不是一个巨大的表。在你拥有易用性和免于控制自我矛盾的事情之前,不要担心性能。
分解表格有多种原因。分解表意味着将其拆分为两个或多个表,其中大多数列只进入一个表,其他列进入多个表(外键)。
Farell提到了正规化。规范化的主要好处是它排除了某些类型的更新异常,包括允许将相互矛盾的事实存储在同一个表中的异常。存储优势是次要的。性能优势(如果存在)可能很小。话虽如此,规范化是您可以了解的关于表格设计的最重要的事情。如果你在不了解后果的情况下违反规范化规则,你就会失明。
如果我被介绍到一个包含40列或更多列的数据库表,并且数据库中存在任何类型的问题(性能,损坏或其他),我会研究该表是否可以进一步规范化,以及是这样做的成本/利益。
分区表有多种原因。正如Reinerpost所说,在你控制正常化之前,不要开始担心分裂。
答案 4 :(得分:0)
我肯定会看normalizing the table。虽然我不确定性能优势,但很可能会有大量条目的存储优势。
我的第一个改变是拥有与1或2项运动相关的任何数据,并将它们放在具有主表中的外键的单独表格中