国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數(shù)據(jù)庫 > MySQL > 正文

將你的網(wǎng)站從MySQL改為Postgre SQL

2024-07-24 12:55:53
字體:
供稿:網(wǎng)友

我的站點最初是采用php驅(qū)動,由mysql數(shù)據(jù)庫支持的方案,這在當(dāng)時是一個明智的方案。在2001年夏天,我將我的數(shù)據(jù)庫換成了postgresql(有時也簡稱為postgres)。

這個教程分為兩部分,第一部分講述了我進(jìn)行這種轉(zhuǎn)換的動機(jī),并一步步地解釋了如何將已存在有mysql的數(shù)據(jù)轉(zhuǎn)換到postgres中。第二部分將會解釋如何根據(jù)新的數(shù)據(jù)庫系統(tǒng)對php進(jìn)行相應(yīng)的調(diào)整。

轉(zhuǎn)換的動機(jī)

我第一次了解postgres是在phpbuilder網(wǎng)站的一篇文章中。這篇文章將postgres和mysql進(jìn)行了比較,當(dāng)時我正在使用 mysql。但是,當(dāng)我閱讀了這篇文章后,我對postgres著了迷 -- 但是當(dāng)時我還沒有想到對我的網(wǎng)站進(jìn)行重新的設(shè)計。

我繼續(xù)使用mysql,因為我的主機(jī)提供商只能提供mysql的支持,這是我所無法改變的。直到有一天,主機(jī)提供商的主機(jī)崩潰了。我立即換了一個主機(jī)提供商,與原來的那個相比,新的主機(jī)提供商有很多不同,他們在安全性和穩(wěn)定性方面對我作出了更多的承諾。新公司試圖說服我使用postgres,因為 postgres要比mysql來得更穩(wěn)定,但是我當(dāng)時沒有接受這個建議,因為我的網(wǎng)站已經(jīng)根據(jù)mysql完成了全部的編碼工作。他們只好專門為我的站點安裝了mysql。于是問題開始了。

我的第一個工作是將舊服務(wù)器上的mysql的數(shù)據(jù)拷貝到新的主機(jī)上。首先,我將已有的數(shù)據(jù)dump到一個sql文件中,然后在新的主機(jī)上導(dǎo)入這個sql文件。在處理這個數(shù)千行的文件時,mysql迅速地崩潰了。重啟mysql后,其中大概只有一半數(shù)據(jù)成功地導(dǎo)入了,而且mysql只能間歇性地工作。最后,他們不得不刪除了已經(jīng)導(dǎo)入的信息讓我再試一次。mysql再次崩潰。這種情況重復(fù)了好幾次,直到最終我決定將我的sql文件分割成幾塊。我不得不又試了幾次,最后終于將絕大多數(shù)的數(shù)據(jù)都成功地導(dǎo)入到新的mysql服務(wù)器中。一切都好了,我總算松了一口氣。

在下面的幾個月中,mysql幾乎每兩周都要崩潰一次,其中最慘痛的一次是在2001年6月底。這一次,存儲在mysql中的數(shù)據(jù)完全被毀壞了。我有一個 sql的備份文件,但是因為上次向mysql中導(dǎo)入大量數(shù)據(jù)的痛苦的經(jīng)歷,這一次我再也不想通過這個備份恢復(fù)數(shù)據(jù)了。這時,公司再次建議我對我的網(wǎng)站進(jìn)行轉(zhuǎn)向,使用postgres。由于mysql的失敗,最終我接受了這個建議。

將數(shù)據(jù)從mysql轉(zhuǎn)移到postgres中

將數(shù)據(jù)從mysql轉(zhuǎn)移到postgres是一個不大的挑戰(zhàn),因為postgres比mysql支持了更多的sql的標(biāo)準(zhǔn)格式,在postgres中直接使用sql的dump結(jié)果是不可能的。但是,sql語法相當(dāng)相似,因此對于我來說,這并沒有花費(fèi)太多的時間。

對mysql的dump結(jié)果進(jìn)行轉(zhuǎn)換

