SQL - 源代码管理和架构/脚本管理

时间:2010-12-17 17:43:03

标签: sql

我的公司刚刚完成年度审核流程,我终于说服他们现在是时候找到更好的解决方案来管理我们的SQL架构/脚本了。目前,我们只有几个脚本可以手动更新。

我曾在另一家公司使用过VS2008数据库版,这是一款非常棒的产品。我的老板让我看看Redgate的SQL Compare,并寻找可能更好的其他产品。 SQL Compare似乎也是一款出色的产品。但是,看起来他们并不支持Perforce。

你有没有使用过各种各样的产品?

您使用哪些工具来管理SQL?

在我公司购买之前,要求中应包含哪些内容?

10 个答案:

答案 0 :(得分:6)

我将链接到我对其他与数据库源代码管理相关的问题的答案

Is RedGate SQL Source Control for me?

Exposing SQL Server database objects as files in a file system

答案 1 :(得分:4)

我正处于“自己编写脚本”阵营,因为第三方产品只能帮助您管理数据库代码。我没有每个对象一个脚本,因为对象会随着时间的推移而变化,而十分之九只是更新我的“创建表”脚本以使三个新列不合适。

创建数据库基本上是微不足道的。设置一堆CREATE脚本,正确排序(在模式之前创建数据库,在表之前创建模式,在过程之前创建表,在调用过程之前调用过程等),然后完成。管理数据库更改并不是那么简单:

  • 如果您向表中添加列,则不能只删除表并使用新列创建表,因为这样做会消除所有宝贵的生产数据。
  • 如果Fred在表XYZ中添加了一列,并且Mary向表XYZ添加了不同的列,则首先添加哪一列?是的,表中列的顺序无关紧要[因为你从不使用SELECT *,对吧?]除非你试图管理数据库并跟踪版本控制,此时有两个“有效”的数据库没有看起来彼此成为一个真正的头痛。我们使用SQL比较而不是管理,而是审查和跟踪事物,特别是在开发过程中,少数“这些不同(但它们并不重要)”我们所拥有的情况可以积极地阻止我们注意到重要的差异
  • 同样,当多个项目(开发人员)在共享数据库上同时并单独工作时,它会变得非常棘手。也许每个人都在开展Next Big Thing项目,突然之间有人必须开始研究Last Big Thing项目的错误修复工作。当发布顺序可变且灵活时,如何管理所需的代码修改? (确实有趣的时间。)
  • 更改表结构意味着更改数据,当您必须处理向后兼容性时,这可能变得非常复杂。你添加一个“DeltaFactor”列,好吧,那你怎么做为所有现有(读取:遗留)数据填充这个深奥的价值?您添加了一个新的查找表和相关列,但是如何为现有行填充它?这种情况可能不会经常发生,但是当它们发生时,你自己做。第三方工具无法预测您的业务逻辑需求。

基本上,我所拥有的是每个数据库的CREATE脚本,随后是一系列ALTER脚本,因为我们的代码库随着时间的推移而变化。每个脚本都会检查它是否可以运行:这是数据库的正确“类型”,是否已运行必要的必备脚本,是否已运行此脚本。只有在通过检查时,脚本才会执行其更改。

工具方面,我们使用SourceGear Fortress进行基本源代码控制,Redgate SQL Compare用于一般支持和故障排除,以及许多基于SQLCMD的本土脚本,用于将alter脚本“批量”部署到多个服务器和数据库以及跟踪谁在什么时候将哪些脚本应用于哪些数据库。最终结果:我们所有的数据库都是一致的,稳定的,我们可以随时了解任何人的版本或版本。

答案 2 :(得分:3)

我认为没有一种工具可以处理所有碎片。 VS Database Edition无法提供合适的发布机制。从解决方案资源管理器运行单个脚本在大型项目中无法很好地扩展。

至少你需要

  • IDE /编辑
  • 可以与IDE一起使用的源代码存储库
  • 将各种脚本命名和组织到文件夹中的约定
  • 处理变更,管理发布和部署的过程

最后一颗子弹通常会发生故障。这就是原因。为了更好的可管理性和版本跟踪,您希望将每个db对象保留在自己的脚本文件中。即每个表,存储过程,视图,索引等都有自己的文件。

