重构过时的数据库架构的技巧
陷入不再能反映数据模型的旧数据库架构是每个开发人员的噩梦。但是,在谈论重构代码以实现可维护性的过程中,我很少听说过重构过时的数据库模式的事情。
在不破坏所有依赖旧代码的代码的情况下,如何过渡到更好的模式有哪些技巧?我将提出一个特定的问题,我必须说明我的观点,但可以随时就已证明有用的其他技术提供建议,这些技术也可能会派上用场。
我的例子:
我公司接收并运送产品。现在,产品收据和产品装运具有一些非常不同的数据,因此原始数据库设计者为收据和装运创建了一个单独的表。
在使用该系统的一年中,我意识到当前的模式没有什么意义。毕竟,收据和装运基本上都是交易,它们都涉及更改产品的数量,从本质上讲,只有+ /符号是不同的。确实,我们经常需要查找产品在一段时间内变化的总量,而这种设计是非常棘手的。
显然,适当的设计将是拥有一个交易表,其ID是ReceiptInfo或者ShipmentInfo表的外键。不幸的是,错误的模式已经投入生产多年,并且具有数百个存储过程,并从中写入了数千行代码。然后如何转换架构以使其正常工作?
解决方案
所有数据访问是否仅限于存储过程?如果不是这样,则该任务几乎是不可能的。如果是这样,则只需确保数据迁移脚本在从旧模式到新模式的过渡中正常运行,然后确保存储过程尊重输入和输出。
希望它们都没有" select "查询。如果是这样,请使用" sp_help表名"获取完整的列列表,将其复制出来,然后将每个替换为完整的列列表,以确保我们不会破坏客户端代码。
我建议逐渐进行更改,并进行大量集成测试。不引入一些错误就很难进行重大的改型。
首先是创建表架构。我已经使用Enterprise Architect对旧数据库进行了此操作。我们可以选择数据库,它将创建每个表/字段。然后,我们将需要将所有内容分成几类。举例来说,我们所有的收货和一起发货产品,属于其他类别的客户材料。清除所有内容后,我们将能够通过创建新表,新重新发布和新字段来重构字段。当然,如果在不使用存储过程的情况下进行全部访问,则将需要进行很多更改。
这是数据库重构的完整目录:
http://databaserefactoring.com/
这是一件非常困难的事情。重构数据库后,有几个快速选择:
- 创建与原始架构匹配但从新架构中提取的视图;我们可能在此处需要触发器,以便可以处理视图的任何更新。
- 创建新的架构,并在每一侧放置触发器以维护另一侧。
存储过程和视图在这里是朋友。即使系统不使用它们,也可以对其进行更改以使用它们,然后在下面重构数据库。
收据和发货便成为视图。
当心,收据和发货实际上是我使用过的大多数系统中的两种截然不同的野兽。收据链接到供应商,而货件链接到客户(或者客户/收货地点)。在库存级别,它们通常表示相同。
这本书(重构数据库)在处理遗留数据库模式时,包括在我不得不处理库存数据库几乎完全相同的问题时,是我的天赐之物。
同样,拥有一个适当的系统来跟踪数据库模式的更改(例如存储在源代码控制存储库中的一系列更改脚本)有助于极大地找出代码与数据库之间的依赖性。
我认为交易表的ID应该不是ReceiptInfo或者ShipmentInfo的外键并不明显。反过来思考。在面向对象的模型中,我们应该有一个交易表,而ReceiptInfo或者ShipmentInfo应该有一个交易表的外键。如果幸运的话,代码中只有1或者2个点可在ReceiptInfo或者ShipmentInfo中进行新记录。在那里,我们应该添加代码,在"事务"表中添加条目,然后在ReceiptInfo或者ShipmentInfo中使用事务的外键创建条目。
有时,我们可以创建结构更好的新表,然后使用旧表的名称创建视图,但这些视图基于新表中的数据。这样,代码就不会在我们开始转向更好的结构时中断。尽管有时我们会从一个非关系表转移到一个有多个记录的关系结构,而代码只希望有一个记录,但请务必小心。如果我们有使用子查询的开发人员,这是特别的。
然后,随着每件事的变化,它将从视图移到实际表。最终,我们可以删除视图。至少这使我们可以逐步进行操作以使事物在移动事物时保持正常运行,但可以开始进行修正以使用更好的设计。