首先,要求你的主機(jī)提供商為你的帳號建立一個數(shù)據(jù)庫。和mysql數(shù)據(jù)庫一樣,postgres的數(shù)據(jù)庫也由一系列包含實際數(shù)據(jù)的數(shù)據(jù)表組成。然后,使用mysqldump命令為你的mysql數(shù)據(jù)庫做一個dump文件。

mysqldump -u username -p databasename > sqldump.txt

使用ftp將整個dump文件下載下來?,F(xiàn)在在你的計算機(jī)上有了這個sql文件,你可以將其轉(zhuǎn)換成postgres可以導(dǎo)入的文件。

首先,從dump文件中剪切所有的mysql的create table查詢,并將其粘貼到一個單獨(dú)的文本文件中。下一步是使用postgres可以理解的語言重新對數(shù)據(jù)表進(jìn)行定義。

postgres建立表的sql和mysql非常類似,但不完全一樣。下面是一個例子:

以下為引用的內(nèi)容:
create table practicetable

  {

  someid serial,

  time timestamp default now(),

  name varchar(50),

  address varchar(50),

  city varchar(50),

  state varchar(2),

  country varchar(3) default 'usa',

  postlcode varchar(15),

  age smallint,

  lattitude real,

  longitude real,

  somebool boolean,

  message textitem

  };

在一個postgres的表定義中,字段名后面必須跟著字段類型。在上面的例子中我們給出了一些最普通的字段類型,你還可以在有關(guān)postgres數(shù)據(jù)類型的文檔中找到全部的字段類型的列表。對于不同的任務(wù),postgres在字段類型方面有多種選擇,并可以存儲各種類型的數(shù)據(jù),從internet地址到貨幣信息到幾何對象的定義。這兒簡要地介紹最常用的幾種數(shù)據(jù)類型。

serial類型的字段和mysql中的自增唯一id等價。當(dāng)你在你的數(shù)據(jù)表中定義了一個serial類型的列后,serial的自增功能會被自動添加到數(shù)據(jù)庫。當(dāng)自增功能不能適應(yīng)實際需求時,我們可以自定義唯一id的邏輯。從mysql向postgres轉(zhuǎn)輸數(shù)據(jù)時,默認(rèn)的功能已經(jīng)足夠了。

和字面上的意義一樣varchar類型是一個可變長度的文本字段。字段的長度由括號中的數(shù)值定義。例如,varchar(5)定義了一個最多可包含5個字符的文本字段。

smallint、int和bigint用來定義整型字段。smallint字段可存儲數(shù)值范圍為-32768到+32767(實際的范圍可能會稍微受到你的計算機(jī)類型的影響,上面的范圍適用于最普通的系統(tǒng))。int字段可存儲數(shù)值范圍為-2147483648到+2147483647。而bigin字段類型可存儲任何更大的整數(shù),它沒有范圍的限制。

real字符類型是一個包含十進(jìn)制小數(shù)的實數(shù)。它可以精確到小數(shù)點后六位。double precision字段與此相類似,但是它可以精確到小數(shù)點后15位。

boolean字段是真或假、1或0。這和mysql中相似。

timestamp字段和mysql中的情況類型。每次記錄更新時,timestamp被更新為當(dāng)前的日期和時間。postgres的時間字段還可以包含時區(qū)信息。有關(guān)postgres時間數(shù)據(jù)的更復(fù)雜的應(yīng)用,請參看postgresql文檔的日期和時間。

建立數(shù)據(jù)表

當(dāng)你使用sql文件在postgres中建立數(shù)據(jù)表時,請檢查在每一個create table查詢的最后是不是都以分號結(jié)束 - 這對于postgres是不可省略的。使用telnet這樣的工具連接到你的web主機(jī),然后用下面的方法建立數(shù)據(jù)表。

