特性 | MySQL | PostgreSQL |
实例 | 通过执行 MySQL 命令(mysqld)启动实例。 一个实例能够管理一个或多个数据库。一台server能够执行多个 mysqld 实例。一个实例管理器能够监视 mysqld 的各个实例。 | 通过运行 Postmaster 进程(pg_ctl)启动实例。一个实例能够管理一个或多个数据库,这些数据库组成一个集群。 集群是磁盘上的一个区域,这个区域在安装时初始化并由一个文件夹组成,全部数据都存储在这个文件夹中。使用 initdb 创建第一个数据库。一台机器上能够启动多个实例。 |
数据库 | 数据库是命名的对象集合。是与实例中的其它数据库分离的实体。一个 MySQL 实例中的全部数据库共享同一个系统编目。 | 数据库是命名的对象集合。每一个数据库是与其它数据库分离的实体。每一个数据库有自己的系统编目,可是全部数据库共享 pg_databases。 |
数据缓冲区 | 通过 innodb_buffer_pool_size 配置參数设置数据缓冲区。这个參数是内存缓冲区的字节数,InnoDB 使用这个缓冲区来缓存表的数据和索引。在专用的数据库server上。这个參数最高能够设置为机器物理内存量的 80%。 | Shared_buffers 缓存。 在默认情况下分配 64 个缓冲区。默认的块大小是 8K。能够通过设置 postgresql.conf 文件里的 shared_buffers 參数来更新缓冲区缓存。 |
数据库连接 | 客户机使用 CONNECT 或 USE 语句连接数据库。这时要指定数据库名。还能够指定用户 id 和password。使用角色管理数据库中的用户和用户组。 | 客户机使用 connect 语句连接数据库。这时要指定数据库名。还能够指定用户 id 和password。 使用角色管理数据库中的用户和用户组。 |
身份验证 | MySQL 在数据库级管理身份验证。 基本仅仅支持password认证。 | PostgreSQL 支持丰富的认证方法:信任认证、口令认证、Kerberos 认证、基于 Ident 的认证、LDAP 认证、PAM 认证 |
加密 | 能够在表级指定password来对数据进行加密。还能够使用 AES_ENCRYPT 和 AES_DECRYPT 函数对列数据进行加密和解密。能够通过 SSL 连接实现网络加密。 | 能够使用 pgcrypto 库中的函数对列进行加密/解密。能够通过 SSL 连接实现网络加密。 |
审计 | 能够对 querylog 运行 grep。 | 能够在表上使用 PL/pgSQL 触发器来进行审计。 |
查询解释 | 使用 EXPLAIN 命令查看查询的解释计划。 | 使用 EXPLAIN 命令查看查询的解释计划。 |
备份、恢复和日志 | InnoDB 使用写前(write-ahead)日志记录。支持在线和离线全然备份以及崩溃和事务恢复。须要第三方软件才干支持热备份。 | 在数据文件夹的一个子文件夹中维护写前日志。支持在线和离线全然备份以及崩溃、时间点和事务恢复。 能够支持热备份。 |
JDBC 驱动程序 | 能够从 參考资料 下载 JDBC 驱动程序。 | 能够从 參考资料 下载 JDBC 驱动程序。 |
表类型 | 取决于存储引擎。比如。NDB 存储引擎支持分区表,内存引擎支持内存表。 | 支持暂时表、常规表以及范围和列表类型的分区表。不支持哈希分区表。 因为PostgreSQL的表分区是通过表继承和规则系统完毕了,所以能够实现更复杂的分区方式。 |
索引类型 | 取决于存储引擎。MyISAM:BTREE,InnoDB:BTREE。 | 支持 B-树、哈希、R-树和 Gist 索引。 |
约束 | 支持主键、外键、惟一和非空约束。对检查约束进行解析。可是不强制实施。 | 支持主键、外键、惟一、非空和检查约束。 |
存储过程和用户定义函数 | 支持 CREATE PROCEDURE 和 CREATE FUNCTION 语句。存储过程能够用 SQL 和 C++ 编写。用户定义函数能够用 SQL、C 和 C++ 编写。 | 没有单独的存储过程,都是通过函数实现的。用户定义函数能够用 PL/pgSQL(专用的过程语言)、PL/Tcl、PL/Perl、PL/Python 、SQL 和 C 编写。 |
触发器 | 支持行前触发器、行后触发器和语句触发器。触发器语句用过程语言复合语句编写。 | 支持行前触发器、行后触发器和语句触发器,触发器过程用 C 编写。 |
系统配置文件 | my.conf | Postgresql.conf |
数据库配置 | my.conf | Postgresql.conf |
客户机连接文件 | my.conf | pg_hba.conf |
XML 支持 | 有限的 XML 支持。 | 有限的 XML 支持。 |
数据訪问和管理server | OPTIMIZE TABLE —— 回收未使用的空间并消除数据文件的碎片 myisamchk -analyze —— 更新查询优化器所使用的统计数据(MyISAM 存储引擎) mysql —— 命令行工具 MySQL Administrator —— 客户机 GUI 工具 | Vacuum —— 回收未使用的空间 Analyze —— 更新查询优化器所使用的统计数据 psql —— 命令行工具 pgAdmin —— 客户机 GUI 工具 |
并发控制 | 支持表级和行级锁。InnoDB 存储引擎支持 READ_COMMITTED、READ_UNCOMMITTED、REPEATABLE_READ 和 SERIALIZABLE。 使用 SET TRANSACTION ISOLATION LEVEL 语句在事务级设置隔离级别。 | 支持表级和行级锁。 支持的 ANSI 隔离级别是 Read Committed(默认 —— 能看到查询启动时数据库的快照)和 Serialization(与 Repeatable Read 相似 —— 仅仅能看到在事务启动之前提交的结果)。使用 SET TRANSACTION 语句在事务级设置隔离级别。使用 SET SESSION 在会话级进行设置。 |
MySQL相对于PostgreSQL的劣势:
MySQL | PostgreSQL |
最重要的引擎InnoDB非常早就由Oracle公司控制。眼下整个MySQL数据库都由Oracle控制。 | BSD协议,没有被大公司垄断。 |
对复杂查询的处理较弱。查询优化器不够成熟 | 非常强大的查询优化器,支持非常复杂的查询处理。 |
仅仅有一种表连接类型:嵌套循环连接(nested-loop),不支持排序-合并连接(sort-merge join)与散列连接(hash join)。 | 都支持 |
性能优化工具与度量信息不足 | 提供了一些性能视图。能够方便的看到发生在一个表和索引上的select、delete、update、insert统计信息,也能够看到cache命中率。网上有一个开源的pgstatspack工具。 |
InnoDB的表和索引都是按同样的方式存储。也就是说表都是索引组织表。 这一般要求主键不能太长并且插入时的主键最好是按顺序递增,否则对性能有非常大影响。 | 不存在这个问题。 |
大部分查询仅仅能使用表上的单一索引;在某些情况下,会存在使用多个索引的查询,可是查询优化器一般会低估其成本,它们经常比表扫描还要慢。 | 不存在这个问题 |
表添加列,基本上是重建表和索引,会花非常长时间。 | 表添加列。仅仅是在数据字典中添加表定义,不会重建表 |
存储过程与触发器的功能有限。 可用来编写存储过程、触发器、计划事件以及存储函数的语言功能较弱 | 除支持pl/pgsql写存储过程,还支持perl、python、Tcl类型的存储过程:pl/perl,pl/python,pl/tcl。 也支持用C语言写存储过程。 |
不支持Sequence。 | 支持 |
不支持函数索引,仅仅能在创建基于详细列的索引。 不支持物化视图。 | 支持函数索引,同一时候还支持部分数据索引,通过规则系统能够实现物化视图的功能。 |
运行计划并非全局共享的, 只在连接内部是共享的。 | 运行计划共享 |
MySQL支持的SQL语法(ANSI SQL标准)的非常小一部分。 不支持递归查询、通用表表达式(Oracle的with 语句)或者窗体函数(分析函数)。 | 都 支持 |
不支持用户自己定义类型或域(domain) | 支持。 |
对于时间、日期、间隔等时间类型没有秒下面级别的存储类型 | 能够精确到秒下面。 |
身份验证功能是全然内置的。不支持操作系统认证、PAM认证,不支持LDAP以及其他类似的外部身份验证功能。 | 支持OS认证、Kerberos 认证 、Ident 的认证、LDAP 认证、PAM 认证 |
不支持database link。有一种叫做Federated的存储引擎能够作为一个中转将查询语句传递到远程server的一个表上,只是,它功能非常粗糙而且漏洞非常多 | 有dblink,同一时候另一个dbi-link的东西。能够连接到oracle和mysql上。 |
Mysql Cluster可能与你的想象有较大差异。开源的cluster软件较少。 复制(Replication)功能是异步的,而且有非常大的局限性.比如,它是单线程的(single-threaded),因此一个处理能力更强的Slave的恢复速度也非常难跟上处理能力相对较慢的Master. | 有丰富的开源cluster软件支持。 |
explain看运行计划的结果简单。 | explain返回丰富的信息。 |
类似于ALTER TABLE或CREATE TABLE一类的操作都是非事务性的.它们会提交未提交的事务,而且不能回滚也不能做灾难恢复 | DDL也是有事务的。 |
PostgreSQL主要优势:
1. PostgreSQL全然免费。并且是BSD协议。假设你把PostgreSQL改一改,然后再拿去卖钱,也没有人管你,这一点非常重要。这表明了PostgreSQL数据库不会被其他公司控制。
oracle数据库不用说了,是商业数据库。不开放。而MySQL数据库尽管是开源的,但如今随着SUN被oracle公司收购。如今基本上被oracle公司控制,事实上在SUN被收购之前。MySQL中最重要的InnoDB引擎也是被oracle公司控制的,而在MySQL中非常多重要的数据都是放在InnoDB引擎中的。反正我们公司都是这种。所以假设MySQL的市场范围与oracle数据库的市场范围冲突时,oracle公司必然会牺牲MySQL,这是毫无疑问的。
2. 与PostgreSQl配合的开源软件非常多,有非常多分布式集群软件,如pgpool、pgcluster、slony、plploxy等等。非常easy做读写分离、负载均衡、数据水平拆分等方案,而这在MySQL下则比較困难。
3. PostgreSQL源码写的非常清晰,易读性比MySQL强太多了,怀疑MySQL的源码被混淆过。
所以非常多公司都是基本PostgreSQL做二次开发的。
4. PostgreSQL在非常多方面都比MySQL强,如复杂SQL的运行、存储过程、触发器、索引。同一时候PostgreSQL是多进程的,而MySQL是线程的,尽管并发不高时,MySQL处理速度快,但当并发高的时候。对于如今多核的单台机器上。MySQL的整体处理性能不如PostgreSQL,原因是MySQL的线程无法充分利用CPU的能力。
眼下仅仅想到这些,以后想到再加入,欢迎大家拍砖。
PostgreSQL与oracle或InnoDB的多版本号实现的区别
PostgreSQL与oracle或InnoDB的多版本号实现最大的差别在于最新版本号和历史版本号是否分离存储,PostgreSQL不分,而oracle和InnoDB分。而innodb也仅仅是分离了数据,索引本身没有分开。
PostgreSQL的主要优势在于:
1. PostgreSQL没有回滚段,而oracle与innodb有回滚段。oracle与Innodb都有回滚段。对于oracle与Innodb来说。回滚段是很重要的。回滚段损坏,会导致数据丢失,甚至数据库无法启动的严重问题。另由于PostgreSQL没有回滚段,旧数据都是记录在原先的文件里,所以当数据库异常crash后,恢复时。不会象oracle与Innodb数据库那样进行那么复杂的恢复,由于oracle与Innodb恢复时同步须要redo和undo。所以PostgreSQL数据库在出现异常crash后。数据库起不来的几率要比oracle和mysql小一些。
2. 因为旧的数据是直接记录在数据文件里。而不是回滚段中,所以不会象oracle那样常常报ora-01555错误。
3. 回滚能够非常快完毕。由于回滚并不删除数据,而oracle与Innodb。回滚时非常复杂,在事务回滚时必须清理该事务所进行的改动,插入的记录要删除。更新的记录要更新回来(见row_undo函数),同一时候回滚的过程也会再次产生大量的redo日志。
4. WAL日志要比oracle和Innodb简单。对于oracle不仅须要记录数据文件的变化。还要记录回滚段的变化。
PostgreSQL的多版本号的主要劣势在于:
1、最新版本号和历史版本号不分离存储。导致清理老旧版本号须要作很多其它的扫描。代价比較大,但一般的数据库都有高峰期,假设我们合理安排VACUUM,这也不是非常大的问题,并且在PostgreSQL9.0中VACUUM进一步被加强了。
2、因为索引中全然没有版本号信息,不能实现Coverage index scan。即查询仅仅扫描索引,直接从索引中返回所需的属性。还须要訪问表。而oracle与Innodb则能够;
进程模式与线程模式的对照
PostgreSQL和oracle是进程模式,MySQL是线程模式。
进程模式对多CPU利用率比較高。
进程模式共享数据须要用到共享内存,而线程模式数据本身就是在进程空间内都是共享的。不同线程訪问仅仅须要控制好线程之间的同步。
线程模式对资源消耗比較少。
所以MySQL能支持远比oracle多的很多其它的连接。
对于PostgreSQL的来说,假设不使用连接池软件,也存在这个问题,但PostgreSQL中有优秀的连接池软件软件,如pgbouncer和pgpool。所以通过连接池也能够支持非常多的连接。
堆表与索引组织表的的对照
Oracle支持堆表,也支持索引组织表
PostgreSQL仅仅支持堆表,不支持索引组织表
Innodb仅仅支持索引组织表
索引组织表的优势:
表内的数据就是按索引的方式组织。数据是有序的,假设数据都是按主键来訪问。那么訪问数据比較快。
而堆表,按主键訪问数据时,是须要先按主键索引找到数据的物理位置。
索引组织表的劣势:
索引组织表中上再加其他的索引时。其他的索引记录的数据位置不再是物理位置,而是主键值,所以对于索引组织表来说,主键的值不能太大,否则占用的空间比較大。
对于索引组织表来说。假设每次在中间插入数据。可能会导致索引分裂,索引分裂会大大减少插入的性能。所以对于使用innodb来说。我们一般最好让主键是一个无意义的序列,这样插入每次都发生在最后。以避免这个问题。
因为索引组织表是按一个索引树,一般它訪问数据块必须按数据块之间的关系进行訪问,而不是按物理块的訪问数据的。所以当做全表扫描时要比堆表慢非常多,这可能在OLTP中不明显,但在数据仓库的应用中可能是一个问题。
PostgreSQL9.0中的特色功能:
PostgreSQL中的Hot Standby功能
也就是standby在应用日志同步时。还能够提供仅仅读服务。这对做读写分离非常实用。
这个功能是oracle11g才有的功能。
PostgreSQL异步提交(Asynchronous Commit)的功能:
这个功能oracle中也是到oracle11g R2才有的功能。由于在非常多应用场景中,当宕机时是同意丢失少量数据的,这个功能在这种场景中就特别合适。
在PostgreSQL9.0中把synchronous_commit设置为false就打开了这个功能。须要注意的是。尽管设置为了异步提交,当主机宕机时,PostgreSQL仅仅会丢失少量数据,异步提交并不会导致数据损坏而数据库起不来的情况。MySQL中没有听说过有这个功能。
PostgreSQL中索引的特色功能:
PostgreSQL中能够有部分索引,也就是仅仅能表中的部分数据做索引。create index 能够带where 条件。
同一时候PostgreSQL中的索引能够反向扫描。所以在PostgreSQL中能够不必建专门的降序索引了。