Zap*_*ica 2 sql database sql-server database-design normalization
好的我知道你可能会因为问这个问题而杀了我,但是我和同事讨论了一个关于我们的数据库表的友好程序员问题,他问了一个我知道答案的问题,但我不能解释这是更好的方法.
为了简化问题,我将简化情况,我们有一个相当大的人/用户表.现在,在存储的其他数据中,所讨论的数据如下:我们有一个simNumber,cellNumber和该sim的ipAddress.
现在我说我们应该创建一个表,让它称之为SimTable并将这3个条目放入sim表中,然后在UsersTable中放入一个FK链接两者.为什么?因为这就是我一直教给你的桌子!好的,所以在这方面一切都很好.
但现在我的朋友对我说是的,但现在当你想查询用户的电话号码时,SQL现在必须去:
现在当我去请求10000个用户的电话号码时,完成的操作数量会严重增加.
与另一种方法相反
现在这个论点纯粹基于表现.尽管我理解为什么我们会对数据进行规范化(删除冗余数据,可维护性,在一个表中对数据进行更改等等).在我看来,在一个表中使用数据的方法会更快或者至少会减少任务/操作给我我想要的数据?
那么这种情况是怎样的呢?我希望我没有问过任何愚蠢的事情,这是一大早所以如果我不清楚的话,请原谅我
MS SQL Server 2012中涉及的技术
[编辑]下面的这篇文章也涉及我上面提到的一些概念 http://databases.about.com/od/specificproducts/a/Should-I-Normalize-My-Database.htm
规范化的目标不是表现.目标是以最小冗余正确建模数据,以避免数据异常.
比如说两个用户共用同一部手机.如果将电话存储在用户表中,则每个用户的行中都会存储SIM号,IP地址和单元号.
然后,您更改一行的IP地址,而不是另一行.一个sim号码如何有两个IP地址?这甚至有效吗?哪一个是正确的?你会如何解决这些差异?你怎么会发现它们?
有时候非规范化是值得的,如果你真的需要为一个经常运行的查询优化数据访问.但非规范化需要付出代价,因此请准备好承担更多的手工工作,以承担数据完整性的责任.更多代码,更多测试,更多清理任务.在考虑整个项目的"绩效"时,这些是否有用?
评论:
我同意@JoelBrown,一旦实现了第一个非规范化的情况,就会对数据完整性做出妥协.
我将扩展乔尔提到的"考虑周全".非规范化有益于特定的查询.因此,您需要知道应用中有哪些查询,以及需要针对哪些查询进行优化.保守地执行此操作,因为虽然非规范化可以帮助特定查询,但它会损害相同数据的所有其他用途的性能.因此,您需要知道是否需要以不同方式查询数据.
示例:假设您正在为StackOverflow设计数据库,并且您希望支持问题的标记.每个问题都可以包含多个标记,每个标记都可以应用于许多问题.设计这个的标准化方法是创建第三个表,将问题与标签配对.这是多对多关系的物理数据模型:
Questions ----<- QuestionsTagged ->---- Tags
Run Code Online (Sandbox Code Playgroud)
但是,您认为您不想进行连接以获取给定问题的标记,因此您将标记放入问题表中以逗号分隔的字符串中.这使得查询给定问题及其相关标签变得更快.
但是,如果您还想查询一个特定标签并找到相关问题,该怎么办?如果使用规范化设计,它只是针对多对多表的查询,而是在tag列上.
但是,如果通过在"问题"表中将标记存储为逗号分隔列表来进行非规范化,则必须在该逗号分隔列表中搜索标记作为子字符串.搜索子字符串不能使用标准B树样式索引编制索引,因此搜索相关问题会成为代价高昂的表扫描.插入和删除标记,或应用唯一性或外键等约束也更复杂,效率更低.
这就是我的意思是非规范化,以牺牲其他数据使用为代价来改进一种查询.这就是为什么以正常形式开始一切都是一个好主意,然后随着你的瓶颈揭示自己,然后根据具体情况重构非规范化设计.
这可以追溯到古老的智慧:
"过早的优化是所有邪恶的根源" - 唐纳德克努特
换句话说,除非您能够在负载测试期间证明(a)它对性能进行真正的改进以证明数据完整性的损失是合理的,并且(b)它不会令其他情况的性能降级得无法接受,所以不要进行非规范化.
| 归档时间: |
|
| 查看次数: |
558 次 |
| 最近记录: |