当某些内容发生变化时,您将更新该文件,并且您的存储库中有一个新版本,其中包含您需要的信息。在将大量更改捆绑到版本中时,处理单个文件可能很麻烦。

我使用的2个选项:

  • 除了将所有单个数据库对象保留在其文件中之外,还有一些发行脚本,这些脚本是各个脚本的串联。这样做的缺点是:你有2个代码,有所有的风险和劣势。好处:运行发布就像执行单个脚本一样简单。

  • 编写一个小工具,可以从发布清单中读取脚本元数据,并执行目标服务器清单中列出的eadch脚本。除了必须编写代码之外,没有任何缺点。此方法不适用于无法删除和重新创建的表(一旦您处于活动状态并拥有数据),因此对于表,您仍将拥有更改脚本。所以实际上,这将是两种方法的结合。

答案 3 :(得分:1)

我们要求对所有数据库进行更改或插入,例如查找表,以编写脚本并存储在源代码管理中。然后以与部署软件版本的任何其他代码相同的方式部署它们。由于我们的开发人员无权部署,因此他们别无选择,只能创建脚本。

答案 4 :(得分:1)

我们使用LiquiBase来控制数据库更改:

Liquibase is an open source (Apache 2.0 Licensed), database-independent library for tracking, managing and applying database changes.

答案 5 :(得分:0)

我通常使用MS Server Management Studio来管理sql,处理数据,开发数据库并调试它,如果我需要将一些数据导出为sql脚本或者我需要在数据库中创建一些困难的对象,我使用EMS SQL Management Studio for SQL Server,因为在那里我可以更清楚地看到我的代码和视觉设计的狭窄部分在这个环境中让我更容易

答案 6 :(得分:0)

Red Gate SQL Source Control正在努力支持其他源代码控制系统。如果您对Perforce支持感兴趣,请对https://redgate.uservoice.com/admin/forums/39019-sql-source-control/suggestions/863715-support-perforce-进行投票/评论,如果支持可用,我们会更新。

答案 7 :(得分:0)

尝试“SQL Effects Clarify”,这是一个非常好的工具,可以比较大多数对象,包括免费的行数。还有一些工具可以比较数据。

答案 8 :(得分:0)

我有一个开源(LGPL许可)工具集项目,该项目试图解决与(及更多)SQL Server(2005/2008 / Azure)bsn ModuleStore的正确数据库模式版本相关的问题。整个过程非常接近Philip Kelley在这里发布的概念。

基本上,工具集的独立部分将数据库模式的SQL Server数据库对象编写为应用了标准格式的文件,因此只有在对象确实发生更改时才会更改文件内容(与脚本编写相反)由VS完成,它也编写了一些脚本日期等,将所有对象标记为已更改,即使它们实际上是相同的。)

