重构过时的数据库模式的提示

时间:2008-09-19 18:36:14

标签: database refactoring schema

坚持不再反映数据模型的遗留数据库架构是每个开发人员的噩梦。然而,由于所有关于为可维护性重构代码的讨论,我都没有听说过重构过时的数据库模式。

有关如何在不破坏依赖旧代码的所有代码的情况下过渡到更好的架构的一些提示?我将提出一个具体的问题,我必须说明我的观点,但随意提出其他已证明有用的技巧的建议 - 这些技术也可能会派上用场。


我的例子:

我的公司收到并运送产品。现在产品收据和产品装运有一些非常不同的数据,因此原始数据库设计者为收据和装运创建了一个单独的表。

在我使用这个系统的一年中,我已经意识到当前的架构没有任何意义。毕竟,收据和发货基本上都是一笔交易,它们各自涉及改变产品的数量,但只有+/-符号不同。实际上,我们经常需要找到产品在一段时间内发生变化的总量,这个问题对于这种设计来说是完全难以解决的。

显然,适当的设计是拥有一个Transactions表,其中Id是ReceiptInfo或ShipmentInfo表的外键。不幸的是,错误的模式已经生产了几年,并且有数百个存储过程,并且有数千行代码写入其中。那么我怎样才能将模式转换为正常工作?

8 个答案:

答案 0 :(得分:5)

以下是数据库重构的完整目录:

http://databaserefactoring.com/

答案 1 :(得分:3)

解决这个问题非常困难;重构数据库后的几个快速选项是:

  • 创建与原始模式匹配但从新模式中拉出的视图;您可能需要触发器,因此可以处理对视图的任何更新。
  • 创建新架构并在每一侧放置触发器以维护另一侧。
  • 答案 2 :(得分:3)

    在处理遗留数据库模式时,

    This book (Refactoring Databases)一直是上帝发送给我的,包括当我不得不处理几乎完全相同的库存数据库问题时。

    此外,建立一个系统来跟踪对数据库模式的更改(就像存储在源控制存储库中的一系列更改脚本一样)有助于确定代码到数据库的依赖关系。

    答案 3 :(得分:1)

    存储过程和视图是您的朋友。即使系统不使用它们,也要更改它以使用它们,然后重构下面的数据库。

    您的收据和货件随后成为观点。

    请注意,在我使用的大多数系统中,收据和货件实际上是两种截然不同的野兽。收据与供应商相关联,而货件则与客户(或客户/送货地点)相关联。在库存水平上,它们通常表示相同。

    答案 4 :(得分:0)

    所有数据访问是否仅限于存储过程?如果没有,这项任务几乎是不可能的。如果是这样,您只需确保您的数据迁移脚本能够很好地从旧模式转换到新模式,然后确保您的存储过程符合您的输入和输出。

    希望他们都没有“select *”查询。如果他们这样做,使用'sp_help tablename'来获取完整的列列表,将其复制并用完整列列表替换每个*,以确保不破坏客户端代码。

    我建议逐步进行更改,并进行大量的集成测试。如果不引入一些错误,很难进行重大改造。

    答案 5 :(得分:0)

    首先是创建表模式。我已经使用Enterprise Architect为Legacy数据库做了这个。您可以选择数据库,它将为您创建每个表/字段。然后,您需要将所有内容拆分为类别。将所有收到的产品和产品组合在一起,将客户的东西放在另一个类别中。一旦清理完毕,您将能够通过创建新表,新的迁移和新字段来重构字段。当然,如果在没有存储过程的情况下访问所有内容,则需要进行大量更改。

    答案 6 :(得分:0)

    我认为很明显,transaction表的id应该是ReceiptInfo或ShipmentInfo的外键。反过来想想。在面向对象的模型中,您应该有一个事务表,并且ReceiptInfo或ShipmentInfo应该具有事务表的外键。如果幸运的话,代码中只有1或2个点可以在ReceiptInfo或ShipmentInfo中创建新记录。在那里,您应该添加代码,在Transaction表中添加一个条目,之后在ReceiptInfo或ShipmentInfo中创建条目,并使用外键到Transaction。

    答案 7 :(得分:0)

    有时您可以创建具有更好结构的新表,然后使用旧表的名称创建视图,但这些视图基于新表中的数据。这样,当您开始转向更好的结构时,代码不会中断。但请注意,尽管有时您会从非关系表移动到关系结构,在该关系结构中您有多个记录,而代码只期望一个。如果您有使用子查询的开发人员,则尤其如此。

    然后随着每件事的改变,它将从视图移动到真实的桌子。最终你可以删除视图。这至少可以让你逐步工作,以便在移动东西时保持工作,但是开始修复以使用更好的设计。