创建表Else Alter表

时间:2010-11-04 14:49:56

标签: php mysql

这似乎是一个简单的问题,但经过一段时间的搜索,我无法找到答案。

我目前在我的本地数据库中有一个由webapp使用的MySQL表,它们在远程服务器的数据库中有相同的表。现在,我通过PHP使用CREATE TABLE IF NOT EXISTS命令在数据库上创建表:

CREATE TABLE IF NOT EXISTS users (  
  `id` int(10) NOT NULL AUTO_INCREMENT,  
  `username` varchar(18) NOT NULL,  
  PRIMARY KEY (`id`)  
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;

但是,假设我对本地数据库进行了修改,例如添加了一个collumn。每次更改本地数据库时都必须更改远程数据库真的很烦人。有没有更简单的方法来运行代码来创建一个表(如果它不存在),如果它确实存在,请确保它的结构与create table结构的结构相匹配?

这是一个例子,让我想要传达的东西更加清晰。让我们说在本地数据库中我有一个用户表,我决定在我的webapp中我想要另一个列password。所以我转到本地数据库并添加password列。是否有运行PHP / MySQL代码以检查用户表是否存在,如果存在,请确保它具有password列,如果没有,请添加它吗?

4 个答案:

答案 0 :(得分:2)

您实际需要的是迁移,例如您正在寻找一种模式管理工具,它允许您在版本化的代码差异中管理数据库结构。

例如,对于您描述的场景,您首先要创建一个脚本来创建表格,例如001_create_user_table.sql。然后,您将使用架构管理器将这些更改连接并部署到数据库。

当您想要更改或添加内容时,您只需编写另一个脚本,例如002_Add_Password_Column_To_User_Table.sql。只需填写代码即可进行更改。然后再次运行架构管理器。

通常,您告诉架构管理器浏览所有现有的迁移文件。在每次运行时,Schema管理器将更新数据库中的changelog表,因此当您运行它时,它将知道它应该应用哪些脚本。

好处是,您可以将这些迁移添加到常规VCS中,这样您就可以始终知道在哪个版本的应用程序中使用了哪种数据库模式。而且你会有适当的更新日志。

答案 1 :(得分:1)

要直接回答您的问题,您可以创建临时过程来检测字段存在,例如使用如下查询:

SHOW COLUMNS FROM table_name LIKE 'column_name';

然而,在现实世界中,数据库更改通常归为三个脚本。一个创建脚本和两个增量一个向上和向下一个。然后对数据库进行版本控制,以便您知道数据库在任何给定时间处于什么状态。

答案 2 :(得分:0)

要专门检查password列,您可以使用DESCRIBE

$colExists = false;
$res = mysql_query('DESCRIBE `users`');
while ($row = mysql_fetch_assoc($res)) {
    if ($row['Field'] == 'password') {
        $colExists = true;
        break;
    }
}

if (!$colExists) {
    // create column
}

但是,您应该查看replication或其他一些自动化工具,看看它们是否适合您。

答案 3 :(得分:0)

按照以下步骤(你可以在PHP中轻松实现这一点,我假设表的名称是Foo)

1。)运行以下代码:

desc Foo

2.。)根据第一步的结果,你可以创建你的create table命令(你应该)

3。)存储现有表格中的数据,这些表格将被替换为变量(可选,如果您可以使用旧表中的数据,则只需要这个)

4.修改从步骤3开始提取的行。)这样它们将与您的新定义兼容(可选,如果您可以使用旧表中的数据,则只需要这个)

5.。)从新的Foo表中获取行

6。)合并步骤4中得到的结果。)5。)(可选,如果你可以使用旧表中的数据,你只需要这个)

7。)运行旧表的删除表

8。)生成一个替换为命令,将所有行插入到新创建的Foo表中(您可以阅读有关此here的更多信息)

完成这些步骤后,您将获得该表的新版本。如果表太大,可以执行CREATE TABLE IF NOT EXISTS命令,如果不成功,请运行alter命令。

此外,您可以创建一个库来执行这些步骤,并将在未来使用它,而不是多次解决相同的问题。

编辑: 您可以使用以下函数连接数据库:mysql-connect(documentation here) 您可以使用此函数运行查询:mysql-query(文档here

基于第一步,您将获得字段名称(假设您将其存储在名为$ bar的变量中),您可以使用结果生成select命令(连接到您拥有重要数据的数据库。可能是两个):

$field_list = "1";
foreach ($bar as $key => $value)
    $field_list.= ",".$bar[$key];

mysql_connect(/*connection data*/);
mysql_query("select ".$field_list." from Foo");

您可以使用新资源构建插入命令,以便在删除重新创建后插入所有重要数据(关于资源阅读更多here,关于如何生成插入内容,您可以阅读here ,但我建议你应该使用replace into而不是insert,就像插入一样,除非它替换了行,如果它已经存在,它在这里比插入更好,阅读更多here

所以,使用mysql_connect和mysql_query,mysql_query函数返回的资源可以用于以后替换(我现在已经链接了你需要的所有内容,所以我很确定你会解决问题。),为以前不够具体而道歉。