360°全方位比較PostgreSQL和MySQL

360°全方位比較PostgreSQL和MySQL
1、原文
https://www.enterprisedb.com/blog/postgresql-vs-mysql-360-degree-comparison
2、摘要
本文對MySQL和PostgreSQL進行詳細的比較,方便選擇。
一、爲何使用PostgreSQL
二、爲何使用MySQL
三、易用性
四、語法
五、數據類型
六、複製與集羣
七、視圖
八、觸發器
九、存儲過程
十、查詢
十一、分區
十二、表的可伸縮性
1三、NoSQL能力
1四、安全
1五、分析函數
1六、GUI工具
1七、性能
1八、Adoption
1九、最佳環境
3、PG vs MySQL:選擇哪一個?
PostgreSQL和MySQL都是最流行的開源數據庫。MySQL被認爲是世界上最流行的數據庫,而PostgreSQL被認爲是世界上最早進的數據庫。MySQL並不徹底符合SQL標準,而且不少PG上的特性並不支持。這就是爲何PG受到大量開發者喜歡的緣由,而且如今PG愈來愈流行。
前幾年,Oracle收購了MySQL,致使MySQL的出現兩個版本:商業版和社區版。對於後者,因爲Oracle控制了MySQL的開發,受到了廣大使用者的批評。
PostgreSQL是世界上最受歡迎的數據庫:他支持大量企業級特性和功能。PG由postgresql全球社區開發,該社區由一批優秀的開發人員組成,幾十年來一直努力確保PG具備豐富的功能,並與其餘開源、商業數據庫競爭。社區也從世界各地的公司獲得巨大貢獻。
一、爲何使用PG
PG做爲開源、功能豐富的數據庫,可與Oracle展開競爭。開發者也會將PG當作NoSQL數據庫來使用。在雲中和本地部署使用PG很是簡單,也能夠在docker容器等各個平臺使用。
PG徹底支持ACID,對開發人員和DBA很是友好,是跨任何域的高併發事務、複雜應用程序最佳選擇,能夠知足基於WEB和移動的各類應用程序服務。PG也是一個很是好的數據倉庫,用於大數據上運行復雜的報告查詢。
二、爲何使用MySQL
MySQL具備社區版和商業版。商業版由Oracle管理。做爲關係型數據庫,部署和使用很是簡單。可是對於SQL標準要求很高的應用不太合適。MySQL的集成能力也有限,很難成爲異構數據庫環境的一部分。
MySQL適用於簡單web應用程序或者須要簡單schema、SQL執行數據庫操做的應用。對於處理大量數據的複雜應用來講,MySQL並非一個很好的選擇。
三、易用性
PG可以處理結構化和非結構化的數據、具有關係型數據庫全部的特性。MySQL在SQL和特性方面的侷限性可能會爲其構建高效的RDBMS應用程序帶來挑戰。
四、語法
大部分數據庫的SQL語法都比較類似。然而,MySQL並不支持全部的SQL。對於支持的SQL和其餘數據庫都比較類似。例如查詢,PG和MySQL都是:
SELECT * FROM employees;
五、數據類型
MySQL和PG都支持許多數據類型,從傳統的數據類型(integer、date、timestamp)到複雜類型(json、xml、text)。然而,在複雜實時數據查詢下又有所不一樣。
PG不止支持傳統數據類型:numeric、strings、date、decimal等,還支持非結構的數據類型:json、xml、hstore等以及網絡數據類型、bit字符串,還有ARRAYS,地理數據類型。
MySQL不支持地理數據類型。
從9.2開始,PG支持json數據類型。相對於MySQL來講,PG對json的支持比較先進。他有一些json指定的操做符和函數,是的搜索json文本很是高效。9.4開始,能夠以二進制的格式存儲json數據,支持在該列上進行全文索引(GIN索引),從而在json文檔中進行快速搜索。
從5.7開始,MySQL支持json數據類型,比PG晚。也能夠在json列上創建索引。然而對json相關的函數的支持比較有限。不支持在json列上全文索引。因爲MySQL對SQL支持的限制,在存儲和處理json數據方面,MySQL不是一個很好的選擇。
六、複製和集羣
MySQL和PG都具備複製和集羣的能力,可以確保數據操做水平分佈。
MySQL支持主-備、一主多備的複製機制,經過SQLs即binlog保證將全部的數據傳輸到備機上。這也是複製只能是異步、半同步的緣由。
優勢:備機能夠寫。這就意味着一旦master崩潰了,slave能夠立刻接管,確保應用正常工做。DBAs須要確保slave變成主了,而且新的binlog複製到原主。當有不少長SQL時,複製會變得慢。
MySQL也支持NDB集羣,即多主的複製機制。這種類型的複製對要求水平擴展的事務有利。
PG的複製和MySQL不一樣,他是基於WAL文件,使複製更加可靠、更快、更有利於管理。他也支持主備和一主多從的模式,包括級聯複製形式。PG的複製成爲流複製或物理複製,能夠異步也能夠同步。
默認狀況下,複製時異步,Slave可以知足讀請求。若是要求在備機上讀到的數據和主機上同樣,就須要設置同步複製。可是缺點是一旦備機上事務沒有提交,主機就會hang住。
可使用第三方工具Slony、Bucardo、Londiste、RubyRep等對錶級別的複製進行歸檔。這些工具都是基於觸發器的複製。PG也支持邏輯複製。最初經過pglogical擴展支持邏輯複製,從10開始內核支持邏輯複製。
七、視圖
MySQL支持視圖,視圖下面經過SQL使用的表的個數限制爲61。視圖不存儲物理數據,也不支持物化視圖。簡單SQL語句建立的視圖能夠更新,複雜SQL建立的視圖不能夠更新。
PG和MySQL相似。簡單SQL建立的視圖可更新,複雜的不行。可是能夠經過RULES更新複雜的視圖。PG支持物化視圖和REFRESHED。
八、觸發器
MySQL支持INSERT、UPDATE、DELETE上AFTER和BEFORE事件的觸發器。觸發器不一樣執行動態SQL語句和存儲過程。
PG的觸發器比較先進。支持AFTER、BEFORE、INSTEAD OF事件的觸發器。若是在觸發器喚醒時執行一個複雜的SQL,能夠經過函數來完成。PG中的觸發器能夠動態執行函數:
CREATE TRIGGER audit
AFTER INSERT OR UPDATE OR DELETE ON employee
FOR EACH ROW EXECUTE FUNCTION employee_audit_func();
九、存儲過程
MySQL和PG都支持存儲過程,但MySQL僅支持標準的SQL語法,而PG支持很是先進的存儲過程。PG以帶RETURN VOID子句的函數形式完成存儲過程。PG支持的語言有不少:Ruby、Perl、Python、TCL、PL/pgSQL、SQL和JavaScript。而MySQL則沒有這麼多。
十、查詢
使用MySQL時須要考慮的限制:
某些UPDATE SQL的返回值不符合SQL標準
mysql> select * from test;
+------+------+
| c | c1 |
+------+------+
| 10 | 100 |
+------+------+
1 row in set (0.01 sec)mysql

