2

我与我们的 DBA 讨论了如何更改数据库模式。他的观点是,所有的变化都必须是可逆的。例如:

  • 过时的表/列一旦变得多余就不应被删除。相反,它们应该至少保留几个版本。
  • 不要重命名表/列,而是创建一个新表/列并将内容从旧的复制到新的
  • 当需要修改名为“foo”的存储过程/触发器时,保留原始存储过程/触发器并创建一个名为“foo2”的新存储过程/触发器。当然,这意味着必须更新对存储的 proc/trigger 的所有引用以引用新名称

这种方法的好处是,如果(例如)发布失败并且需要恢复到应用程序的以前版本,数据库可以切换到以前的版本。如果只是删除表和列,这是不可能的。

我对这种方法的智慧有自己的看法,但我暂时将它们保密,以免引起反应的偏见。如果有什么不同,环境是一家开发社交网络应用程序的初创公司。

4

4 回答 4

4

您没有说您所处的软件环境,而是来自企业(银行)工作,这是我的观点。

一般原则是正确的,发布可能出现问题的可能不是 SQL 代码而是客户端代码,您需要能够恢复服务器。我已经多次看到这种情况发生。

如果在发布后的某个时间发现问题,比如几个小时,那么您将不得不处理在此期间输入的任何数据。

可能是在发布时获取的数据库副本可以使用新数据进行更新,但环境可能不允许这样做(尽管这是我完成大型发布的主要方式)。

根据我的经验,发布问题可能会影响系统的一小部分,并且大部分都可以,因此您不想关闭并恢复整个系统只是为了恢复一小部分。

但是,鉴于更改需要是可逆的,我认为您的 dba 有点保守。

应该在某个阶段删除表和列,但这可能要等到以后的版本,以便您可以恢复

是的,总是复制数据(实际上最好不要重命名,因为除非名称完全不合适,否则进行更改的风险肯定会带来任何好处)。如果要更改列的类型,则取决于 SQL 服务器和正在执行的操作。例如,在 Sybase 上,我将允许增加列的大小,因为这不会改变数据,但减小大小将需要副本,因为数据值可能会受到影响。

至于存储过程和触发器,我不会重命名而只是覆盖,因为这就像编译的代码。您正在更改的对象不依赖于数据,因此可以立即重新创建。虽然这确实假设你可以很容易地从版本控制等中获取任何以前版本的存储过程。(我见过代码不受版本控制的数据库,唯一的版本在数据库中,然后我可以看到不需要覆盖代码 - 但我会在下一个版本之前控制代码)

于 2009-09-24T15:47:33.363 回答
1

我同意你应该总是备份你的数据库,但你也不应该用无用的信息污染你的数据库。就像你不应该让你的代码被无用的代码污染一样。

备份数据库,然后制作你的模组。如果发生任何事情,请恢复到您的备份。

将所有内容一直保存在数据库中会导致令人难以置信的膨胀。不仅如此,您还会遇到一些性能问题。最重要的是,以后没人会想碰它,因为他们不知道它为什么在那里。与代码不同,要弄清楚为什么在将来的某个日期在数据库中还有其他列等,要困难得多。他们不会知道它是遗留数据/代码,因此他们只会继续维护它!

于 2009-09-24T15:54:06.910 回答
1

“过时的表/列不应该在它们变得多余时立即被删除。相反,它们应该至少保留几个版本。”

然后他是否还保留了管理那些他不想立即删除的列的约束?

这意味着可能由于用户声明的约束不再是业务规则的一部分而导致更新失败?

我有点同情那些一直寻求“逐步谨慎地逐步淘汰”的人。我只是不知道在您提到的所有示例中,这种方法在数据库上下文中是否可行。

于 2009-09-24T21:59:12.387 回答
0

这听起来像 DBA 懒得做备份。;)

于 2009-09-24T15:48:55.000 回答