don*_*nde 5 database-design normalization
请提出您对不规范化的好主意的看法.我刚刚目睹了一个架构师和DBA之间激烈的讨论,他们坚持认为数据库是TOO规范化的.
EJB*_*EJB 11
性能查询可能性:如果数据库过于规范化,这可能会导致查询中出现大量连接,并限制了搜索特定属性的可能性.在进行数据库设计时,您应该通过访问路径分析来考虑计划使用它的方式.
详细说明,规范化经常更新的数据并对主要读取的数据进行非规范化是一个经验法则.
HLG*_*GEM 10
规则是规范化直到它受伤,然后非规范化直到它起作用.(谁说的?)
一般来说,当我有很多父子关系时,我经常会非规范化,而且我知道我经常需要加入五到六个大表来获取一个数据(例如客户端ID)并且不需要任何大部分时间来自中间表的信息.如果可能的话,我会尝试对不会经常更改的内容(例如id字段)进行非规范化.但是无论何时你进行非规范化,你都必须编写触发器或其他一些进程(但是如果它不是可以通过PK/FK关系和级联更新来处理的话,通常会触发)以确保数据保持同步.如果您未能在数据库级别执行此操作,则会出现数据完整性问题,并且您的数据将变得无用.不要以为您可以通过应用程序代码维护非规范化.这是一场灾难,
正确地进行非规范化可以减慢插入,更新和删除的速度,尤其是在需要执行大批量数据时.它可能会也可能不会提高选择查询速度,具体取决于您查询数据的方式.如果您最终需要进行大量的自连接来获取数据,那么最好不要进行非规范化.永远不要在没有测试的情况下进行非规范化,看看你是否有改进 记住,当许多用户使用它时,减慢插入/更新/删除将对系统产生整体影响.通过非规范化来解决一个问题,您可能会在整个系统中引入更严重的问题.不要只测试你试图加速的一个查询,测试整个系统的性能.您可以加快每月运行一次的查询速度,并减慢每天运行数千次的其他qreries.
通常对数据仓库进行非规范化,这是特殊情况,因为它们通常是按计划自动更新而不是用户一次更新一个记录.专门从事数据仓库的DBA也倾向于构建它们,并且知道如何避免数据完整性问题.
另一种常见的非规范化技术是为与复杂报告相关的数据创建一个临时表,该表不需要使用实时数据运行.这是一种穷人的数据仓库,如果没有按计划更新登台表的方法,就不应该这样做(尽管你可以随意使用,但这会使用服务器资源,这些资源可能会在大多数时间更好地花费在其他地方. )当系统上的用户很少并且落后于实时数据一整天时,通常会更新这些类型的表.不要考虑这样做,除非您正在暂存数据的查询真的很慢,否则无法进行优化.许多慢速查询可以在没有反复异化的情况下进行优化,因为开发人员通常使用最简单的方法来理解,而不是以最高效的方式来选择数据.
一些标准化是为了允许未来增长,您可能不需要它.
例如,假设你有一张person
桌子.你可以birthday
作为专栏,因为每个人只会有一个生日.
如果你严格正火,你不会有phone_number
和cell_number
和fax_number
在列person
,但可能反而有phonenumber
每一行都有一个编号,类型,以及为person_id关系表.这可能比仅仅在person
表中粘贴新列更好,因为
cell_number_2
关注#1是有效的,但关注#2可能是"你不需要它"的一个例子.说"我们只允许一个细胞数,这就是那个"是有效的.在这种情况下,您可能不会费心为电话号码制作单独的表格.
这是一个权衡.通过不创建单独的表,您不是严格规范化,并且您可能有很多NULL空格.但是你也有更少的连接要做,而且它的工作量更少.
像许多良好实践一样,规范化本身就可以成为目的 - 你私下给自己的金徽章,因为你做得对.那没关系.但是很高兴认识到,为了保持简单,有时可以修改规则.
最后一件事:一旦代码启动并运行,你必须权衡改变数据库模式的事实.因此可以说"我们不需要它",但在你提交之前尽量确定.
已经有几个关于存储与性能的好答案,但另外我还要添加一个块,这对我来说应该考虑去规范化是你需要使用自连接查询的地方.
从概念上讲,自联系表格没有任何问题,但经验表明,对于没有经验的程序员来说,这是一个比较困难的概念,因此容易产生错误.如果您能够设计出这些需求,您很可能会放松未来的维护路径.
当然,这是一个判断问题,因此是一种指示,而非规则.