2010-11-04 84 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