mysql> update test set c=c+1, c1=c;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0ios

mysql> select * from test;
+------+------+
| c | c1 |
+------+------+
| 11 | 11 |
+------+------+
1 row in set (0.00 sec)web

預期的標準形式:
mysql> select * from test;
+------+------+
| c | c1 |
+------+------+
| 11 | 10 |
+------+------+sql

不能執行的UPDATE或DELETE語句:
mysql> delete from test where c in (select t1.c from test t1, test t2 where t1.c=t2.c);
ERROR 1093 (HY000): docker

子查詢中不能使用LIMIT子句
mysql> select * from test where c in (select c from test2 where c<3 limit 1);
ERROR 1235 (42000): 數據庫

MySQL也不支持「LIMIT & IN/ALL/ANY/SOME子句」。一樣也不支持FULL OUTER JOINS、INTERSECT、EXCEPT等。也不支持Partial索引、bitmap索引、表達式索引等。PG支持全部SQL標準的特性。對於須要寫複雜SQL的開發者來講,PG是一個很好的選擇。
十一、分區
MySQL和PG都支持表分區,然而雙方都有一些限制。
MySQL支持的分區類型有RANGE、LIST、HASH、KEY和COLUMNS(RANGE和LIST),也支持SUBPARTITIONING。然而DBA在使用時可能不太易用。
MySQL8.0,只有innodb和NDB存儲引擎支持表分區,其餘存儲引擎不支持。
若是分區key的列不是主鍵或者惟一鍵的一部分,那麼就不可能對錶進行分區。
從5.7.24開始,逐步取消支持將表分區放在表空間上,這意味着DBA沒法平衡表分區和磁盤IO。
mysql> create table emp (id int not null, fname varchar (30), lname varchar(30), store_id int not null ) partition by range (store_id) ( partition p0 values less than (6) tablespace tbs, partition p1 values less than(20) tablespace tbs1, partition p2 values less than (40) tablespace tbs2);
ERROR 1478 (HY000): InnoDB : A partitioned table is not allowed in a shared tablespace.
mysql>json