首先,用一個文本編輯器打開你的表定義文件。然后登錄到你的主機(jī),并輸入psql運(yùn)行postgres交互終端。默認(rèn)的用戶論證方式是使用你的 telnet/ftp用戶名作為你的postgres帳號。這使得不需要你輸入用戶名和口令,postgres就能自動鑒別你的身份。你的web主機(jī)也許不是采用的這種方式,在這種情況下,你需要為psql程序帶入?yún)?shù):psql -d databasename -u username -w。-d用來指定數(shù)據(jù)庫,-u指定用戶名,而-w要求psql提示你輸入一個口令。

當(dāng)你成功地運(yùn)行了psql以后,將每個create table查詢單獨(dú)地粘貼到psql中并按回車鍵。如果在你的sql語句中有錯誤,psql會給出相應(yīng)提示。通過逐一地加入每一個表,你會得到每一個表的調(diào)試信息,這樣做起來相當(dāng)簡單。

如果,在你輸入了表的定義之后,你發(fā)現(xiàn)遺漏了一兩個字段,有兩種方法能解決這個問題。你可以使用alter table命令,或者是使用drop table刪除這張表,然后重新生成。如果你使用第二種方法,你會看到一個警告以驗證你是不是真的想要刪除表。

要使用drop table命令,只需要輸入drop table practicetable;。這會刪除我們剛才定義的表。但是當(dāng)你對這個表重新進(jìn)行定義時,你會發(fā)現(xiàn)一個錯誤。這是因為在刪除一個表時并不相應(yīng)地刪除這個表中serial類型字段的序列。這些遺留下來的序列會在你重建表時引起錯誤。要解決這個問題,你必須在刪除表之前使用drop sequence sequencename;刪除相應(yīng)的序列。而且有件很討厭的事,那就是序列名并不就是serial列的名字。當(dāng)你定義一個serial類型的字段時, postgres會自動生成這樣的序列名:tablename_colname_seq。在現(xiàn)在的這種情況下,drop sequence 語句將會是這樣的:drop sequence practicetable_someid_seq;。現(xiàn)在你就可以刪除這張表并重新生成它了。

在添加完這些表之后,你可以輸入z對這些表進(jìn)行復(fù)查。而輸入q將會退出psql?,F(xiàn)在剩下來的就是準(zhǔn)備輸入到postgres中的數(shù)據(jù)了。

處理dump文件

因為mysql保留了絕大多數(shù)的sql語言的標(biāo)準(zhǔn),從一個sql的dump文件中導(dǎo)出實際數(shù)據(jù)并不是太困難的。然而,在我們使用postgres對這個文件進(jìn)行處理前,我們還是需要作一些編輯工作。

對于數(shù)據(jù)記錄,在mysql和postgres之間的主要區(qū)別是對引號的處理。在postgres中,字符串變量(包含文本的變量)必須由兩個單引號引出。而在mysql中,你還可以使用雙引號,但是幸運(yùn)的是,在mysqldump程序中程序中使用的是單引號,這剛好與postgres一致。然而, mysql和postgres還有一個地方不同,那就是對字符串中出現(xiàn)的引號的處理。在mysql中使用"",而在postgres中使用"。使用你的文本編輯器并通過替換功能將其中所有的""替換為"。有趣的是,postgres和mysql都使用''來表示單引號,這使得我們免去了一個麻煩。

導(dǎo)入到postgres中

當(dāng)你整理好sql dump文件后,將這個文件上載到你的web主機(jī)中,就如同你當(dāng)初建表那樣登錄到主機(jī),轉(zhuǎn)到sql dump文件存放的目錄。啟動psql,不過這次你必須使用另一個命令行參數(shù):psql -f sqldump.txt,這兒的sqldump.txt就改為你的sql dump文件的文件名。這個命令會將全部的sql文件導(dǎo)入到適當(dāng)?shù)膒ostgres數(shù)據(jù)表中。在此之前,你也許還需要其它的一些命令行參數(shù)以使得psql 可以對你的身份進(jìn)行驗證。如果發(fā)生了錯誤,psql會告訴這是由什么引起的。找到文件中的這一部分,找到問題并手工解決它。我當(dāng)初是沒有遇到任何問題,我差不多準(zhǔn)備結(jié)束工作了。但是,很快我注意到另一個問題。

