MySQL和PostgreSQL - 兩大開源對象關係型數據庫管理系統,每個都有大量的粉絲。這麼多年來,在PostgreSQL社區中MySQL一直被消遣:默認鬆散的SQL風格、對複雜鏈接操做支持的缺失、沒有位圖索引等等。相反,MySQL也有其強悍的地方:經過複製實現擴展的能力超強。前端
您可能會問 - 爲何要在同一環境中使用這兩個數據庫?在Galera集羣(高一致性MySQL架構)中使用PostgreSQL有價值嗎?在這篇文章中,咱們嘗試從MySQL DBA的角度來理解這些問題。接下來咱們也會討論部署PostgreSQL的不一樣方法。算法
PostgreSQL的一大優點是可以有效的處理複雜查詢。PostgreSQL可以使用不一樣的鏈接算法(像hash join),這在建立最優執行計劃時是很是靈活的。相比而言,MySQL僅支持嵌套循環鏈接,這種鏈接方式並非放之四海而皆準。sql
PostgreSQL可能比MySQL更快的另一個理由是對於子查詢的處理。MySQL在執行子查詢時,查詢優化器並不夠完美。在過去,大部分的執行被看成依賴子查詢,若是要對這類查詢加速,就要求進行手工查詢重寫。在MySQL 5.6中,已經作了一些提高,能夠進行子查詢物化。在MySQL 5.7中,針對該類情景又作了部分提高,可是相比PostgreSQL而言仍然是相去甚遠。shell
在MySQL中建立存儲過程是很是艱難的。比起其餘RDBMS系統,MySQL中的編程語言既功能有限又不夠靈活。在PostgreSQL中建立存儲過程比在MySQL中容易的多 - 咱們能夠建立一系列的存儲過程,並將複雜的操做邏輯放在數據庫端。相比而言,在MySQL中,受限於存儲過程語言,一般不得不把一些複雜的邏輯分離到前端應用處理。PostgreSQL的另外優點是,您不只可使用PL/pgSQL語言,也可使用C、PL/Tcl、PL/Perl和PL/Python,這些都包含在覈心發佈包中,還有一些另外的存儲過程語言能夠自行添加。數據庫
一件使人興奮的事,若是您使用JSON和GIS數據類型,那麼好吧,PostgreSQL支持的很是好。相比之下,MySQL在5.7版本中經過MyISAM表提供GIS支持,最近才引入InnoDB引擎。JSON數據類型的支持也是在MySQL 5.7才實現。在本篇文章寫做時,Galera還不支持5.7,因此您不得不選擇單機版的MySQL或者PostgreSQL來實現該類需求。另一方面,GIS和JSON都是InnoDB引擎新增的功能,還不夠成熟,須要一段時間的錘鍊。相對來講,PostgreSQL能夠提供一種跟穩定有效的選擇。編程
PostgreSQL目前在各個主流的Linux分發版中都有,您能夠很容易的經過yum或者apt-get命令進行安裝。架構
一旦安裝完成,當前僅能經過切換到postgres用戶後用localhost進行訪問。命令行操做以下:dom
root@ip-172-30-4-22 ~ # su - postgres postgres@ip-172-30-4-22:~$ psql psql (9.3.13) Type "help" for help. postgres=#
接下來,您即可以立刻對數據庫進行管理,最重要的一點是:正確的配置訪問權限和建立數據庫用戶。socket
PostgreSQL的訪問方法在文件pg_hba.conf中定義。在不一樣的操做系統中,該文件可能處於不一樣的位置,例如:Ubuntu 14.04在/etc/postgresql/9.3/main/pg_hba.conf,CentOS7在/var/lib/pgsql/data/pg_hba.conf下。下面看一個pg_hba.conf的簡單例子:tcp
# Database administrative login by Unix domain socket local all postgres peer # TYPE DATABASE USER ADDRESS METHOD # "local" is for Unix domain socket connections only local all all peer # IPv4 local connections: host all all 127.0.0.1/32 md5 # IPv6 local connections: host all all ::1/128 md5
正如您上面所見,定義了四條規則。第一條規則定義了用戶postgres可以以本地操做系統用戶訪問全部數據庫(peer方法)。類似的規則,你也能夠在PostgreSQL數據庫中建立一個myuser用戶,並在操做系統也建立一個myuser用戶,而後經過該用戶登錄,固然要這樣執行須要相應的操做系統權限。另外兩條本地TCP規則,都是用了md5方法,着意味着登錄時須要輸入密碼。
接下來,咱們來爲PostgreSQL數據庫建立一個除postgres之外的用戶。咱們能夠很輕鬆的實現:
postgres@ip-172-30-4-22:~$ createuser -P --interactive Enter name of role to add: s9suser Enter password for new role: Enter it again: Shall the new role be a superuser? (y/n) n Shall the new role be allowed to create databases? (y/n) n Shall the new role be allowed to create more new roles? (y/n) n postgres@ip-172-30-4-22:~$ createuser -P --interactive Enter name of role to add: s9sadmin Enter password for new role: Enter it again: Shall the new role be a superuser? (y/n) y
上面的例子中,咱們建立了兩個用戶:s9suser - 普通用戶,s9sadmin - 超級用戶。兩個用戶建立時都帶有密碼。使用上面的工具建立用戶有多種選項,具體能夠參見手冊或者--help輸出文檔。
用戶建立完成後,接下來就是建立數據庫了。這裏也能夠經過shell來建立:(全部的數據庫操做均可以經過SQL實現,固然這裏爲了展現一些shell級別的簡便命令,並無使用SQL)
postgres@ip-172-30-4-22:~$ createdb s9sdb
最後,咱們開始訪問數據庫:
postgres@ip-172-30-4-22:~$ psql -U s9suser -W -h 127.0.0.1 s9sdb Password for user s9suser: psql (9.3.13) SSL connection (cipher: DHE-RSA-AES256-GCM-SHA384, bits: 256) Type "help" for help. s9sdb=>
此刻,咱們能夠從本地shell界面登錄到數據庫中。可是此時遠程主機仍然不能訪問PostgreSQL,要開放該權限,須要執行如下操做。
首先,須要讓PostgreSQL監聽到對應的接口地址。咱們能夠修改postgresql.conf文件中的內容:(postgresql.conf文件和pg_hba.conf在同一路徑下)
#listen_addresses = 'localhost' # what IP address(es) to listen on; # comma-separated list of addresses; # defaults to 'localhost'; use '*' for all # (change requires restart)
從上面的結果能夠看到,PostgreSQL默認監聽localhost,咱們須要對這裏做出修改,讓他可以接受外部鏈接。修改完監聽IP後,須要重啓PostgreSQL服務。修改完後,能夠經過如下語句確認監聽:
root@ip-172-30-4-22 ~ # netstat -lnp | grep 5432 tcp 0 0 172.30.4.22:5432 0.0.0.0:* LISTEN 20026/postgres unix 2 [ ACC ] STREAM LISTENING 2000624 20026/postgres /var/run/postgresql/.s.PGSQL.5432
接下來再嘗試從不一樣主機鏈接到咱們的PostgreSQL服務:
[root@ip-172-30-4-212 ~]# psql -h 172.30.4.22 -U s9sadmin s9sdb psql: FATAL: no pg_hba.conf entry for host "172.30.4.212", user "s9sadmin", database "s9sdb", SSL on FATAL: no pg_hba.conf entry for host "172.30.4.212", user "s9sadmin", database "s9sdb", SSL off
咱們獲得了一個錯誤:缺乏pg_hba.conf配置。因此咱們在pg_hba.conf文件中增長如下語句:
host all all 172.30.4.212/32 md5
上面的錯誤也顯而易見,若是有不少不一樣的客戶端須要登錄,那麼須要在pg_hba.conf文件中都作相關的配置,活着直接將IP定義爲未0.0.0.0/0用來接收全部的鏈接。
pg_hba.conf文件中作的改變須要重載PostgreSQL服務才能生效。這裏請注意,重載PostgreSQL服務(service postgresql reload)不會中斷當前連接,因此重載是使配置生效的一種非中斷方式。最後讓咱們來一塊兒看看是否能夠從其餘主機連接到PostgreSQL服務:
[root@ip-172-30-4-212 ~]# psql -h 172.30.4.22 -U s9sadmin s9sdb Password for user s9sadmin: psql (9.2.15, server 9.3.13) WARNING: psql version 9.2, server version 9.3. Some psql features might not work. SSL connection (cipher: DHE-RSA-AES256-GCM-SHA384, bits: 256) Type "help" for help. s9sdb=#
當現實上面的s9sdb=#時,證實咱們成功了!
很顯然,經過倉庫部署不是安裝PostgreSQL的惟一途徑。咱們能夠經過從EDB、BigSQL、第二象限等企業下載封裝好的PG可執行安裝包進行安裝,因爲安裝過程都一步步封裝好,基本不會出錯,這種安裝的好處是在安裝過程當中能夠進行部分配置的定義。
另外還能夠經過源碼進行編譯安裝,該安裝的好處是能夠修改像數據塊大小等更底層的配置。
正如咱們所見,PostgreSQL安裝簡易。不管咱們採用何種方式安裝它,都須要進行一些初始化配置。下一節課,咱們對該內容進行討論。