PG支持表分區繼承和聲明表分區。聲明表分區在10引入,和MySQL相似,而表分區繼承經過使用觸發器和規則來完成。分區類型支持RANGE、LIST、HASH。限制:
和MySQL相似,聲明表分區只能在主鍵和惟一鍵上
繼承表分區,子表不能繼承主鍵和惟一鍵。
INSERT和UPDATE不能自動恆信到字表。
十二、表的擴展性
表段變得愈來愈大時會形成性能問題,在這個表上的查詢會佔用更多資源,花費更多時間。MySQL和PG需考慮不一樣因素。
MySQL支持B+tree索引和分區,這些能夠對大表提高性能。然而,因爲不支持bitmap、partial和函數索引,DBA不能更好的進行調優。並且分區表不能放到不一樣表空間上,這也形成IO不能更好平衡。
PG的表達式索引、partial索引、bitmap索引和全文索引均可以提高大表的性能。PG的表分區和索引能夠放到不一樣的磁盤上,可以更好提高表的擴展性。爲實現水平表級別的擴展,可使用citusdb、Greenplum、Netezza等。開源的PG不支持水平表分區,PostgresXC支持,可是他的性能很差。
1三、存儲
數據存儲是數據庫的一個關鍵能力。PG和MySQL都提供多種選項存儲數據。
PG有一個通用的存儲特性:表空間可以容納表、索引、物化視圖等物理對象。經過表空間,能夠將對象進行分組並存儲到不一樣物理位置,能夠提高IO能力。PG12以前版本,不支持可拔插存儲,12只支持可拔插架構。
MySQL和PG相似,將來具備表空間特性。他支持可拔插存儲引擎。這是MySQL的一個優勢。
1四、支持的數據模型
關係型數據庫的NoSQL能力可以幫助處理非結構化的數據,例如json、xml、text等。
MySQL的NoSQL能力比較有限。5.7引入了json數據類型,須要很長時間才能變得更加成熟。
PG具備豐富的json能力,將來3年內是須要NoSQL能力的開發者的一個很好的選擇。Json和jsonb數據類型,使得PG對json操做更快更有效。一樣能夠在json數據列上創建B-tree索引和GIN索引。XML和HSTORE數據類型能夠處理XML格式以及其餘複雜text格式的數據。對空間數據類型的支持,使得PG是一個完整的多模型數據庫。
1五、安全性
數據庫安全在未認證便可訪問的數據庫中扮演者很重要的角色。安全包括對象級別和鏈接級別。
MySQL經過ROLES和PRIVILEGES將訪問權限付給數據庫、對象和鏈接。每一個用戶都須要賦予鏈接權限。
GRANT ALL PRIVILEGES ON testdb. TO 'testuser@'192.168.1.1’ IDENTIFIED BY 'newpassword';
GRANT ALL PRIVILEGES ON testdb.
TO 'testuser@'192.168.1.*’ IDENTIFIED BY 'newpassword';
每次賦權時都須要指定密碼,不然用戶將不能鏈接。
MySQL一樣支持SSL鏈接。能夠和外部認證系統LDAP和PAM集成。是其企業版一部分。
PG使用GRANT命令經過ROLES和PRIVILEGES提供訪問權限。鏈接認證比較簡單,經過pg_hba.conf認證文件設置:
host database user address auth-method [md5 or trust or reject]
PG開源版本一樣支持SSL鏈接,能夠和外部認證系統集成。
解析函數對一組行數據進行聚合。有兩種類型的解析函數:窗口函數和聚合函數。聚合函數執行聚合並返回記錄集合的一個聚合值(sum,avg,min,max等);而解析函數返回每一個記錄的聚合值。MySQL和PG都支持多種聚合函數。MySQL8.0才支持窗口函數,PG很早就已經支持了。
PG支持的窗口函數:
函數名             描述
CUME_DIST Return the relative rank of the current row.
DENSE_RANK Rank the current row within its partition without gaps.
FIRST_VALUE Return a value evaluated against the first row within its partition.
LAG Return a value evaluated at the row that is at a specified physical offset row before the current row within the partition.
LAST_VALUE Return a value evaluated against the last row within its partition.
LEAD Return a value evaluated at the row that is offset rows after the current row within the partition.
NTILE Divide rows in a partition as equally as possible and assign each row an integer starting from 1 to the argument value.
NTH_VALUE Return a value evaluated against the nth row in an ordered partition.
PERCENT_RANK Return the relative rank of the current row (rank-1) / (total rows-1)
RANK Rank the current row within its partition with gaps.
ROW_NUMBER Number the current row within its partition starting from 1.安全