在我開始使用我的新的postgres驅(qū)動的站點時,我偶然地發(fā)現(xiàn)mysql和postgres之間另一個不兼容的地方。serial類型的自增字段所使用的postgres的序列,它從1開始,并在每次有一個serial類型字段的記錄插入時加一。然而,在我導(dǎo)入mysql的dump文件時,這個 dump文件中的sql將這個值定義為整型主鍵。我當(dāng)時的情況是,我有一個到唯一主鍵已經(jīng)到了60,而序列仍然是1。于是我的每一個插入命令都沒法成功,因為根據(jù)序列產(chǎn)生的不是唯一id。我當(dāng)時用了一個很笨的方法解決這個問題,那就是運(yùn)行了60次insert語句以將序列調(diào)整為適當(dāng)?shù)闹?,但是后來有一個熟悉postgres的朋友教給我一個好方法。下面就是他所講的方法:

使用telnet這樣的終端程序連接到你的主機(jī)。然后啟動psql程序。首先,確定表中id的最大值。這可以用select fieldname from tablename where fieldname=max(fieldname);。然后使用drop sequence table_colname_seq;刪除有問題的序列,這兒table是表名,而colname是serial字段的列名。然后使用create sequence table_colname_seq start 61;重建序列,當(dāng)然這兒的61應(yīng)根據(jù)你的實際情況進(jìn)行修改。

安裝一個圖形界面的工具

當(dāng)我成功地將數(shù)據(jù)導(dǎo)入到postgres后,我還需要讓我的不懂unix的伙伴能夠操作數(shù)據(jù)庫中的數(shù)據(jù)。當(dāng)初的mysql我是使用的 phpmyadmin,這是一個很好用的工具,它能夠在線的顯示和編輯數(shù)據(jù)庫。幸運(yùn)的是,已經(jīng)有了“postgres版本”的phpmyadmin,那就是phppgadmin。

phppgadmin的安裝非常簡單。首先,從phppgadmin網(wǎng)站下載最新的版本,然后將其放到你的web主機(jī)上的你所能訪問的地方。使用 telnet這樣的工具登陸到主機(jī)。到phppgadmin.tar.gz文件所在的目錄,輸入tar -xzvf phppgadmin.tar.gz對程序進(jìn)行解壓(這里只是舉個例子,你的文件名可能不一樣)。下面一件事就是將解壓生成的新的子目錄移到合適的地方,并閱讀readme文件。

最后,用你的web主機(jī)上的文本編輯器打開config.inc.php。這個文件中包含了對phppgadmin的配置。將這個文件配置好你就可以通過瀏覽器使用phppgadmin了,它會提示你輸入用戶名并登錄,通過這個程序你管理你的數(shù)據(jù)庫將變得非常簡單。

結(jié)語

與mysql相比,postgres更加穩(wěn)定,更加可靠,可以應(yīng)付更大的數(shù)據(jù)。按照上面的提示,你可以使用sql的dump文件將數(shù)據(jù)從mysql轉(zhuǎn)到postgres。如果在這個過程中你遇到什么困難,從postgres網(wǎng)站你可以找到一些非常有用的文檔資源。

在本文的下半部分,我們將討論php訪問postgres與訪問mysql的不同點。

在2001年六月,我將我的站點的后端數(shù)據(jù)庫從mysql改為postgresql。這僅僅花了我一天的時間。從那時起,postgres一直工作得很正常,這證明我作出了正確的選擇。

在這篇文章的上半部分,我們講解了如何將數(shù)據(jù)從mysql轉(zhuǎn)換到postgres。我們還說明了我改用postgres的理由。而在下半部分,我們將指導(dǎo)你完成另一半的轉(zhuǎn)換工作并講解如果將已編制好的用于mysql的php代碼改用于postgres。

準(zhǔn)備

