2009-12-29 76 views
4

我已经出现在一份新的工作中,发现了急需一些帮助的数据库。它有很多很多错误,包括糟糕的数据库架构设计的升级策略

  • 没有外键......任何地方。他们伪造使用int s和管理代码中的关系。
  • 实际上,每场可NULL,这是不是真的
  • 命名约定表和列实际上是不存在的
  • 其存储的关系信息串联字符串

乡亲

  • Varchar小号可以争论,“它有效”,它是。但是向前发展,用代码来管理所有这些是一件非常痛苦的事情,并且让我们知道了IMO的错误。基本上,DB是作为一个平面文件使用的,因为它没有做很多工作。

    我想解决这个问题。我看现在的问题是:

    1. 我们有大量的数据(迁移,可能是棘手的)
    2. 所有DB的逻辑是代码(与移民来到大码的变化)

    我也试图做一些“激进”的事情,比如转向无模式数据库。

    当面对基于设计不佳的架构的现有数据库时,有什么好的策略?

  • 回答

    4

    强制外键:如果域中存在关系,那么它应该有一个外键。

    重命名现有的表/列是充满危险的,特别是如果有很多系统直接访问数据库。陷阱包括只能定期运行的任务;这些往往是错过的。

    的意义:斯科特·安布勒的文章:Introduction To Database Refactoring

    Catalog of Database Refactorings

    0

    首先看看代码与数据库相关性有多糟糕,如果它全部混合在没有DAO层的情况下,你不应该考虑重写,但是如果有DAO层,那么重写该层和DB是时候了与它一起。如果可能的话,基于使用两个DAO制作迁移工具。

    但我的猜测是没有DAO,所以你需要找到你将要改变的代码的哪些部分,以及DB的哪些部分,希望你可以把它切成更小的部分,可以更新如你所维护。最大的交易是获得FKs并开始检查正确的索引,这很有可能是他们没有正确完成。

    我不会担心命名太多,直到数据库的其余部分受到控制。至于NULL,如果程序阻塞的值为NULL,不会让它为NULL,但如果程序可以处理它,我不会担心它在将来的这一点,如果它正在执行默认值移动数据库,但这是从事情的声音的方式。

    尽早对Varchars做点事情。如果有什么使得第一个纯背景修复程序。

    要做的另一件事是估计每个区域更改的工作量,然后将该价格添加到该代码段的新开发成本中。这样,您可以在添加新功能时修复这些部件。

    2

    视图通常用于由于封装而在不断变化的数据模型之间转换。视图看起来像一个表,但不作为数据库中的有限对象存在 - 您可以根据需要更改给定列别名返回的列。这使您可以将代码库设置为使用视图,因此您可以从旧的表结构移动到新的表结构,而无需更新应用程序。但这意味着视图必须以现有格式返回数据。例如 - 你当前的数据模型有:

    SELECT t.column --a list of concatenated strings, assuming comma separated 
        FROM TABLE t 
    

    ...这样的观点的第一个版本将是上面的查询,但一旦你创建了一个使用3NF,查询该视图将使用新表:

    SELECT GROUP_CONCAT(t.column SEPARATOR ',') 
        FROM NEW_TABLE t 
    

    ...和应用程序代码永远不会知道任何更改。

    MySQL的问题是,视图支持是有限的 - 你不能使用它的变量,也不能有子查询。

    您想要进行的更改的实际情况是从头开始有效地重写应用程序。将逻辑从代码库移动到数据模型将彻底改变应用程序获取数据的方式。模型 - 视图 - 控制器(MVC)非常适合于像这样的变化来实现,从而最大程度地降低未来这些变化的成本。

    +0

    我喜欢使用这个问题的意见。 – 2009-12-29 07:19:41

    +0

    为此使用视图的问题是它从长远来看并不能真正解决问题,它只是在执行迁移时的临时解决方案。你需要有一个迁移计划,所以你确实要迁移所有旧的代码,否则你最终只能得到两个数据库模式(一个是你想要摆脱的旧的蹩脚的模式)。日程安排可能必须有一个设定的日期,当你将放弃的意见。 – 2009-12-29 10:28:43

    +0

    @Emil:重读我的第一句话;) – 2009-12-29 10:32:53

    1
    1. 创建一个全新的模式,并确保它是完全规范化的,并包含任何唯一的,检查和非空约束等是必需的,并且使用适当的数据类型。
    2. 预先填充填充父角色的每个表与外部键关系中的单个“未知”记录。
    3. 创建一个ETL(提取转换加载)过程(我可以推荐SSIS(SQL Server Integration Services),但还有很多其他的),可以用来定期从现有的模式中重新填充新的模式。使用“未知”记录作为任何孤儿记录的父母 - 将会有很多;)。您需要考虑如何合并重复记录 - 这可能需要逐案处理。
    4. 根据需要使用尽可能多的迭代来优化新的模式(确保ETL过程得到维护并定期运行)。
    5. 尽可能接近地创建与现有模式匹配的新模式的视图。
    6. 递增修改任何客户端以使用新模式在必要时临时使用视图。您应该能够逐渐关闭部分ETL过程,并最终完全禁用它。
    1

    阅读Scott Ambler的书Refactoring Databases。它涵盖了很多关于如何改进数据库的技巧 - 包括使新老程序能够适应不断变化的设计所需的过渡措施。