MySQL支持PG全部的窗口函數,除了如下限制:
窗口函數不能出如今UPDATE和DELETE中
窗口函數不支持DISTINCT
窗口函數不支持NESTED
1六、圖形界面工具
MySQL有Oracle的SQL Developer、MySQL workbench、dbeaver、omnidb等,監控工具備nagios、cacti、zabbix等。PG也可使用Oracle的SQL Developer、pgAdmin、omnidb、dbeaver。監控工具備Nagios, Zabbix, and Cacti。
1七、性能
MySQL數據庫性能調優選項比較有限,不少索引類型都不支持。寫一個高效的SQL語句具備挑戰性。對於大規模數據,MySQL也不是個很好的選擇。表空間僅支持innodb,而且沒法容納表分區。
PG很是適合任何類型的負載:OLTP,OLAP,數據倉庫等。因爲支持的索引類型比較多,能夠更好的提高性能。PG也有選項採集數據庫內存使用,分區表能夠放到不一樣表空間平衡IO。
1八、Adoption
PG是世界上最早進的開源數據庫。 EnterpriseDB 和2ndQuadrant公司可以保證PG在世界範圍上被更多用戶使用。
MySQL表示RDBMS和ORDBMS應用的最佳選擇。由於自從Oracle收購MySQL依賴,MySQL的採用率明顯降低,開源領域的開發進度也受到衝擊,招致MySQL用戶的批評。
1九、最佳環境
MySQL流行於LAMP棧,PG流行於LAPP棧。LAPP棧表明Linux、Apache、Postgres和Php/Python,而且愈來愈流行。LAMP棧表明 Linux Apache MySQL/MongoDB and Php/Python。網絡

相關文章
相關標籤/搜索