如何在现实世界中“升级”数据库?

时间:2010-06-03 06:04:01

标签: php database

我的公司使用php + mysql开发了一个Web应用程序。系统可以向用户显示产品的原始价格和折扣价格。如果您尚未登录,则会获得原始价格,如果您已登录,则会获得折扣价。这很容易理解。

但是我的公司想要系统中的更多功能,它希望根据不同的用户显示不同的价格。例如,用户A是一个黄金parnter,他可以获得50%的折扣。用户B是银色的parnter,只有30%的折扣。但是这个逻辑没有在原始系统中准备,所以我需要在数据库中添加一些属性,至少在这个例子中是用户类型。是否有关于如何将当前数据库合并到我的新版本数据库的建议。此外,所有数据都应该保留,服务器应该全天候工作。 (在数据库中停止)

有可能这样做吗?此外,任何建议未来维护建议?你呢。

3 个答案:

答案 0 :(得分:1)

http://dev.mysql.com/doc/refman/5.1/en/alter-table.html

以下是ALTER TABLE的更具体的例子 http://php.about.com/od/learnmysql/p/alter_table.htm

您可以使用ALTER TABLE向表中添加必要的列,然后使用UPDATE为每个用户设置用户类型。然后部署新版本的应用。使用新列。

答案 1 :(得分:1)

我建议编写一个工具来逐步向数据库运行SQL查询。很像Rails迁移。

在我目前正在研究的系统中,我们用python编写了这样的工具,我们将脚本命名为000000_somename.sql,其中0是我们SCM中的修订号(subversion),该工具运行为开发/测试的一部分,最后部署到生产。

这样做的好处是能够在数据库更改方面回溯,就像在代码中一样(如果使用源代码版本控制工具)。

答案 2 :(得分:0)

您是否将ORM用于数据访问层?我知道Doctrine附带了一个迁移API,允许版本上下切换(如果新版本出现问题)。

在任何框架或ORM考虑之外,快速脚本将最小化减速(或者如果进程太长则停机)。

在我看来,我宁愿选择30秒的网站访问中断和信息页面,而不是缩短中断时间,但要获得可见的错误或根本没有显示。如果中断时间很重要,最好在晚上或交通流量较小时这样做。

这可以在一个脚本中完成(或者至少由一个命令行启动),当我们要在shell脚本中包含这样的脚本时:

  • 将应用程序置于待机状态(临时静态页面):您可以使用.htaccess重定向或适用于您的应用程序/服务器环境的任何内容。
  • svn udpate(或switch)用于源代码和资产升级
  • 空缓存,清理临时文件等
  • 重建生成的类(特定于symfony)
  • 使用ALTER / CREATE TABLE查询升级数据库结构
  • 如果需要,将数据从旧结构迁移到新结构:根据您在结构上更改的内容,可能需要在更改数据库结构之前获取数据,或使用tmp表。
  • 如果一切顺利,请删除临时页面。升级完成
  • 如果出现问题,会向操作员显示红色消息,以便查看发生了什么,尝试修复它,然后手动删除等待页面。

脚本应该检查每个步骤并停止第一个错误,它应该是详细的(但简洁)它在所有步骤中的作用,因此如果出现问题,你可以更快地修复应用程序。 最好的是可恢复的脚本(第2步的错误 - 停止进程 - 手动修复 - 在第3步恢复),我从来没有花时间以这种方式实现它。

如果效果很好但是这些脚本必须在尽可能接近生产环境的环境中进行密集测试。 一般来说,我们在本地开发这样的脚本,并在生产环境(只是不同的路径和数据库)的同一平台上测试它们

如果等待页面不是一个选项,您可以不进行任何操作,但需要确保数据和用户会话的完整性。例如,在升级/数据传输期间对表使用LOCK,并对修改后的文件使用独占锁(我认为是SVN)

还有其他更好的解决方案,但它基本上是我使用的,它为我们完成了工作。主要缺点是必须在每个主要版本上重写一种脚本,这使我不得不寻找其他选项来做到这一点,但是哪一个?如果有人在这里有更好更简单的选择,我会很高兴。