2009-10-25 74 views
9

与其他几个人一起工作时,通常会有几个人在不同区域工作,例如数据库。持续集成和数据库管理

我的挑战是如何让几个人在持续集成环境中编辑数据库模型。

开发人员建议编写一个“版本控制脚本”,其中将每个编辑输入到.sql脚本中,并使用数据库能够检测到的版本号。在该文件中添加一个新的模型会在文件中加上一个版本的标签,并且一旦脚本被提交并且一个构建已经运行,数据库就会被更新。

我也听说过发布者/订阅者...并阅读了一下。

如何在日常工作中管理这种情况,并且您可以给我哪些建议以使数据库更改尽可能无缝地运行?

**编辑**

已经提到了迁移框架和迁移脚本。如果你有一些实践经验并且会提出一个框架,那也是值得赞赏的。

回答

19

中的出色Get Your Database Under Version Control后报价杰夫阿特伍德:

...

我在想这又 因为我的朋友和co-author K. 斯科特·艾伦刚刚写下辉煌的 五部分的数据库版本控制练习:

  1. Three rules for database work
  2. The Baseline
  3. Change Scripts
  4. Views, Stored Procedures and the Like
  5. Branching and Merging

...

真的,全系列值得一读,即使你们中许多人似乎是特别感兴趣的第三部分。顺便说一句,看看第三部分提到的Bulletproof Sql Change Scripts Using INFORMATION_SCHEMA Views文章。您可能已经意识到这一点,但它解释了为什么编写idempotent更改脚本很重要。

关于工具,你可能想看看UpToDater(代码中心),LiquiBase(基于XML)或... dbdeploy的基础上,ThoughtWorks的软​​件开发的现实世界的经验有点宝石。这不是说第一个不好,但这是我的首选(可用于Java,PHP或.NET)。

+2

如果我不仅限于1人,我会赞成18次:D – whaley 2009-10-28 17:41:33

+1

让你的奶奶投票然后:)更严肃地说,很高兴你觉得它有帮助。 – 2009-10-28 17:52:55

+0

感谢您的链接。希望3条规则中的项目#1有更多细节。它是我们现在正在努力的东西。说起来容易做起来难。 – CodingWithSpike 2009-10-28 18:20:43

1

检出迁移框架。 AFAIK,这个想法来自于rails,但是现在人们已经为其他所有东西构建了框架。

5

我倾向于使用'迁移'脚本,这是从简单的版本化脚本开始的下一个阶段。通过迁移,您可以指定对数据库所做的更改(添加,删除等)以及如何撤消迁移正在执行的更改。然后用一个不会与其他开发人员冲突的某种形式的版本标记。一个特别好的版本号是当前时间(以YYYYMMDDHHMMSS格式或者距离纪元秒)。这是一个不错的选择,因为您不太可能发生版本冲突,并且由于此类时间戳的严格增长性质,仍然很容易发现是否存在新版本。

注意:这受到Rails中的迁移系统的很大影响。对于更多细节和想法,我强烈建议查看该系统。

的Rails迁移:

class CreateGroups < ActiveRecord::Migration 
    def self.up 
    create_table :groups do |t| 
     t.string :name 
     t.references :owner 

     t.timestamps 
    end 
    end 

    def self.down 
    drop_table :groups 
    end 
end 

主义迁移:

class CreateGroups extends Doctrine_Migration 
{ 
    public function up() 
    { 
     // Create new author table 
     $columns = array('id' => array('type'   => 'integer', 
             'length'  => 4, 
             'autoincrement' => true), 
         'name' => array('type'   => 'string', 
             'length'  => 255), 
         'owner_id' => array('type' => 'integer', 
              'length' => 4)); 

    $this->createTable('groups', $columns, array('primary' => array('id'))); 
    } 

    public function down() 
    { 
    $this->dropTable('groups'); 
    } 
} 

(对不起,缺乏学说时间戳的......在轨道中的时间戳呼叫created_at和的updated_at字段的表补充说,是自动为你管理的,我不确定在教条中有类似的行为,所以我把它们排除在外)。

+1

我很想看到一个迁移脚本示例,如果你有一个? – CodeMonkey 2009-10-25 22:35:35

+0

我第二个示例请求。 – Martin 2009-10-25 22:54:45

+0

今天晚些时候我将添加一个rails迁移示例,以及一个大致相同的原则迁移。 – workmad3 2009-10-26 12:11:07

1

这取决于。

如果这是您正在讨论的发布产品,则需要仔细跟踪架构编辑,以便您可以规划升级过程。现在开始思考这个问题会很好,所以“版本控制脚本”在某种程度上是有意义的。但向后/向前兼容通常只是用户可见的需求,而不是“编译之间”的需求。在发行版之间,维护一个升级脚本来修改数据库表以将其提升到新的模式是有意义的。

如果这是一个新/未发布的产品,如果有人更改了架构,您会关心什么?为什么你甚至想要在持续集成构建之间保持数据库?无论如何,您应该能够通过自动化测试重新生成任何测试数据。但是,更改架构的任何人都应该更新测试。

对于已发布的产品,您可能希望拥有一组可以处理“1.0版”数据库的测试,以确保它可以成功升级到“1.1版”(例如)。

0

我们在Subversion中编写所有脚本,并将其与任何其他代码一样检入到项目中。所有的数据库部署都是从源代码管理系统提取的脚本完成的。如果两个人碰巧正在使用同一个脚本(这相当罕见),Subversion会让你合并这两个脚本。

1

问题中没有描述技术堆栈(包括使用的数据库),这与哪种解决方案最适合非常相关。

非常流行的以Java为中心的迁移解决方案是FlywayDBUp是非常相似,但专注于.NET堆栈。

在Redgate,我们提供ReadyRoll,它紧密集成到Visual Studio中,专门针对SQL Server。