代码之家  ›  专栏  ›  技术社区  ›  Aaronaught

数据库创建脚本-外部参数/设置

  •  -1
  • Aaronaught  · 技术社区  · 15 年前

    问题摘要:

    有没有比下面发布的更好的方法来实现自动化部署的数据库创建阶段?

    背景/要求:

    • 我正在尝试使用类似于 this one . 这个问题是关于 基线 包括物理创建数据库。

    • 目前的计划是实现一个简单的命令行工具(在.NET中),以应用基线和更改脚本。我希望该工具是通用的(我们有几个独立的事务数据库),因此希望所有脚本都是外部的,包括数据库创建。

    • 测试环境可能不是生产的完美副本;物理文件的位置和大小可能需要很大的不同。

    当前想法: (我正在寻找反馈)

    基本上是一个模板系统。使用简单 string.Replace 在如下脚本上:

    CREATE DATABASE [{DBNAME}] ON PRIMARY
    (
        NAME = N'MyDB_Data',
        FILENAME = N'{PRIMARYFILENAME}',
        SIZE = {PRIMARYSIZE}KB,
        MAXSIZE = UNLIMITED,
        FILEGROWTH = 5%
    ),
    FILEGROUP [FG_MyDB_Index]
    (
        NAME = N'MyDB_Index',
        FILENAME = N'{INDEXFILENAME}',
        SIZE = {INDEXSIZE}KB,
        MAXSIZE = UNLIMITED,
        FILEGROWTH = 5%
    ),
    -- more filegroups ...
    LOG ON 
    (
        NAME = N'MyDB_Log',
        FILENAME = N'{LOGFILENAME}',
        SIZE = {LOGSIZE}KB,
        -- etc.
    )
    GO
    
    ALTER DATABASE [{DBNAME}] SET COMPATIBILITY_LEVEL = 100
    GO
    
    -- more ALTER DATABASE stuff ...
    

    显然,要替换的令牌是 {DBNAME} {LOGFILESIZE} .这些值可以从命令行参数中获取,也可以从外部文件中获取。

    我看到的这个方法的问题是:

    • “script”本身表示为T-SQL脚本,但实际上是无效的T-SQL。它强制您要么使用部署工具,要么执行冗长的手动搜索和替换。

    • 无法使用“默认”值运行它。更糟糕的是,它没有提供一个好的默认值是什么的指示。

    • 感觉很脆弱。似乎可以更改脚本,使其仍然是有效的SQL(或者至少与当前的“有效”一样),但仍然会破坏部署工具。其中一个问题是,缺乏任何逃跑的机会。文本字符串中的模板参数使我的皮肤爬行。

    我考虑过的其他可能性:

    • 构造要用其执行的动态SQL脚本 sp_executesql . 这将提供真正参数的好处,而不是简单的模板,但会使脚本编写、测试和维护变得异常麻烦,特别是如果我们决定采用新的基线(我们可能会这样做——它是一个大数据库)。

    • 使用SSMS模板参数。这样可以很好地将其与部署工具分离开来,但也会使其难以与部署工具集成——这类似于将其与SSM绑定在一起。

    • 将脚本嵌入部署工具中。这样就没有人能处理它,很明显脚本只是一个必须处理的模板。默认值可以嵌入到脚本的“关闭”位置。主要的,巨大的缺点是部署工具变得特定于应用程序,可能需要对一些真正不需要更改代码的东西进行代码更改。

    • 从外部的、人类可读的文件(如yaml)动态生成整个脚本。一开始这个想法 似乎 非常优雅,但最终它开始下沉,因为我可能会重新发明轮子。 一切 关于数据库必须包含在文件中,那么这是否真的比手动修改普通的SQL脚本或者甚至通过SSMS手动创建数据库有任何优势呢?

    这些选择似乎都不太正确。我想要的是 独立的 (正如代码理论上独立于您用来构建它的环境一样),但是 可读的 (无“SQL中的SQL”),以及 不言自明 (清楚地标识出需要什么设置以及哪些好的默认设置)。

    有没有什么方法可以达到我想要达到的所有目标?或者我是太挑剔了,还是看问题的方式不对?

    (P.S.我是 目前正在寻找能够为我执行此任务的商业、独立的第三方工具。”现在我有两个问题。”)

    3 回复  |  直到 15 年前
        1
  •  1
  •   David Hogue    15 年前

    我们通过编写一个可以使用sqlcmd参数的脚本解决了类似的问题。类似:

    :setvar filename somefile.ext
    :setvar version 1
    :on error exit
    
    print 'This is version $(version) on $(filename)'
    -- the rest of the actual script
    

    这可以通过命令行或SSMS运行。最后,我们制作了一个工具,可以读取文件并用相同的语法替换变量。

    我不认为它能解决你列出的每一个问题,但它应该对一些问题有所帮助。

        2
  •  1
  •   marc_s    15 年前

    我可能会将此脚本用作命令行工具中的嵌入式模板;从命令行参数中获取所需的最小信息(替换占位符-dbname和logfilesize;其他类似文件组名称的内容可以从dbname中推导,例如fg_dbname_u primary(对于主文件组))。使用文本搜索/替换来填充空白,然后针对要将其部署到的SQL服务器执行此操作。

    例如:

    CreateDB -server:(local) -dbname:MyTestDB -logsize:50 (as in 50 MB)
    

    或: 使用SMO(SQL Server管理对象)创建数据库。您基本上需要相同的信息(数据库名称、日志文件大小),并且可以通过编程方式创建数据库及其布局—不需要T-SQL脚本。

    附带说明:如果要创建单独的文件组,我建议至少使用以下布局:

    • 主文件组 :仅用于系统目录视图-无其他内容
    • 数据文件组 :标记为默认值,用于表格
    • 索引文件组 对于指数

    这样,就可以最大限度地减小主文件组的大小,从而最大限度地降低主文件组遇到磁盘错误和损坏的风险。主文件组包含系统目录,因此如果该fg被破坏,那么整个db就是toast。

        3
  •  1
  •   boydc7    15 年前

    你考虑过使用吗 SQLCMD scripts 以及 SQLCMD utility 而不是编写自己的命令行界面,或者编写自己的命令行界面并简单地包装sqlcmd功能?当然,这将假定您只希望支持SQL 2005及更高版本。我在过去用过几种不同的方法来实现这一点(例如,使用带有包装sqlcmd的参数/选项的简单批处理文件,使用更广泛的方法来包装当时不幸是vb 6.0的代码,等等)。

    如果您采用自己的代码进行包装,可能还需要考虑使用PowerShell(我目前也在考虑这一点)。SQL Server现在包括自定义PowerShell提供程序和对SMO功能、代码执行、管理等的扩展,这些功能可以自然地轻松地扩展到包装sqlcmd和SQL功能。

    考虑到您正在尝试做的工作,sqlcmd(和sqlcmd脚本)的好处似乎与以下内容非常吻合:

    • 这些脚本对于使用/解释/集成SSMS和其他IDE仍然有效。
    • 默认值有几个选项,但脚本本身没有真正集成任何选项(环境变量、命令行选项等)。此外,您可能需要考虑从正在运行的服务器/实例(如模型或master或tempdb)上的预定义位置提取文件/组位置的默认值。
    • 在当前支持sqlcmd的IDE将在sqlcmd模式下为未定义的变量/值组合抛出异常的意义上,这就不那么脆弱了。

    如果你想交换关于你的项目的笔记/想法,我肯定会帮助你完成编码和/或只是讨论我遇到的一些挑战(例如,引擎的不同版本和功能的使用是我最初没有想到的一些事情)。

    推荐文章