在你做這項工作之前,你需要一些準(zhǔn)備工作。你的編程技巧和網(wǎng)站的復(fù)雜性將對程序的轉(zhuǎn)換影響很大。為了防止在工作中發(fā)生錯誤,在你的web服務(wù)器上為你的站點作一份備份肯定是必要的。我當(dāng)時的解決方法是設(shè)置了一個指定的子域來測試我正在修改的代碼。因為站點會根據(jù)一個配置文件中的一些基本配置自動處理 url,所以這件工作很簡單。你也許不能這樣做,但是不管怎樣,你都需要一個另外的空間來放置你正在改動的程序,這可以是一個子域、你的站點的一個子目錄、另一個web主機(jī)也可以是一個本地的開發(fā)機(jī)器。

注意:如果你在另一臺機(jī)器修改你的程序,你必須確保這個web服務(wù)器的配置和你正在使用的站點一樣。如果你的web主機(jī)只允許從本地連接 postgres,你也許將不得不將你的postgres數(shù)據(jù)拷貝到開發(fā)機(jī)器上。要得到更多有關(guān)拷貝一個postgres數(shù)據(jù)庫的信息,可以參看 http://www.postgresql.org/上的pg_dump和pg_restore。

做好了拷貝并且經(jīng)過測試它可以正常工作之后,你可以著手對程序進(jìn)行解剖了。

php手術(shù):代碼解剖

如何你之前沒有一個中心的配置文件,那么首先建立它。這將減輕我們的很多工作量,而且也使得我們的改動可以即時對整個站點發(fā)生作用。這個配置文件也該是不允許其它人通過網(wǎng)站訪問的,否則這將是一個安全隱患。php的默認(rèn)包含目錄是/usr/local/lib/php/。你需要在你的web主機(jī)上建立這樣一個目錄并不允許通過網(wǎng)站訪問。你還得確保這對于使用同一web主機(jī)的其他人也無法讀取這個目錄。如果你的站點和我的一樣,包含了一個標(biāo)準(zhǔn)的頭文件,你可以將你的postgres設(shè)置文件放在那兒,這個配置文件將會是這樣的:

以下為引用的內(nèi)容:
</p>
<?php
// /usr/local/lib/php/mysite/configfile.php
$hostname = "localhost";
$username = "username";
$database = "mydb";
$password = "mypasswd";
?>
<?php
//標(biāo)準(zhǔn)的html頭
include("mysite/configfile.php");
?>
<html>
<head>
<title>bill's kazoos</title>
...
</head>
<body>
...
 
有了這樣一個前面這樣的中心配置文件,改變數(shù)據(jù)庫系統(tǒng)將變得非常簡單。現(xiàn)在可以著手改程序了。

連接和查詢php有關(guān)mysql的函數(shù)和postgres很相似,所以轉(zhuǎn)換代碼的工作并不是太復(fù)雜。事實上,你可以自己寫一些函數(shù)來完成這種轉(zhuǎn)換。在做這項工作之前,讓我們來看看兩者的不同:

要連接到mysql數(shù)據(jù)庫需要用到兩個命令:

以下為引用的內(nèi)容:

$connection_id=mysql_connect($hostname, $username, $password);
mysql_select_db($database, $connection_id);

如果你使用一個持久的連接:

以下為引用的內(nèi)容:
$connection_id=mysql_pconnect($hostname, $username, $password);
mysql_select_db($database, $connection_id);
 
然而,php連接postgres的函數(shù)只需要一個字符串參數(shù),與mysql函數(shù)不同,這是一個復(fù)合的字符串參數(shù)。postgres函數(shù)也需要你指定使用的數(shù)據(jù)庫。下面是一個示例:

以下為引用的內(nèi)容:

