我曾多次遇到以下困境,并有兴趣了解其他人如何解决这个问题,或者是否有规范的方式可以解决这个问题。
在某些领域,人们自然会考虑非常广泛的表格。例如,进行多年发展的时间序列调查。此类调查可能包含数百个(如果不是数千个)变量。通常虽然可能只有几千或几万行。将这样的结果集视为一个表是绝对自然的,其中每个变量对应于表中的一列,但是,至少在SQL Server中,一个限于1024(非稀疏)列。
显而易见的解决方法是
ResponseId
,VariableName
,ResponseValue
第2号。我认为由于多种原因(难以查询,次优存储等)非常糟糕,所以真正的首选是我看到的唯一可行选择。可以通过将可能一起查询的列分组到同一个表中来改进这种选择 - 但在实际使用数据库之前,人们无法真正了解这一点。
所以,我的基本问题是:有没有更好的方法来处理这种情况?
答案 0 :(得分:1)
嗯,这真的取决于你用它做什么。如果你想保持表的宽度(可能是OLAP或数据仓库),我会使用适当的索引。同样基于更频繁选择的列,我也可以使用覆盖索引。基于更频繁搜索的行,我还可以使用筛选索引。如果有,比方说,表中有数十亿条记录,你也可以对表进行分区。
如果您只想将表存储在多个表中,请务必使用适当的规范化技术(可能高达3NF或3.5NF)将大表分成较小的表。我会使用你的第一种方法,规范化来存储大表的数据,因为它似乎对我来说更有意义。
答案 1 :(得分:1)
您可能希望在表格前放置一个视图,使它们看起来好像是一个表格。好处是您可以在以后重新安排存储而无需更改查询。缺点是只能通过视图对基表进行修改。如有必要,您可以使用常用修改的存储过程来缓解此问题。根据您的时间序列调查的用例,听起来插入和选择比更新或删除更频繁,因此如果您需要在以后重新安排事情,这可能是保持灵活性而不强迫客户更新的可行方法。 / p>
答案 2 :(得分:0)
这是一个古老的话题,但我们正在努力解决这个问题。上述答案中的任何一个都没有给我们认为的解决方案带来多少好处。
我们之前认为拥有宽大的桌子并不是一个真正的问题。花了很多时间分析这个,我们已经看到了光,并意识到插入/更新的成本确实失控。
正如John所述,解决方案实际上是创建一个VIEW来为您的应用程序提供一致的架构。在我们的案例中,任何重新设计的挑战之一可能是,您有数千或数百行代码引用旧的宽表,并且您可能希望提供向后兼容性。
视图也可以用于UPDATES和INSERTS,正如约翰所暗示的那样,但是我们最初发现的一个问题是,如果你采用可能有数百列的myWideTable
的例子而你想将它拆分为{ {1}}列myWideTable_a
,a
和b
以及c
列myWideTable_b
,x
和y
插入仅设置列z
的视图只会插入a
当您想要稍后更新记录并设置myWideTable_a
时,这会导致问题,因为这会失败。
我们采用的解决方案和性能测试就是要有一个'而不是'触发视图插入以始终插入到我们的拆分表中,以便我们可以继续更新或从视图中读取而不受惩罚。
关于在插入上使用此触发器是否提供比宽表仍然打开更多的开销的问题,但很明显它将改进对每个拆分表中的列的后续写入。