编写用于部署的SQL脚本的最佳实践

时间:2011-01-17 21:07:43

标签: sql database database-design scripting

我想知道为编写用于生产和/或开发的数据库编写SQL脚本的最佳做法是什么,例如:

  • 我应该包含CREATE DATABASE语句吗?
  • 我应该在同一个脚本中为数据库创建用户吗?
  • 在执行脚本正文之前禁用FK检查是否正确?
  • 我可以在交易中加入漏洞脚本吗?
  • 最好为每个数据库生成1个脚本,而不是为所有数据库生成一个脚本?

谢谢!

6 个答案:

答案 0 :(得分:4)

您的问题的问题很难回答,因为它取决于您尝试实现的脚本的使用方式。您也没有说您正在使用哪个数据库服务器,因为提供的工具可以使某些任务更容易。

按顺序排列你的观点,这里有一些建议,这可能与每个人都有很大不同:)

  • 我应该包含CREATE DATABASE 声明?

您还在考虑使用哪种替代方案?如果你的问题是你应该将CREATE DATABASE语句放在与它所依赖的表创建相同的脚本中。在开发DB时我使用单独的create DB脚本,因为我有一个脚本来删除所有对象,因此我不需要再次创建数据库。

  • 我应该在同一个脚本中为数据库创建用户吗?

我不会,因为用户可能会改变,但您的架构没有。不妨在较小的脚本中管理这些更改。

  • 在执行脚本正文之前禁用FK检查是否正确?

如果要导入数据以尝试恢复数据库,那么您可能必须使用自动增量ID并希望保留相同的值。此外,您最终可能会“无序”地导入表格而不执行检查。

  • 我可以在整个交易中包含整个脚本吗?

是的,您可以,但这又取决于您运行的脚本类型。如果在重建db之后导入数据,则整个导入应该工作或失败。但是,导入期间您的事务文件将会非常庞大​​。

  • 最好为每个数据库生成1个脚本,而不是为所有数据库生成一个脚本?

同样,出于维护目的,最好将它们分开。

答案 1 :(得分:2)

这可能取决于什么类型的数据库以及如何使用和部署它。我正在开发一个部署在许多不同客户站点的n层标准应用程序。

  1. 我不在脚本中添加CREATE DATABASE语句。创建数据库是安装脚本的一部分,允许用户选择服务器,数据库名称和排序规则

  2. 我不了解客户网站上的用户,所以我不添加创建用户语句,唯一需要访问数据库的用户是执行中间轮胎应用程序的用户。

    < / LI>
  3. 我不禁用FK检查。我需要它们来保护数据库的一致性,即使是我编写正文脚本的人也是如此。我用FK来捕捉我的错误。

  4. 我没有在一个事务中包含整个脚本。我要求用户在运行任何db升级脚本之前备份db。对于创建新数据库,没有什么可以保护的,因此不需要在事务中运行。对于升级,有时会对db进行大量更改。几年前,我们在大约250个表中从varchar切换到nvarchar。不是你想在一次交易中做的事情。

  5. 我建议你为每个数据库生成一个脚本,版本分别控制脚本。

答案 2 :(得分:0)

直接回答,请询问您是否需要扩展任何一点

* Should I include the CREATE DATABASE statement?

通常我会包含它,因为你正在创建和拥有数据库。

* Should I create users for the database in the same script?

这也是一个好主意,特别是如果您的应用程序使用特定用户。

* Is correct to disable FK check before executing the body of the script?

如果脚本包含数据填充,那么它有助于禁用它以使顺序不太重要,否则你可以进入复杂的脚本插入(没有fk链接),创建fk记录,更新fk列。

* May I include the hole script in a transaction?

这通常不是一个好主意。特别是如果包含数据填充,因为交易可能变得非常笨重。由于您正在创建数据库,因此只需删除它并在出现问题时重新开始。

* Is better to generate 1 script per database than one script for all of them?

我建议每个数据库一个,以便在需要时将它们隔离并更容易进行故障排除。

答案 3 :(得分:0)

出于开发目的,每个数据库对象创建一个脚本(每个表,存储过程等一个脚本)是个好主意。如果您以这种方式将它们检入源控制系统,那么开发人员可以检查单个对象,您可以轻松跟踪版本并知道更改的内容和时间。

部署时,您可能希望将每个版本的更改合并到一个脚本中。 Red Gate SQL compare或Visual Studio Team System等工具可以帮助您实现这一目标。

答案 4 :(得分:0)

  

我应该包含CREATE DATABASE语句吗?
  我应该在同一个脚本中为数据库创建用户吗?

这取决于您的DBMS和您的客户。

在Oracle环境中,你可能永远不会被允许做这样的事情(主要是因为在Oracle世界“数据库”的程度超过例如完全不同的的PostgreSQL或MySQL的世界)。

有时,客户将拥有一个DBA,它不会让您创建数据库(或模式或用户 - 具体取决于所使用的DBMS)。因此,您需要将该信息提供给DBA,以便他/她为您的脚本准备环境。

  

我可以在事务中包含漏洞脚本吗?

这完全取决于您使用的DBMS。

一些数据库不支持事务DDL,当你执行一个DDL语句隐含提交任何交易,所以你需要考虑你的安装脚本的顺序。

为了用数据填充表格,我肯定会尝试在单个事务中执行此操作,但这又取决于您的DBMS。

有些DBMS是更快,如果你犯一次或非常罕(Oracle和PostgreSQL属于这一类),但如果你犯更多的时候会慢下来。

其他DBMS处理规模较小,但更多的交易更好,会减慢,如果交易受到太大(SQL Server和MySQL往往会陷入那个方向)

答案 5 :(得分:0)

无论是首次设置还是推出新版本,最佳做法都会有很大差异。首次设置是,您需要创建数据库并创建表脚本。对于新版本,您只需要编写前一版本的更改脚本,因此除非是新表,否则不需要创建数据库和创建表。现在您需要更改表语句,因为您不希望丢失现有数据。我通常使用drop和create statment编写存储过程,函数和视图,因为丢弃那些pbject通常不会影响底层数据。

我发现最好使用存储在版本中的源代码管理中的脚本来创建所有数据库更改。因此,如果客户端是新的,则运行create version 1.0脚本,然后按顺序应用所有其他版本。如果客户端只是从1.2版升级到1.3版,那么只运行1.3版源代码控制库中的脚本。这还包括用于填充或向查找表添加记录的脚本。

对于交易,您可能希望将它们分成几个块,而不是将prod数据库锁定在一个事务中。

如果需要,我们还会编写反转脚本以返回旧版本。如果您有一部分变更导致产品出现意外问题(通常是性能问题),这会让生活更轻松。