2010-11-04 85 views
4

这似乎是一个简单的问题,但经过一段时间的搜索,我无法弄清楚答案。创建表其他变更表

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

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,例如。每次更改本地数据库时都必须更改远程数据库,这实在令人烦恼。有没有更简单的方法来运行代码来创建表,如果它不存在,并且它确实存在,请确保它的结构与创建表结构相匹配?

下面是一个例子,使我想要传达一点清晰。假设在本地数据库中有一个用户表,并且我决定在我的web应用程序中想要另一个列表password。所以我去本地数据库并添加一个password列表。我可以运行PHP/MySQL代码来检查用户表是否存在,如果有,请确保它有一个password列,如果不存在,添加它?

+0

+1你的问题对许多数据库程序员都有帮助。 – 2010-11-04 15:16:13

回答

1

直接回答你的问题,你可以创建临时程序,检测等中,使用这样的查询领域存在:

SHOW COLUMNS FROM table_name LIKE 'column_name';

然而,在现实世界中,数据库的变化是一般卷成三个脚本。一个创建脚本和两个增量一个和一个向下。然后对数据库进行版本控制,以便您知道数据库在任何给定时间处于什么状态。

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或其他一些自动化工具,看看他们是否会为你更好的解决方案。

0

按照以下步骤(你可以很容易地在PHP中实现这一点,我认为该表的名称是富)

1)运行下面的代码:

desc Foo 

2)根据在第一步的结果你可以使你的创建表命令(你应该)

3.)存储你的数据从现有的表,将被替换成一个变量(可选的,你只需要这个,如果你可以可能使用旧表中的数据)

4)修改从第3步所提取的行),这样他们将与新定义兼容(可选,你只需要这个,如果你有可能从旧表使用数据)

5)获取从你的新富表

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

7 )为旧表运行drop table

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

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

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

编辑: 您可以使用此功能连接数据库:MySQL的连接(文档here) 可以运行使用此功能查询:MySQL的查询(文档here

基于第一步骤中,您将获得字段名称(假设您将其存储在名为$ bar的变量中),并且可以使用结果生成选择命令(连接到具有重要数据的数据库,它可能都是):

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

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

你可以我们e你的新资源建立一个插入命令插入删除重新创建后的所有重要数据(关于资源阅读更多here,关于如何生成插入您可以读取here,但我建议你应该使用替换插入而不是插入其工作方式插入,但它取代了行,如果它已经存在,它在这里比的刀片,多读一些here

所以,使用的mysql_connect和的mysql_query,并请求mysql_query函数返回的资源可用于以后再替换(我现在已经链接了所有你需要的URL,所以我敢肯定你会解决这个问题),但以前没有足够具体的道歉。

+0

我将如何能够存储现有表中的数据(如在什么特定命令中)?然后,我会用什么来将行插入到新生成的表中? – element119 2010-11-04 16:08:37

+0

感谢您的更新,我会尽力。 – element119 2010-11-05 01:28:05

+0

不客气。 – 2010-11-05 11:53:39

2

实际上您正在寻找的是迁移,例如您正在寻找一个架构管理工具,可让您以版本化代码差异来管理数据库结构。例如,对于您描述的场景,您首先要创建一个脚本来创建表格,例如, 001_create_user_table.sql。然后,您将使用架构管理器将这些更改连接并部署到您的数据库。

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

通常,您要让架构管理器检查所有现有的迁移文件。在每次运行时,架构管理器都会更新数据库中的更新日志表,因此当您运行它时,它会知道应该应用哪个脚本。

好的是,您可以将这些迁移添加到常规VCS中,以便您始终知道您的应用程序版本是哪个数据库模式。你将有一个适当的更新日志。

+0

你会建议哪种模式管理工具?我不是在寻找一些非常复杂的东西,只是一个简单的工具来管理数据库结构,就像你帮助的那样。 – element119 2010-11-04 16:05:43

+0

@Chromium从链接中给出的,尽管在迁移过程中存在一些缺陷时,我会使用Phing + DBDeploy,主要是因为它使用普通的旧sql文件,我可以使用Phing来执行任何其他部署任务无论如何必须做。另外两个是“仅”架构管理者。尽管Akrabat的Schema经理可能更容易设置和使用。我从来没有使用MDB2_Schema。 – Gordon 2010-11-04 16:15:23