8

我继承的当前项目主要围绕一个未规范化的表。有一些标准化的尝试,但没有设置必要的限制。

示例:在 Project 表中,有一个客户名称(以及其他值),还有一个客户表,其中仅包含客户名称 [任何地方都没有键]。客户表仅用作在添加新项目时为用户提供的值池。客户表上没有主键或外键。

诸如此类的“设计模式”在数据库的当前状态和使用它的应用程序中很常见。我可以使用的工具是 SQL Server 2005、SQL Server Management Studio 和 Visual Studio 2008。我最初的方法是手动确定哪些信息需要规范化并运行 Select INTO 查询。有没有比个案更好的方法,或者无论如何这可以自动化?

编辑: 另外,我发现“工作订单号”不是 IDENTITY(自动编号,唯一)字段,它们是按顺序生成的,并且对于每个工作订单都是唯一的。现有编号中也有一些空白,但都是独一无二的。这是编写存储过程以在迁移之前生成虚拟行的最佳方法吗?

4

7 回答 7

10

迁移到可用设计的最佳方法是什么?小心

除非您愿意破坏(并修复)当前使用数据库的每个应用程序,否则您的选择是有限的,因为您无法对现有结构进行太多更改。

在开始之前,请仔细考虑您的动机 - 如果您有一个现有问题(要修复的错误,要进行的增强),那么请慢慢进行。然而,为了获得别人不会注意到的改进而在工作的生产系统上胡闹是不值得的。请注意,这可能对您有利 - 如果存在现有问题,您可以向管理层指出解决问题的最具成本效益的方法是以这种方式更改数据库结构。这意味着您对更改有管理支持 - 如果某些东西变成梨形,则(希望)他们的支持。

一些实际的想法...

一次进行一项更改……而且只有一项更改。在继续之前,请确保每个更改都是正确的。古老的谚语“两次测量,一次切割”是相关的。

自动化 Automate Automate ...永远不要使用 SQL Server Management Studio 对生产系统进行“实时”更改。编写一次性执行整个更改的 SQL 脚本;针对数据库副本开发和测试这些,以确保您得到正确的结果。不要将生产环境用作测试服务器——你可能会不小心对生产环境运行脚本;使用专用的测试服务器(如果数据库大小在 4G 以下,请使用在您自己的机器上运行的 SQL Server Express)。

备份......任何脚本的第一步都应该是备份数据库,这样如果出现问题,您就有办法回去。

文档...如果有人在十二个月内来找您,询问他们应用程序的功能X为何损坏,您将需要对数据库所做的确切更改的历史记录,以帮助诊断和修复。第一个好的步骤是保留所有更改脚本。

...在数据库中保持主键和外键抽象而不通过应用程序显示通常是一个好主意。在业务层面看起来像钥匙的东西(比如您的工作订单号)有一个令人不安的习惯,即出现异常。将您的键作为具有适当约束的附加列引入,但不要更改现有键的定义。

祝你好运!

于 2009-03-21T21:07:42.823 回答
1
  1. 按照您认为应该构建的方式创建新数据库。
  2. 在新数据库中创建一个 importError 表,其中包含“oldId”和“errorDesc”等列
  3. 编写一个简单、程序化、易读的脚本,尝试从旧结构中选择一行并将其插入到新结构中。如果插入失败,请在 importError 表中记录尽可能具体的错误(特别是插入失败的原因)。
  4. 运行脚本。
  5. 验证新数据。检查是否有错误记录到 importError 表中。如果数据无效或有错误,重构您的脚本并再次运行它,可能在必要时修改您的新数据库结构。
  6. 重复步骤 1-5,直到您拥有可靠的转换脚本。

此过程的结果将是您拥有: a) 一个新的数据库结构,该结构已针对旧结构进行验证并针对“实用主义”进行了测试;b)您可能需要编写代码的潜在问题的日志(例如您无法通过转换修复的错误,因为它们需要您不想要的架构中的让步)

(我可能会注意到,用您选择的脚本/编程语言而不是 SQL 来编写脚本会很有帮助。)

于 2009-03-21T21:04:43.563 回答
0

我想不出一种明智的方式来自动化这个......如果你希望输出有用的话,一些人工输入是这种重构的关键。

重新工单号;假设您希望它继续作为 IDENTITY 列;您能否填充数据,找到最大的,然后使用 ALTER TABLE 使其成为 IDENTITY?我手头没有任何 TSQL 工具,所以很遗憾,我无法测试。或者,只需将其视为natural key

于 2009-03-21T20:56:15.533 回答
0

我建议使用存储过程来帮助翻译过程。

具体来说:

  1. 将代码中使用的查询一一替换为存储过程。作为替换的一部分,直接针对存储过程编写单元(或集成)测试。考虑一个代码级StoredProcs帮助器类来整合那里的数据库访问。
  2. 在所有查询都是存储过程之后,您可以重构数据库,使用这些单元测试来确保您没有更改预期的行为。
  3. 附加优势:您将拥有这些单元测试以防止将来出现故障。
于 2009-03-21T21:21:52.883 回答
0

您没有说是否需要保留当前的应用程序界面,或者您是否打算重写应用程序中的任何查询。

无论哪种方式,我都会

  • 设计新模式
  • 编写 T-SQL 批处理,在必要时使用游标来迁移数据

游标虽然不是操作查询的首选,但非常适合这种类型的应用程序,因为您可以以非常结构化的方式完成任务。这些脚本往往非常易读,当它不能立即工作并且您已经经历了几次迭代时,这一点很重要。

于 2009-03-21T22:11:49.767 回答
0

您可以使用作为 SQL Server 2005 一部分的 SQL Server Integration Services (SSIS) 来帮助您进行迁移。它用于将数据从一种形式传输到另一种形式:

http://en.wikipedia.org/wiki/SQL_Server_Integration_Services http://www.microsoft.com/sqlserver/2005/en/us/integration-services.aspx

于 2009-03-21T22:12:29.237 回答
0

只是添加一个简单的提示。当您将实体关系图放在您面前的一张 A4 或 A3 上时,适当的规范化将意味着没有多对多的关系。检查这本书或至少该网站

于 2009-05-15T19:58:34.877 回答