Appendix A. PostgreSQL錯誤代碼
創(chuàng)新互聯(lián)建站客戶idc服務(wù)中心,提供雅安服務(wù)器托管、成都服務(wù)器、成都主機(jī)托管、成都雙線服務(wù)器等業(yè)務(wù)的一站式服務(wù)。通過各地的服務(wù)中心,我們向成都用戶提供優(yōu)質(zhì)廉價的產(chǎn)品以及開放、透明、穩(wěn)定、高性價比的服務(wù),資深網(wǎng)絡(luò)工程師在機(jī)房提供7*24小時標(biāo)準(zhǔn)級技術(shù)保障。
PostgreSQL服務(wù)器發(fā)出的所有消息都賦予 了五個字符的錯誤代碼,這些代碼遵循 SQL 的"SQLSTATE" 代碼的習(xí)慣。需要知道發(fā)生了什么錯誤條件的應(yīng)用通常應(yīng)該測試錯誤代碼, 而不是查看文本錯誤信息。這些錯誤代碼輕易不會隨著PostgreSQL 的版本更新而修改,并且一般也不會隨著錯誤信息的本地化而發(fā)生修改。 請注意有些(但不是全部)PostgreSQL生成的錯誤代碼是 由 SQL 標(biāo)準(zhǔn)定義的;有些標(biāo)準(zhǔn)沒有定義的錯誤條件是發(fā)明的或者是從其它數(shù)據(jù)庫借來的。
根據(jù)標(biāo)準(zhǔn),錯誤代碼的頭兩個字符表示錯誤類別, 而后三個字符表示在該類別內(nèi)特定的條件。因此, 那些不能識別特定錯誤代碼的應(yīng)用仍然可以從錯誤類別中推斷要做什么。
Table A-1里面列出了PostgreSQL 8.2.3 定義的所有錯誤代碼(有些實際上目前并沒有使用, 但是 SQL 標(biāo)準(zhǔn)定義了)。錯誤類別也列出在此。對于每個錯誤類別都有個 "標(biāo)準(zhǔn)"的錯誤代碼,它的最后三個字符是000。 這個代碼只用于那些落在該類別內(nèi),但是沒有賦予任何更準(zhǔn)確的代碼的錯誤條件。
PL/pgSQL用于每個錯誤代碼的條件名和表中顯示的措辭相同, 只是用下劃線代替了空白。比如,代碼22012, DIVISION BY ZERO 的條件名是DIVISION_BY_ZERO。 條件名大小寫無關(guān)。(請注意PL/pgSQL并不識別警告,這一點和錯誤、條件名正相反;那些是 00, 01, 02 類別。)
Table A-1. PostgreSQL 錯誤代碼
錯誤代碼
含義
常量名
Class 00 — 成功完成
00000 成功完成 successful_completion
Class 01 — 警告
01000 警告 warning
0100C 返回了動態(tài)結(jié)果 dynamic_result_sets_returned
01008 警告,隱含補(bǔ)齊了零比特位 implicit_zero_bit_padding
01003 在集合函數(shù)里消除null null_value_eliminated_in_set_function
01007 沒有賦予權(quán)限 privilege_not_granted
01006 沒有撤銷權(quán)限 privilege_not_revoked
01004 字符串?dāng)?shù)據(jù)在右端截斷 string_data_right_truncation
01P01 廢棄的特性 deprecated_feature
Class 02 — 沒有數(shù)據(jù)(按照 SQL 標(biāo)準(zhǔn)的要求,這也是警告類)
02000 沒有數(shù)據(jù) no_data
02001 返回了沒有附加動態(tài)結(jié)果集 no_additional_dynamic_result_sets_returned
Class 03 — SQL語句尚未結(jié)束
03000 SQL語句尚未結(jié)束 sql_statement_not_yet_complete
Class 08 — 連接異常
08000 連接異常 connection_exception
08003 連接不存在 connection_does_not_exist
08006 連接失敗 connection_failure
08001 SQL 客戶端不能建立 SQL 連接 sqlclient_unable_to_establish_sqlconnection
08004 SQL 服務(wù)器拒絕建立 SQL 連接 sqlserver_rejected_establishment_of_sqlconnection
08007 未知的事務(wù)解析 transaction_resolution_unknown
08P01 違反協(xié)議 protocol_violation
Class 09 — Triggered Action Exception觸發(fā)器動作異常
09000 觸發(fā)器動作異常 triggered_action_exception
Class 0A — 不支持特性
0A000 不支持此特性 feature_not_supported
Class 0B — 非法事務(wù)初始化
0B000 非法事務(wù)初始化 invalid_transaction_initiation
Class 0F — 定位器異常
0F000 定位器異常 locator_exception
0F001 非法的定位器聲明 invalid_locator_specification
Class 0L — 非法賦權(quán)者
0L000 非法賦權(quán)者 invalid_grantor
0LP01 非法賦權(quán)操作 invalid_grant_operation
Class 0P — 非法角色聲明
0P000 非法角色聲明 invalid_role_specification
Class 20 — 未發(fā)現(xiàn)情況
20000 未發(fā)現(xiàn)情況 case_not_found
Class 21 — 勢違例
21000 勢違例 cardinality_violation
Class 22 — 數(shù)據(jù)異常
22000 數(shù)據(jù)異常 data_exception
2202E 數(shù)組下標(biāo)錯誤 array_subscript_error
22021 字符不在規(guī)定范圍內(nèi) character_not_in_repertoire
22008 日期時間字段溢出 datetime_field_overflow
22012 被零除 division_by_zero
22005 賦值中出錯 error_in_assignment
2200B 逃逸字符沖突 escape_character_conflict
22022 INDICATOR OVERFLOW指示器溢出 indicator_overflow
22015 內(nèi)部字段溢出 interval_field_overflow
2201E 對數(shù)運(yùn)算的非法參數(shù) invalid_argument_for_logarithm
22014 NTILE函數(shù)的無效參數(shù) invalid_argument_for_ntile_function
22016 N倍函數(shù)的無效參數(shù) invalid_argument_for_nth_value_function
2201F 指數(shù)函數(shù)的無效參數(shù) invalid_argument_for_power_function
2201G BUCKET函數(shù)的非法參數(shù) invalid_argument_for_width_bucket_function
22018 類型轉(zhuǎn)換時非法的字符值 invalid_character_value_for_cast
22007 非法日期時間格式 invalid_datetime_format
22019 非法的逃逸字符 invalid_escape_character
2200D 非法的逃逸字節(jié) invalid_escape_octet
22025 非法逃逸序列 invalid_escape_sequence
22P06 非標(biāo)準(zhǔn)使用逃逸字符 nonstandard_use_of_escape_character
22010 非法指示器參數(shù)值 invalid_indicator_parameter_value
22023 非法參數(shù)值 invalid_parameter_value
2201B 非法正則表達(dá)式 invalid_regular_expression
2201W 無效的行數(shù)限制 invalid_row_count_in_limit_clause
2201X 在結(jié)果抵消子句中無效的行數(shù) invalid_row_count_in_result_offset_clause
22009 非法時區(qū)顯示值 invalid_time_zone_displacement_value
2200C 逃逸字符的非法使用 invalid_use_of_escape_character
2200G 最相關(guān)類型不匹配 most_specific_type_mismatch
22004 不允許 NULL 值 null_value_not_allowed
22002 NULL 值不能做指示器參數(shù) null_value_no_indicator_parameter
22003 數(shù)字值超出范圍 numeric_value_out_of_range
22026 字符串?dāng)?shù)據(jù)長度不匹配 string_data_length_mismatch
22001 字符串?dāng)?shù)據(jù)右邊被截斷 string_data_right_truncation
22011 抽取子字符串錯誤 substring_error
22027 截斷錯誤 trim_error
22024 未結(jié)束的 C 字符串 unterminated_c_string
2200F 零長度的字符串 zero_length_character_string
22P01 浮點異常 floating_point_exception
22P02 非法文本表現(xiàn)形式 invalid_text_representation
22P03 非法二進(jìn)制表現(xiàn)形式 invalid_binary_representation
22P04 錯誤的COPY文件格式 bad_copy_file_format
22P05 不可翻譯字符 untranslatable_character
2200L 不是一個XML文檔 not_an_xml_document
2200M 無效的XML文檔 invalid_xml_document
2200N 無效的XML內(nèi)容 invalid_xml_content
2200S 無效的XML評論 invalid_xml_comment
2200T 無效的XML處理指令 invalid_xml_processing_instruction
Class 23 — 違反完整性約束
23000 違反完整性約束 integrity_constraint_violation
23001 約束限制 restrict_violation
23502 NOT NULL VIOLATION違反非空 not_null_violation
23503 違反外鍵約束 foreign_key_violation
23505 違反唯一約束 unique_violation
23514 違反檢查 check_violation
23P01 違反排除 exclusion_violation
Class 24 — 非法游標(biāo)狀態(tài)
24000 非法游標(biāo)狀態(tài) invalid_cursor_state
Class 25 — 非法事務(wù)狀態(tài)
25000 非法事務(wù)狀態(tài) invalid_transaction_state
25001 活躍的SQL狀態(tài) active_sql_transaction
25002 分支事務(wù)已經(jīng)激活 branch_transaction_already_active
25008 持有的指針要求同樣的隔離級別 held_cursor_requires_same_isolation_level
25003 對分支事務(wù)的不恰當(dāng)?shù)脑L問方式 inappropriate_access_mode_for_branch_transaction
25004 對分支事務(wù)的不恰當(dāng)?shù)母綦x級別 inappropriate_isolation_level_for_branch_transaction
25005 分支事務(wù)沒有活躍的SQL事務(wù) no_active_sql_transaction_for_branch_transaction
25006 只讀的SQL事務(wù) read_only_sql_transaction
25007 不支持混和的模式和數(shù)據(jù)語句 schema_and_data_statement_mixing_not_supported
25P01 沒有活躍的SQL事務(wù) no_active_sql_transaction
25P02 在失敗的SQL事務(wù)中 in_failed_sql_transaction
Class 26 — 非法SQL語句名
26000 非法SQL語句名 invalid_sql_statement_name
Class 27 — 觸發(fā)數(shù)據(jù)更改違規(guī)
27000 觸發(fā)數(shù)據(jù)更改違規(guī) triggered_data_change_violation
Class 28 — 非法授權(quán)聲明
28000 非法授權(quán)聲明 invalid_authorization_specification
28P01 非法密碼 invalid_password
Class 2B — 依然存在依賴的優(yōu)先級描述符
2B000 依然存在依賴的優(yōu)先級描述符 dependent_privilege_descriptors_still_exist
2BP01 依賴性對象仍然存在 dependent_objects_still_exist
Class 2D — 非法的事務(wù)終止
2D000 非法的事務(wù)終止 invalid_transaction_termination
Class 2F — SQL過程異常
2F000 SQL過程異常 sql_routine_exception
2F005 執(zhí)行的函數(shù)沒有返回語句 function_executed_no_return_statement
2F002 不允許修改SQL數(shù)據(jù) modifying_sql_data_not_permitted
2F003 企圖使用禁止的SQL語句 prohibited_sql_statement_attempted
2F004 不允許讀取SQL數(shù)據(jù) reading_sql_data_not_permitted
Class 34 — 非法指針名
34000 非法指針名 invalid_cursor_name
Class 38 — 外部過程異常
38000 外部過程異常 external_routine_exception
38001 不允許包含的SQL containing_sql_not_permitted
38002 不允許修改SQL數(shù)據(jù) modifying_sql_data_not_permitted
38003 企圖使用禁止的SQL語句 prohibited_sql_statement_attempted
38004 不允許讀取SQL數(shù)據(jù) reading_sql_data_not_permitted
Class 39 — 外部過程調(diào)用異常
39000 外部過程調(diào)用異常 external_routine_invocation_exception
39001 返回了非法的SQL狀態(tài) invalid_sqlstate_returned
39004 不允許使用NULL null_value_not_allowed
39P01 違反觸發(fā)器協(xié)議 trigger_protocol_violated
39P02 違反 SRF 協(xié)議 srf_protocol_violated
Class 3B — 保存點異常
3B000 保存點異常 savepoint_exception
3B001 無效的保存點聲明 invalid_savepoint_specification
Class 3D — 非法目錄名
3D000 非法目錄名 invalid_catalog_name
Class 3F — 非法模式名
3F000 非法模式名 invalid_schema_name
Class 40 — 事務(wù)回滾
40000 事務(wù)回滾 transaction_rollback
40002 違反事務(wù)完整性約束 transaction_integrity_constraint_violation
40001 串行化失敗 serialization_failure
40003 不知道語句是否結(jié)束 statement_completion_unknown
40P01 偵測到死鎖 deadlock_detected
Class 42 — 語法錯誤或者違反訪問規(guī)則
42000 語法錯誤或者違反訪問規(guī)則 syntax_error_or_access_rule_violation
42601 語法錯誤 syntax_error
42501 權(quán)限不夠 insufficient_privilege
42846 無法進(jìn)行類型轉(zhuǎn)換 cannot_coerce
42803 分組錯誤 grouping_error
42P20 開窗口錯誤 windowing_error
42P19 非法遞歸 invalid_recursion
42830 非法的外鍵 invalid_foreign_key
42602 非法名稱 invalid_name
42622 名稱過長 name_too_long
42939 保留名稱 reserved_name
42804 數(shù)據(jù)類型不匹配 datatype_mismatch
42P18 模糊數(shù)據(jù)類型 indeterminate_datatype
42809 錯誤的對象類型 wrong_object_type
42703 未定義的字段 undefined_column
42883 未定義的函數(shù) undefined_function
42P01 未定義的表 undefined_table
42P02 未定義的參數(shù) undefined_parameter
42704 未定義對象 undefined_object
42701 重復(fù)的字段 duplicate_column
42P03 重復(fù)的游標(biāo) duplicate_cursor
42P04 重復(fù)的數(shù)據(jù)庫 duplicate_database
42723 重復(fù)的函數(shù) duplicate_function
42P05 重復(fù)的預(yù)備語句 duplicate_prepared_statement
42P06 重復(fù)的模式 duplicate_schema
42P07 重復(fù)的表 duplicate_table
42712 重復(fù)的別名 duplicate_alias
42710 重復(fù)的對象 duplicate_object
42702 模糊的字段 ambiguous_column
42725 模糊的函數(shù) ambiguous_function
42P08 模糊的參數(shù) ambiguous_parameter
42P09 模糊的別名 ambiguous_alias
42P10 非法字段引用 invalid_column_reference
42611 非法字段定義 invalid_column_definition
42P11 非法游標(biāo)定義 invalid_cursor_definition
42P12 非法數(shù)據(jù)庫定義 invalid_database_definition
42P13 非法函數(shù)定義 invalid_function_definition
42P14 非法預(yù)備語句定義 invalid_prepared_statement_definition
42P15 非法模式定義 invalid_schema_definition
42P16 非法表定義 invalid_table_definition
42P17 非法對象定義 invalid_object_definition
Class 44 — 違反 WITH CHECK 選項
44000 違反 WITH CHECK 選項 with_check_option_violation
特性 MySQL PostgreSQL
實例 通過執(zhí)行 MySQL 命令(mysqld)啟動實例。一個實例可以管理一個或多個數(shù)據(jù)庫。一臺服務(wù)器可以運(yùn)行多個 mysqld 實例。一個實例管理器可以監(jiān)視 mysqld 的各個實例。
通過執(zhí)行 Postmaster 進(jìn)程(pg_ctl)啟動實例。一個實例可以管理一個或多個數(shù)據(jù)庫,這些數(shù)據(jù)庫組成一個集群。集群是磁盤上的一個區(qū)域,這個區(qū)域在安裝時初始化并由一個目錄組成,所有數(shù)據(jù)都存儲在這個目錄中。使用 initdb 創(chuàng)建第一個數(shù)據(jù)庫。一臺機(jī)器上可以啟動多個實例。
數(shù)據(jù)庫 數(shù)據(jù)庫是命名的對象集合,是與實例中的其他數(shù)據(jù)庫分離的實體。一個 MySQL 實例中的所有數(shù)據(jù)庫共享同一個系統(tǒng)編目。 數(shù)據(jù)庫是命名的對象集合,每個數(shù)據(jù)庫是與其他數(shù)據(jù)庫分離的實體。每個數(shù)據(jù)庫有自己的系統(tǒng)編目,但是所有數(shù)據(jù)庫共享 pg_databases。
數(shù)據(jù)緩沖區(qū) 通過 innodb_buffer_pool_size 配置參數(shù)設(shè)置數(shù)據(jù)緩沖區(qū)。這個參數(shù)是內(nèi)存緩沖區(qū)的字節(jié)數(shù),InnoDB 使用這個緩沖區(qū)來緩存表的數(shù)據(jù)和索引。在專用的數(shù)據(jù)庫服務(wù)器上,這個參數(shù)最高可以設(shè)置為機(jī)器物理內(nèi)存量的 80%。 Shared_buffers 緩存。在默認(rèn)情況下分配 64 個緩沖區(qū)。默認(rèn)的塊大小是 8K??梢酝ㄟ^設(shè)置 postgresql.conf 文件中的 shared_buffers 參數(shù)來更新緩沖區(qū)緩存。
數(shù)據(jù)庫連接 客戶機(jī)使用 CONNECT 或 USE 語句連接數(shù)據(jù)庫,這時要指定數(shù)據(jù)庫名,還可以指定用戶 id 和密碼。使用角色管理數(shù)據(jù)庫中的用戶和用戶組。 客戶機(jī)使用 connect 語句連接數(shù)據(jù)庫,這時要指定數(shù)據(jù)庫名,還可以指定用戶 id 和密碼。使用角色管理數(shù)據(jù)庫中的用戶和用戶組。
身份驗證 MySQL 在數(shù)據(jù)庫級管理身份驗證。 基本只支持密碼認(rèn)證。 PostgreSQL 支持豐富的認(rèn)證方法:信任認(rèn)證、口令認(rèn)證、Kerberos 認(rèn)證、基于 Ident 的認(rèn)證、LDAP 認(rèn)證、PAM 認(rèn)證
加密 可以在表級指定密碼來對數(shù)據(jù)進(jìn)行加密。還可以使用 AES_ENCRYPT 和 AES_DECRYPT 函數(shù)對列數(shù)據(jù)進(jìn)行加密和解密。可以通過 SSL 連接實現(xiàn)網(wǎng)絡(luò)加密。 可以使用 pgcrypto 庫中的函數(shù)對列進(jìn)行加密/解密??梢酝ㄟ^ SSL 連接實現(xiàn)網(wǎng)絡(luò)加密。
審計 可以對 querylog 執(zhí)行 grep。 可以在表上使用 PL/pgSQL 觸發(fā)器來進(jìn)行審計。
查詢解釋 使用 EXPLAIN 命令查看查詢的解釋計劃。 使用 EXPLAIN 命令查看查詢的解釋計劃。
備份、恢復(fù)和日志 InnoDB 使用寫前(write-ahead)日志記錄。支持在線和離線完全備份以及崩潰和事務(wù)恢復(fù)。需要第三方軟件才能支持熱備份。 在數(shù)據(jù)目錄的一個子目錄中維護(hù)寫前日志。支持在線和離線完全備份以及崩潰、時間點和事務(wù)恢復(fù)。 可以支持熱備份。
JDBC 驅(qū)動程序 可以從 參考資料 下載 JDBC 驅(qū)動程序。 可以從 參考資料 下載 JDBC 驅(qū)動程序。
表類型 取決于存儲引擎。例如,NDB 存儲引擎支持分區(qū)表,內(nèi)存引擎支持內(nèi)存表。 支持臨時表、常規(guī)表以及范圍和列表類型的分區(qū)表。不支持哈希分區(qū)表。 由于PostgreSQL的表分區(qū)是通過表繼承和規(guī)則系統(tǒng)完成了,所以可以實現(xiàn)更復(fù)雜的分區(qū)方式。
索引類型 取決于存儲引擎。MyISAM:BTREE,InnoDB:BTREE。 支持 B-樹、哈希、R-樹和 Gist 索引。
約束 支持主鍵、外鍵、惟一和非空約束。對檢查約束進(jìn)行解析,但是不強(qiáng)制實施。 支持主鍵、外鍵、惟一、非空和檢查約束。
存儲過程和用戶定義函數(shù) 支持 CREATE PROCEDURE 和 CREATE FUNCTION 語句。存儲過程可以用 SQL 和 C++ 編寫。用戶定義函數(shù)可以用 SQL、C 和 C++ 編寫。 沒有單獨的存儲過程,都是通過函數(shù)實現(xiàn)的。用戶定義函數(shù)可以用 PL/pgSQL(專用的過程語言)、PL/Tcl、PL/Perl、PL/Python 、SQL 和 C 編寫。
觸發(fā)器 支持行前觸發(fā)器、行后觸發(fā)器和語句觸發(fā)器,觸發(fā)器語句用過程語言復(fù)合語句編寫。 支持行前觸發(fā)器、行后觸發(fā)器和語句觸發(fā)器,觸發(fā)器過程用 C 編寫。
系統(tǒng)配置文件 my.conf Postgresql.conf
數(shù)據(jù)庫配置 my.conf Postgresql.conf
客戶機(jī)連接文件 my.conf pg_hba.conf
XML 支持 有限的 XML 支持。 有限的 XML 支持。
數(shù)據(jù)訪問和管理服務(wù)器 OPTIMIZE TABLE —— 回收未使用的空間并消除數(shù)據(jù)文件的碎片
myisamchk -analyze —— 更新查詢優(yōu)化器所使用的統(tǒng)計數(shù)據(jù)(MyISAM 存儲引擎)
mysql —— 命令行工具
MySQL Administrator —— 客戶機(jī) GUI 工具 Vacuum —— 回收未使用的空間
Analyze —— 更新查詢優(yōu)化器所使用的統(tǒng)計數(shù)據(jù)
psql —— 命令行工具
pgAdmin —— 客戶機(jī) GUI 工具
并發(fā)控制 支持表級和行級鎖。InnoDB 存儲引擎支持 READ_COMMITTED、READ_UNCOMMITTED、REPEATABLE_READ 和 SERIALIZABLE。使用 SET TRANSACTION ISOLATION LEVEL 語句在事務(wù)級設(shè)置隔離級別。 支持表級和行級鎖。支持的 ANSI 隔離級別是 Read Committed(默認(rèn) —— 能看到查詢啟動時數(shù)據(jù)庫的快照)和 Serialization(與 Repeatable Read 相似 —— 只能看到在事務(wù)啟動之前提交的結(jié)果)。使用 SET TRANSACTION 語句在事務(wù)級設(shè)置隔離級別。使用 SET SESSION 在會話級進(jìn)行設(shè)置。
MySQL相對于PostgreSQL的劣勢:
MySQL
PostgreSQL
最重要的引擎InnoDB很早就由Oracle公司控制。目前整個MySQL數(shù)據(jù)庫都由Oracle控制。
BSD協(xié)議,沒有被大公司壟斷。
對復(fù)雜查詢的處理較弱,查詢優(yōu)化器不夠成熟
很強(qiáng)大的查詢優(yōu)化器,支持很復(fù)雜的查詢處理。
只有一種表連接類型:嵌套循環(huán)連接(nested-loop),不支持排序-合并連接(sort-merge join)與散列連接(hash join)。
都支持
性能優(yōu)化工具與度量信息不足
提供了一些性能視圖,可以方便的看到發(fā)生在一個表和索引上的select、delete、update、insert統(tǒng)計信息,也可以看到cache命中率。網(wǎng)上有一個開源的pgstatspack工具。
InnoDB的表和索引都是按相同的方式存儲。也就是說表都是索引組織表。這一般要求主鍵不能太長而且插入時的主鍵最好是按順序遞增,否則對性能有很大影響。
不存在這個問題。
大部分查詢只能使用表上的單一索引;在某些情況下,會存在使用多個索引的查詢,但是查詢優(yōu)化器通常會低估其成本,它們常常比表掃描還要慢。
不存在這個問題
表增加列,基本上是重建表和索引,會花很長時間。
表增加列,只是在數(shù)據(jù)字典中增加表定義,不會重建表
存儲過程與觸發(fā)器的功能有限。可用來編寫存儲過程、觸發(fā)器、計劃事件以及存儲函數(shù)的語言功能較弱
除支持pl/pgsql寫存儲過程,還支持perl、python、Tcl類型的存儲過程:pl/perl,pl/python,pl/tcl。
也支持用C語言寫存儲過程。
不支持Sequence。
支持
不支持函數(shù)索引,只能在創(chuàng)建基于具體列的索引。
不支持物化視圖。
支持函數(shù)索引,同時還支持部分?jǐn)?shù)據(jù)索引,通過規(guī)則系統(tǒng)可以實現(xiàn)物化視圖的功能。
執(zhí)行計劃并不是全局共享的, 僅僅在連接內(nèi)部是共享的。
執(zhí)行計劃共享
MySQL支持的SQL語法(ANSI SQL標(biāo)準(zhǔn))的很小一部分。不支持遞歸查詢、通用表表達(dá)式(Oracle的with 語句)或者窗口函數(shù)(分析函數(shù))。
都 支持
不支持用戶自定義類型或域(domain)
支持。
對于時間、日期、間隔等時間類型沒有秒以下級別的存儲類型
可以精確到秒以下。
身份驗證功能是完全內(nèi)置的,不支持操作系統(tǒng)認(rèn)證、PAM認(rèn)證,不支持LDAP以及其它類似的外部身份驗證功能。
支持OS認(rèn)證、Kerberos 認(rèn)證 、Ident 的認(rèn)證、LDAP 認(rèn)證、PAM 認(rèn)證
不支持database link。有一種叫做Federated的存儲引擎可以作為一個中轉(zhuǎn)將查詢語句傳遞到遠(yuǎn)程服務(wù)器的一個表上,不過,它功能很粗糙并且漏洞很多
有dblink,同時還有一個dbi-link的東西,可以連接到oracle和mysql上。
Mysql Cluster可能與你的想象有較大差異。開源的cluster軟件較少。
復(fù)制(Replication)功能是異步的,并且有很大的局限性.例如,它是單線程的(single-threaded),因此一個處理能力更強(qiáng)的Slave的恢復(fù)速度也很難跟上處理能力相對較慢的Master.
有豐富的開源cluster軟件支持。
explain看執(zhí)行計劃的結(jié)果簡單。
explain返回豐富的信息。
類似于ALTER TABLE或CREATE TABLE一類的操作都是非事務(wù)性的.它們會提交未提交的事務(wù),并且不能回滾也不能做災(zāi)難恢復(fù)
DDL也是有事務(wù)的。
PostgreSQL主要優(yōu)勢:
1. PostgreSQL完全免費(fèi),而且是BSD協(xié)議,如果你把PostgreSQL改一改,然后再拿去賣錢,也沒有人管你,這一點很重要,這表明了PostgreSQL數(shù)據(jù)庫不會被其它公司控制。oracle數(shù)據(jù)庫不用說了,是商業(yè)數(shù)據(jù)庫,不開放。而MySQL數(shù)據(jù)庫雖然是開源的,但現(xiàn)在隨著SUN被oracle公司收購,現(xiàn)在基本上被oracle公司控制,其實在SUN被收購之前,MySQL中最重要的InnoDB引擎也是被oracle公司控制的,而在MySQL中很多重要的數(shù)據(jù)都是放在InnoDB引擎中的,反正我們公司都是這樣的。所以如果MySQL的市場范圍與oracle數(shù)據(jù)庫的市場范圍沖突時,oracle公司必定會犧牲MySQL,這是毫無疑問的。
2. 與PostgreSQl配合的開源軟件很多,有很多分布式集群軟件,如pgpool、pgcluster、slony、plploxy等等,很容易做讀寫分離、負(fù)載均衡、數(shù)據(jù)水平拆分等方案,而這在MySQL下則比較困難。
3. PostgreSQL源代碼寫的很清晰,易讀性比MySQL強(qiáng)太多了,懷疑MySQL的源代碼被混淆過。所以很多公司都是基本PostgreSQL做二次開發(fā)的。
4. PostgreSQL在很多方面都比MySQL強(qiáng),如復(fù)雜SQL的執(zhí)行、存儲過程、觸發(fā)器、索引。同時PostgreSQL是多進(jìn)程的,而MySQL是線程的,雖然并發(fā)不高時,MySQL處理速度快,但當(dāng)并發(fā)高的時候,對于現(xiàn)在多核的單臺機(jī)器上,MySQL的總體處理性能不如PostgreSQL,原因是MySQL的線程無法充分利用CPU的能力。
目前只想到這些,以后想到再添加,歡迎大家拍磚。
PostgreSQL與oracle或InnoDB的多版本實現(xiàn)的差別
PostgreSQL與oracle或InnoDB的多版本實現(xiàn)最大的區(qū)別在于最新版本和歷史版本是否分離存儲,PostgreSQL不分,而oracle和InnoDB分,而innodb也只是分離了數(shù)據(jù),索引本身沒有分開。
PostgreSQL的主要優(yōu)勢在于:
1. PostgreSQL沒有回滾段,而oracle與innodb有回滾段,oracle與Innodb都有回滾段。對于oracle與Innodb來說,回滾段是非常重要的,回滾段損壞,會導(dǎo)致數(shù)據(jù)丟失,甚至數(shù)據(jù)庫無法啟動的嚴(yán)重問題。另由于PostgreSQL沒有回滾段,舊數(shù)據(jù)都是記錄在原先的文件中,所以當(dāng)數(shù)據(jù)庫異常crash后,恢復(fù)時,不會象oracle與Innodb數(shù)據(jù)庫那樣進(jìn)行那么復(fù)雜的恢復(fù),因為oracle與Innodb恢復(fù)時同步需要redo和undo。所以PostgreSQL數(shù)據(jù)庫在出現(xiàn)異常crash后,數(shù)據(jù)庫起不來的幾率要比oracle和mysql小一些。
2. 由于舊的數(shù)據(jù)是直接記錄在數(shù)據(jù)文件中,而不是回滾段中,所以不會象oracle那樣經(jīng)常報ora-01555錯誤。
3. 回滾可以很快完成,因為回滾并不刪除數(shù)據(jù),而oracle與Innodb,回滾時很復(fù)雜,在事務(wù)回滾時必須清理該事務(wù)所進(jìn)行的修改,插入的記錄要刪除,更新的記錄要更新回來(見row_undo函數(shù)),同時回滾的過程也會再次產(chǎn)生大量的redo日志。
4. WAL日志要比oracle和Innodb簡單,對于oracle不僅需要記錄數(shù)據(jù)文件的變化,還要記錄回滾段的變化。
PostgreSQL的多版本的主要劣勢在于:
1、最新版本和歷史版本不分離存儲,導(dǎo)致清理老舊版本需要作更多的掃描,代價比較大,但一般的數(shù)據(jù)庫都有高峰期,如果我們合理安排VACUUM,這也不是很大的問題,而且在PostgreSQL9.0中VACUUM進(jìn)一步被加強(qiáng)了。
2、由于索引中完全沒有版本信息,不能實現(xiàn)Coverage index scan,即查詢只掃描索引,直接從索引中返回所需的屬性,還需要訪問表。而oracle與Innodb則可以;
進(jìn)程模式與線程模式的對比
PostgreSQL和oracle是進(jìn)程模式,MySQL是線程模式。
進(jìn)程模式對多CPU利用率比較高。
進(jìn)程模式共享數(shù)據(jù)需要用到共享內(nèi)存,而線程模式數(shù)據(jù)本身就是在進(jìn)程空間內(nèi)都是共享的,不同線程訪問只需要控制好線程之間的同步。
線程模式對資源消耗比較少。
所以MySQL能支持遠(yuǎn)比oracle多的更多的連接。
對于PostgreSQL的來說,如果不使用連接池軟件,也存在這個問題,但PostgreSQL中有優(yōu)秀的連接池軟件軟件,如pgbouncer和pgpool,所以通過連接池也可以支持很多的連接。
SQL server 觸發(fā)器 沒有 BEFORE 啊, 只有 AFTER.
對于 postgresql, 如果 befroe 異常了, 那就回滾結(jié)束掉了, after 沒有執(zhí)行的意義了。
after 觸發(fā)器執(zhí)行異常了, 對于 postgresql 和 SQL server , 那都是要回滾的。
特性 MySQL PostgreSQL
實例 通過執(zhí)行 MySQL 命令(mysqld)啟動實例。一個實例可以管理一個或多個數(shù)據(jù)庫。一臺服務(wù)器可以運(yùn)行多個 mysqld 實例。一個實例管理器可以監(jiān)視 mysqld 的各個實例。
通過執(zhí)行 Postmaster 進(jìn)程(pg_ctl)啟動實例。一個實例可以管理一個或多個數(shù)據(jù)庫,這些數(shù)據(jù)庫組成一個集群。集群是磁盤上的一個區(qū)域,這個區(qū)域在安裝時初始化并由一個目錄組成,所有數(shù)據(jù)都存儲在這個目錄中。使用 initdb 創(chuàng)建第一個數(shù)據(jù)庫。一臺機(jī)器上可以啟動多個實例。
數(shù)據(jù)庫 數(shù)據(jù)庫是命名的對象集合,是與實例中的其他數(shù)據(jù)庫分離的實體。一個 MySQL 實例中的所有數(shù)據(jù)庫共享同一個系統(tǒng)編目。 數(shù)據(jù)庫是命名的對象集合,每個數(shù)據(jù)庫是與其他數(shù)據(jù)庫分離的實體。每個數(shù)據(jù)庫有自己的系統(tǒng)編目,但是所有數(shù)據(jù)庫共享 pg_databases。
數(shù)據(jù)緩沖區(qū) 通過 innodb_buffer_pool_size 配置參數(shù)設(shè)置數(shù)據(jù)緩沖區(qū)。這個參數(shù)是內(nèi)存緩沖區(qū)的字節(jié)數(shù),InnoDB 使用這個緩沖區(qū)來緩存表的數(shù)據(jù)和索引。在專用的數(shù)據(jù)庫服務(wù)器上,這個參數(shù)最高可以設(shè)置為機(jī)器物理內(nèi)存量的 80%。 Shared_buffers 緩存。在默認(rèn)情況下分配 64 個緩沖區(qū)。默認(rèn)的塊大小是 8K??梢酝ㄟ^設(shè)置 postgresql.conf 文件中的 shared_buffers 參數(shù)來更新緩沖區(qū)緩存。
數(shù)據(jù)庫連接 客戶機(jī)使用 CONNECT 或 USE 語句連接數(shù)據(jù)庫,這時要指定數(shù)據(jù)庫名,還可以指定用戶 id 和密碼。使用角色管理數(shù)據(jù)庫中的用戶和用戶組。 客戶機(jī)使用 connect 語句連接數(shù)據(jù)庫,這時要指定數(shù)據(jù)庫名,還可以指定用戶 id 和密碼。使用角色管理數(shù)據(jù)庫中的用戶和用戶組。
身份驗證 MySQL 在數(shù)據(jù)庫級管理身份驗證。 基本只支持密碼認(rèn)證。 PostgreSQL 支持豐富的認(rèn)證方法:信任認(rèn)證、口令認(rèn)證、Kerberos 認(rèn)證、基于 Ident 的認(rèn)證、LDAP 認(rèn)證、PAM 認(rèn)證
加密 可以在表級指定密碼來對數(shù)據(jù)進(jìn)行加密。還可以使用 AES_ENCRYPT 和 AES_DECRYPT 函數(shù)對列數(shù)據(jù)進(jìn)行加密和解密??梢酝ㄟ^ SSL 連接實現(xiàn)網(wǎng)絡(luò)加密。 可以使用 pgcrypto 庫中的函數(shù)對列進(jìn)行加密/解密??梢酝ㄟ^ SSL 連接實現(xiàn)網(wǎng)絡(luò)加密。
審計 可以對 querylog 執(zhí)行 grep。 可以在表上使用 PL/pgSQL 觸發(fā)器來進(jìn)行審計。
查詢解釋 使用 EXPLAIN 命令查看查詢的解釋計劃。 使用 EXPLAIN 命令查看查詢的解釋計劃。
備份、恢復(fù)和日志 InnoDB 使用寫前(write-ahead)日志記錄。支持在線和離線完全備份以及崩潰和事務(wù)恢復(fù)。需要第三方軟件才能支持熱備份。 在數(shù)據(jù)目錄的一個子目錄中維護(hù)寫前日志。支持在線和離線完全備份以及崩潰、時間點和事務(wù)恢復(fù)。 可以支持熱備份。
JDBC 驅(qū)動程序 可以從 參考資料 下載 JDBC 驅(qū)動程序。 可以從 參考資料 下載 JDBC 驅(qū)動程序。
表類型 取決于存儲引擎。例如,NDB 存儲引擎支持分區(qū)表,內(nèi)存引擎支持內(nèi)存表。 支持臨時表、常規(guī)表以及范圍和列表類型的分區(qū)表。不支持哈希分區(qū)表。 由于PostgreSQL的表分區(qū)是通過表繼承和規(guī)則系統(tǒng)完成了,所以可以實現(xiàn)更復(fù)雜的分區(qū)方式。
索引類型 取決于存儲引擎。MyISAM:BTREE,InnoDB:BTREE。 支持 B-樹、哈希、R-樹和 Gist 索引。
約束 支持主鍵、外鍵、惟一和非空約束。對檢查約束進(jìn)行解析,但是不強(qiáng)制實施。 支持主鍵、外鍵、惟一、非空和檢查約束。
存儲過程和用戶定義函數(shù) 支持 CREATE PROCEDURE 和 CREATE FUNCTION 語句。存儲過程可以用 SQL 和 C++ 編寫。用戶定義函數(shù)可以用 SQL、C 和 C++ 編寫。 沒有單獨的存儲過程,都是通過函數(shù)實現(xiàn)的。用戶定義函數(shù)可以用 PL/pgSQL(專用的過程語言)、PL/Tcl、PL/Perl、PL/Python 、SQL 和 C 編寫。
觸發(fā)器 支持行前觸發(fā)器、行后觸發(fā)器和語句觸發(fā)器,觸發(fā)器語句用過程語言復(fù)合語句編寫。 支持行前觸發(fā)器、行后觸發(fā)器和語句觸發(fā)器,觸發(fā)器過程用 C 編寫。
系統(tǒng)配置文件 my.conf Postgresql.conf
數(shù)據(jù)庫配置 my.conf Postgresql.conf
客戶機(jī)連接文件 my.conf pg_hba.conf
XML 支持 有限的 XML 支持。 有限的 XML 支持。
數(shù)據(jù)訪問和管理服務(wù)器 OPTIMIZE TABLE —— 回收未使用的空間并消除數(shù)據(jù)文件的碎片
myisamchk -analyze —— 更新查詢優(yōu)化器所使用的統(tǒng)計數(shù)據(jù)(MyISAM 存儲引擎)
mysql —— 命令行工具
MySQL Administrator —— 客戶機(jī) GUI 工具 Vacuum —— 回收未使用的空間
Analyze —— 更新查詢優(yōu)化器所使用的統(tǒng)計數(shù)據(jù)
psql —— 命令行工具
pgAdmin —— 客戶機(jī) GUI 工具
并發(fā)控制 支持表級和行級鎖。InnoDB 存儲引擎支持 READ_COMMITTED、READ_UNCOMMITTED、REPEATABLE_READ 和 SERIALIZABLE。使用 SET TRANSACTION ISOLATION LEVEL 語句在事務(wù)級設(shè)置隔離級別。 支持表級和行級鎖。支持的 ANSI 隔離級別是 Read Committed(默認(rèn) —— 能看到查詢啟動時數(shù)據(jù)庫的快照)和 Serialization(與 Repeatable Read 相似 —— 只能看到在事務(wù)啟動之前提交的結(jié)果)。使用 SET TRANSACTION 語句在事務(wù)級設(shè)置隔離級別。使用 SET SESSION 在會話級進(jìn)行設(shè)置。
MySQL相對于PostgreSQL的劣勢:
MySQL
PostgreSQL
最重要的引擎InnoDB很早就由Oracle公司控制。目前整個MySQL數(shù)據(jù)庫都由Oracle控制。
BSD協(xié)議,沒有被大公司壟斷。
對復(fù)雜查詢的處理較弱,查詢優(yōu)化器不夠成熟
很強(qiáng)大的查詢優(yōu)化器,支持很復(fù)雜的查詢處理。
只有一種表連接類型:嵌套循環(huán)連接(nested-loop),不支持排序-合并連接(sort-merge join)與散列連接(hash join)。
都支持
性能優(yōu)化工具與度量信息不足
提供了一些性能視圖,可以方便的看到發(fā)生在一個表和索引上的select、delete、update、insert統(tǒng)計信息,也可以看到cache命中率。網(wǎng)上有一個開源的pgstatspack工具。
InnoDB的表和索引都是按相同的方式存儲。也就是說表都是索引組織表。這一般要求主鍵不能太長而且插入時的主鍵最好是按順序遞增,否則對性能有很大影響。
不存在這個問題。
大部分查詢只能使用表上的單一索引;在某些情況下,會存在使用多個索引的查詢,但是查詢優(yōu)化器通常會低估其成本,它們常常比表掃描還要慢。
不存在這個問題
表增加列,基本上是重建表和索引,會花很長時間。
表增加列,只是在數(shù)據(jù)字典中增加表定義,不會重建表
存儲過程與觸發(fā)器的功能有限??捎脕砭帉懘鎯^程、觸發(fā)器、計劃事件以及存儲函數(shù)的語言功能較弱
除支持pl/pgsql寫存儲過程,還支持perl、python、Tcl類型的存儲過程:pl/perl,pl/python,pl/tcl。
也支持用C語言寫存儲過程。
不支持Sequence。
支持
不支持函數(shù)索引,只能在創(chuàng)建基于具體列的索引。
不支持物化視圖。
支持函數(shù)索引,同時還支持部分?jǐn)?shù)據(jù)索引,通過規(guī)則系統(tǒng)可以實現(xiàn)物化視圖的功能。
執(zhí)行計劃并不是全局共享的, 僅僅在連接內(nèi)部是共享的。
執(zhí)行計劃共享
MySQL支持的SQL語法(ANSI SQL標(biāo)準(zhǔn))的很小一部分。不支持遞歸查詢、通用表表達(dá)式(Oracle的with 語句)或者窗口函數(shù)(分析函數(shù))。
都 支持
不支持用戶自定義類型或域(domain)
支持。
對于時間、日期、間隔等時間類型沒有秒以下級別的存儲類型
可以精確到秒以下。
身份驗證功能是完全內(nèi)置的,不支持操作系統(tǒng)認(rèn)證、PAM認(rèn)證,不支持LDAP以及其它類似的外部身份驗證功能。
支持OS認(rèn)證、Kerberos 認(rèn)證 、Ident 的認(rèn)證、LDAP 認(rèn)證、PAM 認(rèn)證
不支持database link。有一種叫做Federated的存儲引擎可以作為一個中轉(zhuǎn)將查詢語句傳遞到遠(yuǎn)程服務(wù)器的一個表上,不過,它功能很粗糙并且漏洞很多
有dblink,同時還有一個dbi-link的東西,可以連接到oracle和mysql上。
Mysql Cluster可能與你的想象有較大差異。開源的cluster軟件較少。
復(fù)制(Replication)功能是異步的,并且有很大的局限性.例如,它是單線程的(single-threaded),因此一個處理能力更強(qiáng)的Slave的恢復(fù)速度也很難跟上處理能力相對較慢的Master.
有豐富的開源cluster軟件支持。
explain看執(zhí)行計劃的結(jié)果簡單。
explain返回豐富的信息。
類似于ALTER TABLE或CREATE TABLE一類的操作都是非事務(wù)性的.它們會提交未提交的事務(wù),并且不能回滾也不能做災(zāi)難恢復(fù)
DDL也是有事務(wù)的。
PostgreSQL主要優(yōu)勢:
1. PostgreSQL完全免費(fèi),而且是BSD協(xié)議,如果你把PostgreSQL改一改,然后再拿去賣錢,也沒有人管你,這一點很重要,這表明了PostgreSQL數(shù)據(jù)庫不會被其它公司控制。oracle數(shù)據(jù)庫不用說了,是商業(yè)數(shù)據(jù)庫,不開放。而MySQL數(shù)據(jù)庫雖然是開源的,但現(xiàn)在隨著SUN被oracle公司收購,現(xiàn)在基本上被oracle公司控制,其實在SUN被收購之前,MySQL中最重要的InnoDB引擎也是被oracle公司控制的,而在MySQL中很多重要的數(shù)據(jù)都是放在InnoDB引擎中的,反正我們公司都是這樣的。所以如果MySQL的市場范圍與oracle數(shù)據(jù)庫的市場范圍沖突時,oracle公司必定會犧牲MySQL,這是毫無疑問的。
2. 與PostgreSQl配合的開源軟件很多,有很多分布式集群軟件,如pgpool、pgcluster、slony、plploxy等等,很容易做讀寫分離、負(fù)載均衡、數(shù)據(jù)水平拆分等方案,而這在MySQL下則比較困難。
3. PostgreSQL源代碼寫的很清晰,易讀性比MySQL強(qiáng)太多了,懷疑MySQL的源代碼被混淆過。所以很多公司都是基本PostgreSQL做二次開發(fā)的。
4. PostgreSQL在很多方面都比MySQL強(qiáng),如復(fù)雜SQL的執(zhí)行、存儲過程、觸發(fā)器、索引。同時PostgreSQL是多進(jìn)程的,而MySQL是線程的,雖然并發(fā)不高時,MySQL處理速度快,但當(dāng)并發(fā)高的時候,對于現(xiàn)在多核的單臺機(jī)器上,MySQL的總體處理性能不如PostgreSQL,原因是MySQL的線程無法充分利用CPU的能力。
目前只想到這些,以后想到再添加,歡迎大家拍磚。
PostgreSQL與oracle或InnoDB的多版本實現(xiàn)的差別
PostgreSQL與oracle或InnoDB的多版本實現(xiàn)最大的區(qū)別在于最新版本和歷史版本是否分離存儲,PostgreSQL不分,而oracle和InnoDB分,而innodb也只是分離了數(shù)據(jù),索引本身沒有分開。
PostgreSQL的主要優(yōu)勢在于:
1. PostgreSQL沒有回滾段,而oracle與innodb有回滾段,oracle與Innodb都有回滾段。對于oracle與Innodb來說,回滾段是非常重要的,回滾段損壞,會導(dǎo)致數(shù)據(jù)丟失,甚至數(shù)據(jù)庫無法啟動的嚴(yán)重問題。另由于PostgreSQL沒有回滾段,舊數(shù)據(jù)都是記錄在原先的文件中,所以當(dāng)數(shù)據(jù)庫異常crash后,恢復(fù)時,不會象oracle與Innodb數(shù)據(jù)庫那樣進(jìn)行那么復(fù)雜的恢復(fù),因為oracle與Innodb恢復(fù)時同步需要redo和undo。所以PostgreSQL數(shù)據(jù)庫在出現(xiàn)異常crash后,數(shù)據(jù)庫起不來的幾率要比oracle和mysql小一些。
2. 由于舊的數(shù)據(jù)是直接記錄在數(shù)據(jù)文件中,而不是回滾段中,所以不會象oracle那樣經(jīng)常報ora-01555錯誤。
3. 回滾可以很快完成,因為回滾并不刪除數(shù)據(jù),而oracle與Innodb,回滾時很復(fù)雜,在事務(wù)回滾時必須清理該事務(wù)所進(jìn)行的修改,插入的記錄要刪除,更新的記錄要更新回來(見row_undo函數(shù)),同時回滾的過程也會再次產(chǎn)生大量的redo日志。
4. WAL日志要比oracle和Innodb簡單,對于oracle不僅需要記錄數(shù)據(jù)文件的變化,還要記錄回滾段的變化。
PostgreSQL的多版本的主要劣勢在于:
1、最新版本和歷史版本不分離存儲,導(dǎo)致清理老舊版本需要作更多的掃描,代價比較大,但一般的數(shù)據(jù)庫都有高峰期,如果我們合理安排VACUUM,這也不是很大的問題,而且在PostgreSQL9.0中VACUUM進(jìn)一步被加強(qiáng)了。
2、由于索引中完全沒有版本信息,不能實現(xiàn)Coverage index scan,即查詢只掃描索引,直接從索引中返回所需的屬性,還需要訪問表。而oracle與Innodb則可以;
進(jìn)程模式與線程模式的對比
PostgreSQL和oracle是進(jìn)程模式,MySQL是線程模式。
進(jìn)程模式對多CPU利用率比較高。
進(jìn)程模式共享數(shù)據(jù)需要用到共享內(nèi)存,而線程模式數(shù)據(jù)本身就是在進(jìn)程空間內(nèi)都是共享的,不同線程訪問只需要控制好線程之間的同步。
線程模式對資源消耗比較少。
所以MySQL能支持遠(yuǎn)比oracle多的更多的連接。
對于PostgreSQL的來說,如果不使用連接池軟件,也存在這個問題,但PostgreSQL中有優(yōu)秀的連接池軟件軟件,如pgbouncer和pgpool,所以通過連接池也可以支持很多的連接。
堆表與索引組織表的的對比
Oracle支持堆表,也支持索引組織表
PostgreSQL只支持堆表,不支持索引組織表
Innodb只支持索引組織表
索引組織表的優(yōu)勢:
表內(nèi)的數(shù)據(jù)就是按索引的方式組織,數(shù)據(jù)是有序的,如果數(shù)據(jù)都是按主鍵來訪問,那么訪問數(shù)據(jù)比較快。而堆表,按主鍵訪問數(shù)據(jù)時,是需要先按主鍵索引找到數(shù)據(jù)的物理位置。
索引組織表的劣勢:
索引組織表中上再加其它的索引時,其它的索引記錄的數(shù)據(jù)位置不再是物理位置,而是主鍵值,所以對于索引組織表來說,主鍵的值不能太大,否則占用的空間比較大。
對于索引組織表來說,如果每次在中間插入數(shù)據(jù),可能會導(dǎo)致索引分裂,索引分裂會大大降低插入的性能。所以對于使用innodb來說,我們一般最好讓主鍵是一個無意義的序列,這樣插入每次都發(fā)生在最后,以避免這個問題。
由于索引組織表是按一個索引樹,一般它訪問數(shù)據(jù)塊必須按數(shù)據(jù)塊之間的關(guān)系進(jìn)行訪問,而不是按物理塊的訪問數(shù)據(jù)的,所以當(dāng)做全表掃描時要比堆表慢很多,這可能在OLTP中不明顯,但在數(shù)據(jù)倉庫的應(yīng)用中可能是一個問題。
PostgreSQL9.0中的特色功能:
PostgreSQL中的Hot Standby功能
也就是standby在應(yīng)用日志同步時,還可以提供只讀服務(wù),這對做讀寫分離很有用。這個功能是oracle11g才有的功能。
PostgreSQL異步提交(Asynchronous Commit)的功能:
這個功能oracle中也是到oracle11g R2才有的功能。因為在很多應(yīng)用場景中,當(dāng)宕機(jī)時是允許丟失少量數(shù)據(jù)的,這個功能在這樣的場景中就特別合適。在PostgreSQL9.0中把synchronous_commit設(shè)置為false就打開了這個功能。需要注意的是,雖然設(shè)置為了異步提交,當(dāng)主機(jī)宕機(jī)時,PostgreSQL只會丟失少量數(shù)據(jù),異步提交并不會導(dǎo)致數(shù)據(jù)損壞而數(shù)據(jù)庫起不來的情況。MySQL中沒有聽說過有這個功能。
PostgreSQL中索引的特色功能:
PostgreSQL中可以有部分索引,也就是只能表中的部分?jǐn)?shù)據(jù)做索引,create index 可以帶where 條件。同時PostgreSQL中的索引可以反向掃描,所以在PostgreSQL中可以不必建專門的降序索引了。
一、 PostgreSQL 的穩(wěn)定性極強(qiáng), Innodb 等引擎在崩潰、斷電之類的災(zāi)難場景下抗打擊能力有了長足進(jìn)步,然而很多 MySQL 用戶都遇到過Server級的數(shù)據(jù)庫丟失的場景——mysql系統(tǒng)庫是MyISAM的,相比之下,PG數(shù)據(jù)庫這方面要好一些。
二、任何系統(tǒng)都有它的性能極限,在高并發(fā)讀寫,負(fù)載逼近極限下,PG的性能指標(biāo)仍可以維持雙曲線甚至對數(shù)曲線,到頂峰之后不再下降,而 MySQL 明顯出現(xiàn)一個波峰后下滑(5.5版本之后,在企業(yè)級版本中有個插件可以改善很多,不過需要付費(fèi))。
三、PG 多年來在 GIS 領(lǐng)域處于優(yōu)勢地位,因為它有豐富的幾何類型,實際上不止幾何類型,PG有大量字典、數(shù)組、bitmap 等數(shù)據(jù)類型,相比之下mysql就差很多,instagram就是因為PG的空間數(shù)據(jù)庫擴(kuò)展POSTGIS遠(yuǎn)遠(yuǎn)強(qiáng)于MYSQL的my spatial而采用PGSQL的。
四、PG 的“無鎖定”特性非常突出,甚至包括 vacuum 這樣的整理數(shù)據(jù)空間的操作,這個和PGSQL的MVCC實現(xiàn)有關(guān)系。
五、PG 的可以使用函數(shù)和條件索引,這使得PG數(shù)據(jù)庫的調(diào)優(yōu)非常靈活,mysql就沒有這個功能,條件索引在web應(yīng)用中很重要。
六、PG有極其強(qiáng)悍的 SQL 編程能力(9.x 圖靈完備,支持遞歸?。?,有非常豐富的統(tǒng)計函數(shù)和統(tǒng)計語法支持,比如分析函數(shù)(ORACLE的叫法,PG里叫window函數(shù)),還可以用多種語言來寫存儲過程,對于R的支持也很好。這一點上MYSQL就差的很遠(yuǎn),很多分析功能都不支持,騰訊內(nèi)部數(shù)據(jù)存儲主要是MYSQL,但是數(shù)據(jù)分析主要是HADOOP+PGSQL。
七、PG 的有多種集群架構(gòu)可以選擇,plproxy 可以支持語句級的鏡像或分片,slony 可以進(jìn)行字段級的同步設(shè)置,standby 可以構(gòu)建WAL文件級或流式的讀寫分離集群,同步頻率和集群策略調(diào)整方便,操作非常簡單。
八、一般關(guān)系型數(shù)據(jù)庫的字符串有限定長度8k左右,無限長 TEXT 類型的功能受限,只能作為外部大數(shù)據(jù)訪問。而 PG 的 TEXT 類型可以直接訪問,SQL語法內(nèi)置正則表達(dá)式,可以索引,還可以全文檢索,或使用xml xpath。用PG的話,文檔數(shù)據(jù)庫都可以省了。
九,對于WEB應(yīng)用來說,復(fù)制的特性很重要,mysql到現(xiàn)在也是異步復(fù)制,pgsql可以做到同步,異步,半同步復(fù)制。還有mysql的同步是基于binlog復(fù)制,類似oracle golden gate,是基于stream的復(fù)制,做到同步很困難,這種方式更加適合異地復(fù)制,pgsql的復(fù)制基于wal,可以做到同步復(fù)制。同時,pgsql還提供stream復(fù)制。
十,pgsql對于numa架構(gòu)的支持比mysql強(qiáng)一些,比MYSQL對于讀的性能更好一些,pgsql提交可以完全異步,而mysql的內(nèi)存表不夠?qū)嵱茫ㄒ驗楸礞i的原因)
最后說一下我感覺 PG 不如 MySQL 的地方。
第一,MySQL有一些實用的運(yùn)維支持,如 slow-query.log ,這個pg肯定可以定制出來,但是如果可以配置使用就更好了。
第二是mysql的innodb引擎,可以充分優(yōu)化利用系統(tǒng)所有內(nèi)存,超大內(nèi)存下PG對內(nèi)存使用的不那么充分,
第三點,MySQL的復(fù)制可以用多級從庫,但是在9.2之前,PGSQL不能用從庫帶從庫。
第四點,從測試結(jié)果上看,mysql 5.5的性能提升很大,單機(jī)性能強(qiáng)于pgsql,5.6應(yīng)該會強(qiáng)更多.
第五點,對于web應(yīng)用來說,mysql 5.6 的內(nèi)置MC API功能很好用,PGSQL差一些。
另外一些:
pgsql和mysql都是背后有商業(yè)公司,而且都不是一個公司。大部分開發(fā)者,都是拿工資的。
說mysql的執(zhí)行速度比pgsql快很多是不對的,速度接近,而且很多時候取決于你的配置。
對于存儲過程,函數(shù),視圖之類的功能,現(xiàn)在兩個數(shù)據(jù)庫都可以支持了。
另外多線程架構(gòu)和多進(jìn)程架構(gòu)之間沒有絕對的好壞,oracle在unix上是多進(jìn)程架構(gòu),在windows上是多線程架構(gòu)。
很多pg應(yīng)用也是24/7的應(yīng)用,比如skype. 最近幾個版本VACUUM基本不影響PGSQL 運(yùn)行,8.0之后的PGSQL不需要cygwin就可以在windows上運(yùn)行。
至于說對于事務(wù)的支持,mysql和pgsql都沒有問題。
查看回滾段名稱及大小 select segment_name, tablespace_name, r.status, (initial_extent/1024) InitialExtent,(next_extent/1024) NextExtent, max_extents, v.curext CurExtent From dba_rollback_segs r, v$rollstat v Where r.segment_id =