14

受困于不再反映您的数据模型的遗留数据库模式是每个开发人员的噩梦。然而,在所有关于重构代码以实现可维护性的讨论中,我并没有听到太多关于重构过时的数据库模式的消息。

关于如何在不破坏所有依赖于旧模式的代码的情况下过渡到更好的模式的技巧有哪些?我将提出一个特定的问题,我必须说明我的观点,但请随时就已证明有用的其他技术提供建议——这些技术也可能会派上用场。


我的例子:

我公司接收和运送产品。现在产品收据和产品发货有一些非常不同的数据与之关联,因此最初的数据库设计者为收据和发货创建了一个单独的表。

在我使用这个系统的一年中,我意识到当前的模式没有一点意义。毕竟收据和发货基本上都是一种交易,它们都涉及更改产品的数量,本质上只是+/-符号不同。事实上,我们经常需要找出产品在一段时间内的变化总量,而这个设计对于这个问题是非常棘手的。

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

4

8 回答 8

5

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

http://databaserefactoring.com/

于 2008-09-19T18:42:46.153 回答
3

这是一件很难解决的事情。重构数据库后的几个快速选项是:

  • 创建与原始模式匹配但从新模式中提取的视图;您可能需要在此处使用触发器,以便可以处理对视图的任何更新。
  • 创建新模式并在每一侧放置触发器以维护另一侧。
  • 于 2008-09-19T18:43:19.177 回答
    3

    这本书(重构数据库)在处理遗留数据库模式时是上帝送给我的,包括当我不得不为我们的库存数据库处理几乎完全相同的问题时。

    此外,拥有一个系统来跟踪对数据库模式的更改(例如存储在源代码控制存储库中的一系列更改脚本)有助于找出代码到数据库的依赖关系。

    于 2008-09-19T18:44:37.910 回答
    1

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

    然后,您的收据和发货将成为视图。

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

    于 2008-09-19T18:44:08.270 回答
    0

    所有数据访问都仅限于存储过程吗?如果没有,这项任务几乎是不可能的。如果是这样,您只需要确保您的数据迁移脚本在从旧模式过渡到新模式时运行良好,然后确保您的存储过程尊重他们的输入和输出。

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

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

    于 2008-09-19T18:40:43.803 回答
    0

    首先是创建表模式。我已经使用 Enterprise Architect 为 Legacy 数据库做到了这一点。您可以选择数据库,它会为您创建每个表/字段。然后,您需要将所有内容分类。以您所有的收货和发货产品为例,其他类别的客户资料。一切就绪后,您将能够通过创建新表、新关系和新字段来重构字段。当然,如果在没有存储过程的情况下访问所有内容,这将需要进行大量更改。

    于 2008-09-19T18:41:26.000 回答
    0

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

    于 2008-09-19T18:44:51.217 回答
    0

    Sometimes you can create new tables that have better structures and then create views with the names of your old tables but are based on the data in the new tables. That way, you code doesnt break while you start to move to a better structure. Be careful with thsi though as sometimes you move from a non-relational table to a relational structure where you have multiple records while the code will be expecting only one. This is particulalry true if you have developers who use subqueries.

    Then as each thing is changed, it will move away from the views to the real table. Eventually you can drop the views. This at least allows you to work incrementally to keep things working as you move stuff, but start to fix things to use a better design.

    于 2008-09-19T18:47:52.520 回答