$connection_id=pg_connect("host=$hostname dbname=$database user=$username
password=$password");

一個持久的連接執(zhí)行同樣的工作,只是需要調(diào)用pg_pconnect()函數(shù)。

php的mysql和postgres的查詢函數(shù)同樣有點不同。mysql的查詢函數(shù)是$result_data = mysql_query("query goes here",$connection_id);,而postgres的查詢函數(shù)是這樣的:$result_data = pg_exec($connection_id, "query goes here")。

正如你所看到的,php對mysql和postgres和連接和查詢的支持區(qū)別并不大,但是函數(shù)參數(shù)的不同還是需要我們慢慢處理。要提高速度,你可以寫一些函數(shù)使得postgres可以使用和mysql一樣的函數(shù)來連接。如果你有了包含這樣一種函數(shù)的中心庫,你可以將這些函數(shù)也放在那里。你也可以將它們放置在我們前面所提到的配置文件中,因為它會自動地被每個頁面包含。

//連接到數(shù)據(jù)庫

以下為引用的內(nèi)容:

function postg_connect($hostname, $username, $password, $database)

{

return pg_connect("host=$hostname dbname=$database

user=$username password=$password");

}

//如果你僅僅使用一個數(shù)據(jù)庫,你最好將這些變量放到你的配置文件中

function postg_autoconnect()

{

global $hostname, $username $password $database;

return pg_connect("host=$hostname dbname=$database

user=$username password=$password");

}

//查詢函數(shù)

function postg_query($query, $connection_id)

{

return pg_exec($connection_id, $query);

}

不管你是否使用這種函數(shù),代碼轉(zhuǎn)換的工作總是相當(dāng)簡單的。postgres幾乎可以支持所有的以前在mysql下使用的sql查詢,但是你可能還是要整理一下你的查詢。因為在不同的地方數(shù)據(jù)模型和代碼會有一些不同,我在這里不想詳細(xì)解釋這個問題。然而,對sql的轉(zhuǎn)換并不困難。首先轉(zhuǎn)換代碼,然后看看有哪些查詢無法在postgres中正常執(zhí)行。對mysql語言指南和postgresql用戶向?qū)е械南嚓P(guān)問題進(jìn)行比較,你也許不能在postgres中找到所有與mysql同等的功能,但是postgres支持所有的通用的功能。

現(xiàn)在你已經(jīng)把連接和查詢的代碼改好了,下面的問題可能要稍微復(fù)雜一點。php中mysql和postgres對結(jié)果集處理的不同可能需要你對代碼作更多的變動。

讓我們來看看對結(jié)果的處理

php的postgres對結(jié)果的處理并不完全和mysql一一對應(yīng);它們有一些微小的不同。這些微小的差別可能只需要對代碼作微小的改動,但是也可能是一個挺復(fù)雜的問題。

首先,讓我們看看mysql和postgres有哪些相似的地方。下面這個列表介紹了普通的mysql結(jié)果處理函數(shù)和它們相對應(yīng)的postgres函數(shù):

mysql

mysql_num_rows($result) 返回結(jié)果集的行數(shù),這僅對select語句有效

mysql_affected_rows($result) 返回在一個insert、update或delete查詢中受到影響的行數(shù)

mysql_fetch_object($result) 取得一行的數(shù)據(jù)并將其作為一個對象返回。字段名對應(yīng)于類的屬性名。(即$field1 = $var->field1;)這個函數(shù)保存了一個內(nèi)部變量以保證每次調(diào)用時可以返回下一行。

mysql_fetch_row($result) 這個函數(shù)以一個數(shù)組的形式返回結(jié)果集的一行。這個值可以通過一個從0開始的數(shù)組值獲得。(即$field1 = $var[0];)。同樣,這個函數(shù)保存了一個內(nèi)部的計數(shù)器以保證每次調(diào)用時可以返回下一行。

mysql_fetch_array($result) 這個函數(shù)和另外兩個fetch函數(shù)基本相同,只是它以一個聯(lián)合數(shù)組的形式返回一個行($field1 = $var["field1"];)。

postgres

pg_numrows($result) 與對應(yīng)的mysql_num_rows($result)完全一樣

pg_cmdtuples($result) 與對應(yīng)的mysql_affected_rows($result)完全一樣

pg_fetch_object($result, $row) 獲得結(jié)果集中的指定行。必須使用$row參數(shù),而且沒有一個內(nèi)部的計數(shù)器。除此之外,它與mysql_fetch_object($result)完全相同。

pg_fetch_row($result, $row) 以一個數(shù)組的形式返回結(jié)果集中的指定行。同樣必須使用$row參數(shù),而且沒有一個內(nèi)部的計數(shù)器。

pg_fetch_array($result, $row) 與對應(yīng)的mysql_fetch_array($result)基本一樣,只是需要指定行,并且缺少一個內(nèi)部的計數(shù)器。

有關(guān)這些函數(shù)的更詳細(xì)的信息,請參看php.net上的php文檔。

php對mysql和postgres支持的最本質(zhì)的不同在于對結(jié)果集的閱讀。mysql自動決定獲取哪一行,而postgres必須指定要閱讀哪一行。下面是一些例子,你也可能會遇到這些問題,對于它們有兩個解決方案。

//第一個普通的例子:

$rslt=mysql_query("select * from blah", $connection_id);

while($value=mysql_fetch_array($rslt))

{

//完成數(shù)據(jù)處理工作

}

//對于postgres,這樣的代碼無法執(zhí)行,因為他們需要指定行號

//代碼將作如下改動(如果你沒有使用前面討論的函數(shù)):

$rslt=pg_exec($connection_id, "select * from blah");

$limit=pg_numrows($rslt);

for($rownum=0;$rownum<$limit;$rownum++)

{

$value=pg_fetch_array($rslt, $rownum);

//完成處理工作

}

在上面的例子中,你可以注意到postgres的代碼要稍微長一點,這是因為你必須指定行號。然而,如果你使用了你編寫的自己的計數(shù)函數(shù),問題就變得很簡單了。這兒是一個添加了這樣一個函數(shù)的有用的文件。請注意在postg_query()中使用了三個全局變量。

以下為引用的內(nèi)容:

<?php
// /usr/local/lib/php/mysite/configfile.php
$hostname = "localhost";
$username = "username";
$database = "mydb";
$password = "mypasswd";
//內(nèi)部計數(shù)變量
$fetch_array_counter=0;
$fetch_object_counter=0;
$fetch_row_counter=0;
//處理連接到postgresql數(shù)據(jù)庫的函數(shù)
function postg_connect($hostname, $username, $password, $database)
{
return pg_connect(host=$hostname, dbname=$database user=$username,
password=$password");
}
//不需要任何參數(shù)的連接
function postg_autoconnect()
{
global $hostname, $username, $password, $database;
return pg_connect(host=$hostname, dbname=$database user=$username,
password=$password");
}
//查詢函數(shù)
function postg_query($query, $connection_id)
{
//將全局變量設(shè)置為0
global $fetch_array_counter, $fetch_row_counter, $fetch_object_counter;
$fetch_array_counter=$fetch_row_counter=$fetch_object_counter=0;
return pg_exec($connection_id, $query);
}
//pg_fetch_array()置換
function postg_fetch_array($rslt)
{
global $fetch_array_counter;
$fetch_array_counter++;
//計數(shù)器加一
return pg_fetch_array($rslt, $fetch_array_counter);
}
//pg_fetch_row()置換
function postg_fetch_row($rslt)
{
global $fetch_row_counter;
$fetch_row_counter++;
//計數(shù)器加一
return pg_fetch_row($rslt, $fetch_row_counter);
}
//pg_fetch_object()置換
function postg_fetch_object($rslt)
{
global $fetch_object_counter;
$fetch_object_counter++;
//計數(shù)器加一
return pg_fetch_object($rslt, $fetch_object_counter);
}
?>

當(dāng)然,如果你在同一個循環(huán)中同時對兩個結(jié)果集進(jìn)行操作,上面的函數(shù)將無法正常地工作,因為它們只使用了一個內(nèi)部的計數(shù)器。如果因為某種原因,你需要同時閱讀幾個結(jié)果集,你將不得不使用傳統(tǒng)的postgres方法。

另一個你可能遇到的問題是在postgres中沒有與mysql中mysql_insert_id()相應(yīng)的函數(shù),這個函數(shù)反映最后的insert查詢的索引值。php文檔往往會讓讀者誤以為pg_getlastoid()會完成這項工作,但是實際情況并不是這樣。缺少這一樣一個函數(shù)并不一個無法逾越的障礙,你可以利用postgres的sequence系統(tǒng)來實現(xiàn)這樣的功能。

幸運(yùn)的是,要獲得最后的id是相當(dāng)容易的。你可以通過sql獲得sequence信息,因此你可以用這個語句來實現(xiàn)mysql_insert_id()的功能:

以下為引用的內(nèi)容:

function postg_insert_id($tablename, $fieldname)
{
global connection_id;
$result=pg_exec($connection_id, "select last_value from ${tablename}_
${fieldname}_seq");
$seq_array=pg_fetch_row($result, 0);
return $seq_array[0];
}

因為postgres使用了一個特別的命名系統(tǒng)來命名序列,我上面建立的這個函數(shù)需要指定表名和字段名。調(diào)用這個函數(shù),會返回你的表中的任意serial字段的最后一個序列值,即使在表中有不止一個這樣的字段。

經(jīng)過上面的這些處理后,你已經(jīng)可以在你的mysql站點上成功地運(yùn)行postgresql了。然而,這僅僅是第一步;如果你想了解更多,繼續(xù)看下去,你會看到一些有用的postgresql的資源。

更進(jìn)一步的資源

從postgresql非faq文檔站點你可以看到最初的和最重要的postgresql資源。這個有價值的資源可以向你提供大量的書籍、參考、技術(shù)參考甚至于具體的工作。它同樣會涉及將后端數(shù)據(jù)庫從mysql 改為postgres,此外對于使用postgresql的其它問題它也可以給你幫助。

另一個有價值的postgresql提供的資源是postgresql交互文檔。其中涉及到使用postgresql的很多問題。

xach beane,因為其在the gimp(一種圖形處理軟件)上的工作而著名,他也編寫了關(guān)于將mysql dump轉(zhuǎn)換為postgres dump的書寫一個腳本。他的程序可以更為全面地處理這些問題。不過,對這些問題的處理并不是十分完美的,因此你得小心地使用它。

dobrica pavlinusic也編寫了一個程序以處理從mysql到postgres的轉(zhuǎn)換。同樣得提醒你這個程序的處理仍然不是十分完美的,因此還是少不了象我們上面所討論的手工的修改。

從這兒你可以找到一個非常完全的postgresql&php指南。它會從安裝開始介紹postgresql的使用。這個指南非常值得初學(xué)者閱讀。

bruce momjohan編寫了一本關(guān)于postgresql的名為postgresql: introduction and concepts的書,已由addison wesley出版。你甚至還可以在線閱讀!

最后,opendocs也出版了實用postgresql。這本書在2001年十月份出版,你可以從the opendocs linuxports.com站點閱讀。

將你的站點的后端數(shù)據(jù)庫從mysql改為postgresql是一個明智的選擇。轉(zhuǎn)換工作肯定會耗費(fèi)時間和精力,但是經(jīng)過這些努力后,你的站點可以擁有一個更完美的數(shù)據(jù)庫系統(tǒng)。就象我一樣,你也會覺得這項工作是有意義的!

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 罗定市| 襄汾县| 龙州县| 花莲市| 浦城县| 通城县| 安远县| 青神县| 垫江县| 靖安县| 镇雄县| 洛阳市| 防城港市| 阳江市| 浮梁县| 准格尔旗| 和田市| 准格尔旗| 宜都市| 玉田县| 临江市| 贵阳市| 双辽市| 衡南县| 平武县| 囊谦县| 南华县| 松原市| 清流县| 阿拉善右旗| 临潭县| 马龙县| 商丘市| 海南省| 大城县| 龙里县| 威宁| 杨浦区| 招远市| 黎平县| 平乐县|