重构或升级数据库以处理新功能


9

针对数据库模式问题的一些回答,建议使用一个附加表来规范不属于当前要求的功能的数据库(UserDepartment表允许员工/用户与他们可能在不同部门之间建立多对多关系属于。)。

不反对规范化。似乎在进行数据库设计时,大力推动包含他们“确定”某人将来会想要的功能。将表/字段添加到数据库以适应功能是否是如此困难,以至于过度工程化的趋势?如果需要,它们是否会像应用程序的其余部分那样进行重构或升级?重做从来都不是一件有趣的事,但是可以将数据从一个表转移到一个新表。只是不确定这种思路会在哪里结束。

编辑:对此有很大的反感,我想知道有多少项目最终没有添加需要进行重大数据库更改的功能,或者是否采取了非规范化的方法(例如添加DepartmentID2字段而不是新表)。员工需要多个部门是一个常见的领域问题。我只是没有注意到许多杂乱无章的数据库模式。


1
+1感谢您提出这个问题。阅读我对原始问题的回答后,我学到了很多东西,这也是一个很有见地的话题。
吉姆(Jim)

Answers:


3

有整本关于数据库重构的书。就像代码重构一样,有一些标准的方法可以进行数据库重构。唯一的区别是,在进行代码重构时,您不必考虑对象/代码的状态,而在数据库中则必须考虑数据,因为丢失数据对用户(或实际上对任何人都没有好处) )。

您可以在此处阅读有关数据库重构的更多信息。


该站点首先提示了这个问题;)
JeffO 2011年

14

重构代码很容易-您只需更改代码并运行回归测试即可。

重构数据库很困难-您必须移动(可能大量)数据,确保没有数据被删除,确保约束在新模式中得到维护。而且,如果您对数据有审核要求,那么您必须能够解释其组织方式为何不同,并且能够将前refoctor数据与后重构数据进行匹配。另外,您的旧备份都不会与新架构匹配,这是另一个风险。

可怕的东西。


数据库测试应该没有什么不同。所有更改都需要审核,并影响备份。在认识到这种需求之前,您将要积累多少数据?如果您已转换数据,则此功能将更加明显。
JeffO 2011年

8
+1 @Mathew Flynn。在认识到这种需求之前,您将要积累多少数据?数百万行。另一个问题是,很多时候您的应用程序并不是唯一使用数据库的应用程序。数据库中可以使用许多应用程序,您甚至可能不知道它们的存在(例如,野生的“ BI”应用程序)。数据库架构中的更改令人恐惧。
Angelo

2
有时数十亿行
HLGEM 2011年

1
如果要处理数十亿行,您最好知道如何移动它们
JeffO 2011年

3

在花费大量时间进行过度工程与投入少量时间来添加足够的功能以节省将来的大量时间之间,存在一条很好的界限。


1
您可以针对一个或两个孤立的实例进行争论,但是时间的“几位”何时加起来太多呢?
JeffO 2011年

根据我自己的经验,绝大多数项目实际上都是如此。但是我也可能会认为它是有经验的,并且是非常主观的:)如果有人能给您确切的配方,我会感到惊讶(因此称为“细线”)。
0x4B1D 2011年

@Jeff O:不会是“位”。必须在硬化上花费10%或20%的开发时间投入,因为该系统可能会超出最初设想的时间范围和您的工作。
rwong 2011年

3

我认为理论是,如果您包含一个链接表以支持2个表之间的多对多关系,那么即使数据中确实只有多对一关系,每个人都将以这种方式编写SQL:支持多对多,一切都会“正常工作”。

在实践中,我通常没有发现这是真的,但是我想SQL比其他方式更接近支持多对多需求所需的条件。

但是,要具体解决您的问题,实际上,将关系从1对多转换为多对多确实很多痛苦。原因是SQL的设计目标不是与对象具有相同的封装目标,并且大多数查询在数据库层使用的表多于人们对在业务层中具有可见性的对象感到满意的程度。

因此到许多变化一对多的关系将影响每一个涉及到原来的2台,经常查询宽级联效应比将发生在业务层上。因此,人们竭尽全力防止这种情况的发生。

