我正在考虑数据库设计问题。
例如,我正在设计这个stackoverflow网站,我有一个问题列表。
每个问题都包含某些可能不会改变的元数据。 每个课题还包含将持续变化的某些数据(最近查看日期,总观点等)
使用主表来读取常量元数据和进行连接会更好吗? 并将变化的值保存在不同的表中?
OR
将所有内容保存在一个表中会不会更好。
我不确定是否是这种情况,但是在更新时,ROW会锁定吗?
答案 0 :(得分:6)
在设计数据库结构时,最好先normalize,然后在对查询进行概要分析和基准测试后更改性能。规范化旨在防止数据重复,提高完整性并定义数据之间的正确关系。
请记住,执行加入也需要付出代价,所以很难说你的想法是否会有所帮助。使用规范化结构进行适当的索引会更有帮助。
关于行级锁,这取决于存储引擎 - 有些使用行级锁定,有些使用表锁。
答案 1 :(得分:4)
您的初始数据库设计应仅基于概念和关系考虑因素,完全独立于物理因素。数据库软件旨在支持良好的关系设计。你几乎不需要放松那些处理性能的考虑因素。首先,不要考虑连接,锁定和活动类型的成本。然后,进一步推迟这些考虑,直到探索了所有其他途径。
你的rdbms是你的朋友,而不是你的对手。
答案 2 :(得分:0)
您应该将两个表分开,因为您可能想要记录问题的历史记录。主问题表由问题ID索引,然后状态表由查询ID和日期/时间戳索引,并且每次状态更改时都包含一行。
除非您使用悲观锁定,否则行将被锁定一段时间,不知道更新是否非常重要。
答案 3 :(得分:0)
我会考虑使用Asp.net缓存或使用MemCached在本地缓存您的结果。
答案 4 :(得分:0)
如果您使用的是Oracle,这肯定是一个坏主意。在Oracle中,您可以非常愉快地读取记录,而其他会话正在修改它们,因为它具有多版本的可靠性控制。如果没有节省,您可能会因为加入而产生额外的性能损失。
然而,一个有用的设计模式是预先连接表,预先计算聚合或预先应用使用物化视图的where子句。
答案 5 :(得分:0)
如前所述,最好从干净的标准化设计开始。稍后更容易反规范化,而不是反过来。经验告诉你,你永远不会对那张大桌子进行反正规化!您只需根据需要添加更多列。而且您将需要越来越多的索引和更新将变得越来越慢。
你还应该看看预期的负载:会有更多的新答案还是更多的查询?您还有其他什么操作?在优化方面,您可以使用dbms系统的功能:索引,视图,......
答案 6 :(得分:0)
Eran Galperin已经提供了我的大部分答案。此外,您提出的结构在锁定方面确实无法帮助您。如果它们在同一行中是相对静态和动态的属性,则将静态和动态分解为两个表并没有多大好处。静态数据是否被锁定并不重要,因为无论如何都没有人试图改变它。
事实上,你可能会在这个设计上做得更糟。一些数据库引擎使用页面锁定。如果表的列数较少/较小,则页面上会有更多行。页面上的行越多,锁争用的可能性就越大。通过将静态数据与动态混合在一起,行更大,因此页面中的行数更少,因此页锁的等待时间更少。
如果您有两组独立的动态属性,并且它们通常由不同的actor修改,那么您可以通过将它们分成不同的表来获得一些好处。然而,这是一个非常不寻常的案例。
我还要指出,在相对较小的环境中将表分成静态和动态部分可能不是有益的,但在大型分布式环境中,以不同的速率缓存和复制动态数据可能很有用。比静态数据。