但是,如果使用.NET,工具集将超越它:它允许您将SQL脚本嵌入到库或应用程序中(作为嵌入式资源),然后将嵌入式脚本与数据库中的当前状态进行比较。非表相关的更改(根据Martin Fowler's definition不是“破坏性更改”)可以自动应用或根据请求应用(例如创建和删除视图,函数,存储过程,类型,索引等对象),和更改脚本(需要手动编写)也可以在同一个过程中应用;还会创建新表,可选择与其设置数据一起创建。更新后,再次将DB模式与脚本进行比较,以确保在提交更改之前成功进行数据库升级。

请注意,整个脚本和比较代码在没有SMO的情况下工作,因此在应用程序中使用bsn ModuleStore时,您没有痛苦的SMO依赖性。

根据您希望如何访问数据库,工具集提供了更多功能 - 它实现了一些ORM功能,并提供了一种非常好用且基于接口的方法来调用存储过程,包括使用本机.NET XML对XML进行透明支持类和TVP(表值参数)为IEnumerable<PocoClass>

答案 9 :(得分:0)

这是我的脚本,用于跟踪存储的proc和udf以及触发器到表中。

  1. 创建一个表来保存现有的存储过程源代码

  2. 使用所有现有触发器和脚本数据插入表格

  3. 创建DDL触发器以监控对它们的更改

            /****** Object:  Table [dbo].[sysupdatelog]    Script Date: 9/17/2014 11:36:54 AM ******/
            SET ANSI_NULLS ON
            GO
    
            SET QUOTED_IDENTIFIER ON
            GO
    
                            CREATE TABLE [dbo].[sysupdatelog] (
                                [id] [bigint] IDENTITY(1, 1) NOT NULL
                                ,[UpdateUsername] [nvarchar](1000) NULL
                                ,[actionname] [nvarchar](1000) NULL
                                ,[objectname] [nvarchar](1000) NULL
                                ,[type] [nvarchar](1000) NULL
                                ,[createDate] [datetime] NULL
                                ,[content] NTEXT NULL
                                ,CONSTRAINT [PK_sysupdatelog] PRIMARY KEY CLUSTERED ([id] ASC) WITH (
                                    PAD_INDEX = OFF
                                    ,STATISTICS_NORECOMPUTE = OFF
                                    ,IGNORE_DUP_KEY = OFF
                                    ,ALLOW_ROW_LOCKS = ON
                                    ,ALLOW_PAGE_LOCKS = ON
                                    ) ON [PRIMARY]
                                ) ON [PRIMARY]
                            GO
    
            ALTER TABLE [dbo].[sysupdatelog] ADD CONSTRAINT [DF__sysupdate__conte__4EDE7CE6] DEFAULT('')
            FOR [content]
            GO
    
            INSERT INTO [dbo].[sysupdatelog] (
                [UpdateUsername]
                ,[actionname]
                ,[objectname]
                ,[type]
                ,[createDate]
                ,[content]
                )
            SELECT 'sa'
                ,'loginitialdata'
                ,r.ROUTINE_NAME
                ,r.ROUTINE_TYPE
                ,GETDATE()
                ,r.ROUTINE_DEFINITION
            FROM INFORMATION_SCHEMA.ROUTINES r
    
            UNION
    
            SELECT 'sa'
                ,'loginitialdata'
                ,v.TABLE_NAME
                ,'view'
                ,GETDATE()
                ,v.VIEW_DEFINITION
            FROM INFORMATION_SCHEMA.VIEWS v
    
            UNION
    
            SELECT 'sa'
                ,'loginitialdata'
                ,o.NAME
                ,'trigger'
                ,GETDATE()
                ,m.DEFINITION
            FROM sys.objects o
            JOIN sys.sql_modules m ON o.object_id = m.object_id
            WHERE o.type = 'TR'
            GO
    
            CREATE TRIGGER [SCHEMA_AUDIT] ON DATABASE
            FOR CREATE_PROCEDURE
                ,ALTER_PROCEDURE
                ,DROP_PROCEDURE
                ,CREATE_INDEX
                ,ALTER_INDEX
                ,DROP_INDEX
                ,CREATE_TRIGGER
                ,ALTER_TRIGGER
                ,DROP_TRIGGER
                ,ALTER_TABLE
                ,ALTER_VIEW
                ,CREATE_VIEW
                ,DROP_VIEW AS
    
            BEGIN
                SET NOCOUNT ON
    
                DECLARE @data XML
    
                SET @data = Eventdata()
    
                INSERT INTO sysupdatelog
                VALUES (
                    @data.value('(/EVENT_INSTANCE/LoginName)[1]', 'nvarchar(255)')
                    ,@data.value('(/EVENT_INSTANCE/EventType)[1]', 'nvarchar(255)')
                    ,@data.value('(/EVENT_INSTANCE/ObjectName)[1]', 'nvarchar(255)')
                    ,@data.value('(/EVENT_INSTANCE/ObjectType)[1]', 'nvarchar(255)')
                    ,getdate()
                    ,@data.value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]', 'nvarchar(max)')
                    )
    
                SET NOCOUNT OFF
            END
            GO
    
            SET ANSI_NULLS OFF
            GO
    
            SET QUOTED_IDENTIFIER OFF
            GO
    
            ENABLE TRIGGER [SCHEMA_AUDIT] ON DATABASE
            GO
    
相关问题