恕我直言,如果我们使用比SQL更好的语言来指定关系代数,则不需要使用此方法。如果可行的是,逐个建立不需要对查询中的每个表具有可见性的对象的SQL查询,则不会发生这种情况。诸如LINQ(对SQL或对实体)之类的东西试图解决这个问题,但这是一个非常复杂的解决方案,并且难以优化(我去过提到LINQ的DBA用户组,每次都会抱怨得越来越多)。我梦想着一种一流的关系代数函数普遍支持的一种数据库语言...

同时,是的,您可以从1对多重构为多对多,但是这可能需要很多工作。


您不会将每一种关系变成多对多关系吗?
JeffO 2011年

@Jeff O-不确定我是否理解您的问题。如有疑问,我会建立尽可能多的模型,以避免对您原始问题的各种回答中提到的陷阱。在维护确实确实使几乎所有关系成为多对多关系的数据库之后,我对此变得更加警惕,因为它们最终做了诸如创建使关系看起来一对多的视图之类的事情(实际上,他们都是)。因此,他们两全其美。我从来没有在自己的设计上发生过这种情况,但这只是一个警告。
psr

3

我通常以这种方式向PHB解释-代码是墙壁和屋顶,数据库是基础。

可以移动墙壁并更换屋顶。改变地基需要大量挖掘和重建墙壁和屋顶。

没有经验的开发人员(和大学教授)说的是“工程过度”,即经验丰富的开发人员称为“未来证明”。尽管规范说了什么,但您知道在ALM期间可能会发生什么变化,或者在哪里出现性能问题,因此您希望正确地开始使用表结构。

将更新脚本推广到客户服务器是一个不平凡的项目,每个客户的DBA都遍布您,想要对它们进行三重检查。毕竟,一些额外的列和表还不错。


1

一般规则是,如果一种关系是一对一的,但将来可能会是多对多的,那么就会使之成为多对多的关系。

员工/部门是一个典型的例子。在大多数的小公司,这是一个有效的一对多关系的大部分时间。但是,几乎总是存在这样一种情况:您的一位工程师升入管理,但是仍然负责支持他在工程期间开发的产品,或者您的一位销售人员转移到产品开发,但是由于他与重要客户关系密切,因此他仍然是该客户的首席销售员。

如果一对多实现了多对多花费并不多-但是重构数据库和应用程序以支持多对多是昂贵且困难重重的。


我同意有很多成熟的领域(例如HR),客户无法预期需求,但是您知道它一定会发生。
JeffO

0

有两种查看软件设计的方法(可能还有许多其他方法)-战术视图或战略视图。每种都有自己的优点和缺点。

即使使用OO软件进行修改仍然很痛苦,不仅编码部分很困难,而且在投诉环境中(考虑到当前的技术水平)促进生产变更的过程对于应该被认为是大型系统来说是不现实的。工作24/7。

我按照我的原则说:“ 如果可能的战略,设计共享软件构件 ” -这听起来像它违背了以某种方式YAGNI原则,但是,这是我的看法。这种方法保证了减少复杂性和资源成本的返工。

在您的情况下,添加新联结表所需的活动包括:设计,设计批准,更改架构,为3个表重写CRUD的几种方法(某些读取除外),构建索引,为以下表创建GUI新表的CRUD,允许用户选择创建,更新新表等时的PK。哦,而且请不要忘记单元测试,用户验收测试,系统测试和产品推广。

如果这还不够,那么真正的噩梦就是信息丢失。如果没有开始的联结表,并且决定捕获员工与部门之间的关联/离职发生的日期,则将无法自动在联结表上填充日期。您必须手动输入(如果有数据)。

因此,最好从一开始就预见到这一点。


从一开始就可以预见一切。
JeffO 2011年

0

正如Matthew前面所说,与软件相比,重构/更改数据库通常要涉及更多的内容,因为还需要考虑管理数据。有一些技术可以帮助您,例如,确保您具有适当的数据库单元测试套件,通过使用“ DB API”(存储过程/视图等)将客户端应用程序与基本架构脱钩。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.