Oracle vs MySQL
一、历史
1. Oracle:
Oracle这是一家传奇的公司,由一个传奇的大老板Larry
Ellision在1977年创办的。 Ellision
32岁还一事无成,读了三个大学,没得到一个学位文凭,换了十几家公司,老婆也离他而去。开始创业时只有1200美元,却使得Oracle公司连续12年销售额每年翻一番。oracle的理论基础,来自于一篇IBM的论文《A
Relational Model of Da
由于其诞生早、结构严谨、高可用、高性能等特点,使其在传统数据库应用中大杀四方,金融、通信、能源、运输、零售、制造等各个行业的大型公司基本都是用了Oracle,世界500强几乎100%都是Oracle的用户。
2. MySQL :MySQL称自己是最流行的开源数据库 MySQL的最初的核心思想,开源、简便易用。其开发可追溯至1985年,而第一个内部发行版本诞生,已经是1995年。到1998年,MySQL已经可以支持10种操作系统了。MySQL的爆发实际是在01、02年,尤其是02年发布的4.0
Beta版,正式选定InnoDB作为默认引擎,对事务处理能力及数据缓存能力有了极大的提高。同年4.1版开始支持子查询,至此MySQL终于蜕变成一个成熟的关系型数据库系统。05年的5.0版本又添加了存储过程、服务端游标、触发器、查询优化以及分布式事务功能,
二、典型应用场景
大型数据库应用有以下特点:海量数据、高吞吐量;复杂逻辑、高计算量,以及高可用性。
1.Oracle
Oracle的应用,主要在传统行业的数据化业务中,如:银行、金融这样的对可用性、健壮性、安全性、实时性要求极高的业务;零售、物流这样对海量数据存储分析要求很高的业务。而且由于Oracle对复杂计算、统计分析的强大支持,在互联网数据分析、数据挖掘方面的应用也越来越多。
2.MySQL
MySQL基本是生于互联网,长于互联网。
互联网的爆发成就了MySQL,LAMP架构风靡天下。MySQL安装使用简便,深受广大互联网公司的喜爱。并且由于MySQL的开源特性,针对一些对数据库有特别要求的应用,可以通过修改代码来实现定向优化。
三、架构
其实要说执行的区别,主要还是架构的区别,正是架构导致了相同SQL在执行过程中的解释、优化、效率的差异。
1.Oracle:从逻辑结构上看,它是由:表空间、段对象、区、Oralce数据库构成的集合;从物理结构上看,它是一些OS 文件构成的集合:包括:控制文件、数据文件、日志文件。由于Oracle文件管理的统一性,就可以对SQL执行过程中的解析和优化,指定统一的标准:RBO(基于规则的优化器)、CBO(基于成本的优化器)。通过优化器的选择,以及HINT规则,给予了SQL优化极大的自由,对CPU、内存、IO资源进行方方面面的优化。
2 MySQL:从逻辑上,MySQL 可以看成是二层架构,第一层我们通常叫做SQL 层,在MySQL 数据库系统处理底层数据之前的所有工作都是在这一层完成的,包括权限判断,sql 解析,执行计划优化等等; 第二层就是存储引擎层,也就是底层数据存取操作实现部分,由多种存储引擎共同组成。
存储引擎是MySQL区别于其他数据库的一个最重要特性;插件式的存储引擎。根据应用程序的不同需要,选择不同的存储引擎;对于某种引擎不满意,可以修改源代码来实现自己想要的特性。
四、并发性
并发性是OLTP 数据库最重要的特性,并发涉及到资源的获取、共享与锁定。
oracle使用行级锁,只锁定sql需要的资源,对资源锁定的粒度很小,并且加锁是在数据库中的数据行上,不依赖与索引。
mysql以表级锁为主,对资源锁定的粒度较大(如果一个session对一个表加锁时间过长,会让其他session无法更新此表中的数据)。虽然InnoDB引擎的表可以用行级锁,但这个行级锁的机制依赖于表的索引,如果表没有索引,或者sql语句没有使用索引,那么仍然使用表级锁。
五、一致性
oracle支持serializable(可串行化)的隔离级别,可以实现最高级别的读一致性。每个session提交后其他session才能看到提交的更改。oracle通过在undo表空间中构造多版本数据块来实现读一致性,
每个session查询时,如果对应的数据块发生变化,oracle会在undo表空间中为这个session构造它查询时的旧的数据块。
mysql没有类似oracle的构造多版本数据块的机制,只支持read commited的隔离级别。一个session读取数据时,其他session不能更改数据,但可以在表最后插入数据。session更新数据时,要加上排它锁,其他session无法访问数据。
六、事务
oracle很早就完全支持事务。
mysql在innodb存储引擎的行级锁的情况下才支持事务。
七、数据持久性
oracle
保证提交的数据均可恢复,因为oracle把提交的sql操作线写入了在线联机日志文件中,保持到了磁盘上,
如果出现数据库或主机异常重启,重启后oracle可以考联机在线日志恢复客户提交的数据。
mysql:
默认提交sql语句,但如果更新过程中出现db或主机重启的问题,也许会丢失数据。
八、提交方式
oracle默认不自动提交,需要用户手动提交。
mysql默认是自动提交。
九、逻辑备份
oracle逻辑备份时不锁定数据,且备份的数据是一致的。
mysql逻辑备份时要锁定数据,才能保证备份的数据是一致的,影响业务正常的DML使用。
十、热备份
oracle有成熟的热备工具rman,热备时,不影响用户使用数据库。即使备份的数据库不一致,也可以在恢复时通过归档日志和联机重做日志进行一致的回复。
mysql:
myisam的引擎,用mysql自带的mysqlhostcopy热备时,需要给表加读锁,影响dml操作。
innodb的引擎,它会备份innodb的表和索引,但是不会备份.frm文件。用ibbackup备份时,会有一个日志文件记录备份期间的数据变化,因此可以不用锁表,不影响其他用户使用数据库。但此工具是收费的。
innobackup是结合ibbackup使用的一个脚本,他会协助对.frm文件的备份。
十一、sql语句的扩展和灵活性
oracle在这方面感觉更加稳重传统一些。
mysql对sql语句有很多非常实用而方便的扩展,比如limit功能,insert可以一次插入多行数据,select某些管理数据可以不加from。
十二、复制
oracle:既有推或拉式的传统数据复制,也有dataguard的双机或多机容灾机制,主库出现问题是,可以自动切换备库到主库,但配置管理较复杂。
mysql:复制服务器配置简单,但主库出问题时,丛库有可能丢失一定的数据。且需要手工切换丛库到主库。
十三、性能诊断
oracle有各种成熟的性能诊断调优工具,能实现很多自动分析、诊断功能。比如awr、addm、sqltrace、tkproof等
mysql的诊断调优方法较少,主要有慢查询日志。
十四、权限与安全
mysql的用户与主机有关,感觉没有什么意义,另外更容易被仿冒主机及ip有可乘之机。
oracle的权限与安全概念比较传统,中规中矩。
十五、分区表和分区索引
oracle的分区表和分区索引功能很成熟,可以提高用户访问db的体验。
mysql的分区表还不太成熟稳定。
十六、管理工具
oracle有多种成熟的命令行、图形界面、web管理工具,还有很多第三方的管理工具,管理极其方便高效。
mysql管理工具较少,在linux下的管理工具的安装有时要安装额外的包(phpmyadmin, etc),有一定复杂性
十七、SQL语句语法规则
1.组函数用法规则
mysql中组函数在select语句中可以随意使用,但在oracle中如果查询语句中有组函数,那其他列名必须是组函数处理过的,或者是group by子句中的列否则报错
eg:
select name,count(money) from user;这个放在mysql中没有问题在oracle中就有问题了。
2.自动增长的数据类型处理
MYSQL有自动增长的数据类型,插入记录时不用操作此字段,会自动获得数据值。ORACLE没有自动增长的数据类型,需要建立一个自动增长的序列号,插入记录时要把序列号的下一个值赋于此字段。
CREATE SEQUENCE 序列号的名称 MINVALUE 1 MAXVALUE 100 INCREMENT BY 1 START WITH 1 NOCACHE;
其中最大的值按字段的长度来定,如果定义的自动增长的序列号NUMBER(6),最大值为999999
INSERT语句插入这个字段值为:序列号的名称.NEXTVAL
3.字符串处理
单引号的处理:MYSQL里使用单引号,可以用双引号包起字符串(用 SET sql_mode='ANSI_QUOTES';来改变当前设置)。ORACLE里只可以用单引号包起字符串。
空字符的处理 MYSQL的非空字段也有空的内容,ORACLE里定义了非空字段就不容许有空的内容。
4 Select 语句
select 1 这个在mysql不会报错的,oracle下会报错。oracle有一个dual表,select 1 from dual才不会报错的。
oracle查询时from 表名后面 不能加上as ,不然会报错的,select t.username from test as t 而在mysql下是可以的。
5.翻页的SQL语句的处理
MYSQL处理翻页的SQL语句比较简单,用LIMIT开始位置,记录个数;PHP里还可以用SEEK定位到结果集的位置。ORACLE处理翻页的SQL语句就比较繁琐了。每个结果集只有一个ROWNUM字段标明它的位置,并且只能用ROWNUM<100,不能用ROWNUM>80。
以下是经过分析后较好的两种ORACLE翻页SQL语句(ID是唯一关键字的字段名):
语句一:
SELECT ID, [FIELD_NAME,...] FROM TABLE_NAME WHERE ID IN ( SELECT ID FROM (SELECT ROWNUM AS NUMROW, ID FROM TABLE_NAME WHERE 条件1 ORDER BY 条件2) WHERE NUMROW > 80 AND NUMROW < 100 ) ORDER BY 条件3;
语句二:
SELECT * FROM (( SELECT ROWNUM AS NUMROW, c.* from (select [FIELD_NAME,...] FROM TABLE_NAME WHERE 条件1 ORDER BY 条件2) c) WHERE NUMROW > 80 AND NUMROW < 100 ) ORDER BY 条件3;
6.长字符串的处理
长字符串的处理ORACLE也有它特殊的地方。INSERT和UPDATE时最大可操作的字符串长度小于等于4000个单字节,如果要插入更长的字符串,请考虑字段用CLOB类型,方法借用ORACLE里自带的DBMS_LOB程序包。插入修改记录前一定要做进行非空和长度判断,不能为空的字段值和超出长度字段值都应该提出警告,返回上次操作。
6.日期字段的处理
MYSQL日期字段分DATE和TIME两种,ORACLE日期字段只有DATE,包含年月日时分秒信息,用当前数据库的系统时间为SYSDATE,精确到秒,或者用字符串转换成日期型函数TO_DATE(‘2001-08-01’,’YYYY-MM-DD’)年-月-日24小时:分钟:秒的格式YYYY-MM-DD HH24:MI:SS TO_DATE()还有很多种日期格式,可以参看ORACLE DOC.日期型字段转换成字符串函数TO_CHAR(‘2001-08-01’,’YYYY-MM-DD
HH24:MI:SS’)
日期字段的数学运算公式有很大的不同。MYSQL找到离当前时间7天用DATE_FIELD_NAME > SUBDATE(NOW(),INTERVAL 7 DAY)ORACLE找到离当前时间7天用 DATE_FIELD_NAME >SYSDATE - 7;
MYSQL中插入当前时间的几个函数是:NOW()函数以`'YYYY-MM-DD HH:MM:SS'返回当前的日期时间,可以直接存到DATETIME字段中。CURDATE()以’YYYY-MM-DD’的格式返回今天的日期,可以直接存到DATE字段中。CURTIME()以’HH:MM:SS’的格式返回当前的时间,可以直接存到TIME字段中。例:insert into tablename (fieldname) values (now())
而oracle中当前时间是sysdate
7.字符串的模糊比较
MYSQL里用字段名like%‘字符串%’,ORACLE里也可以用字段名like%‘字符串%’但这种方法不能使用索引,速度不快,用字符串比较函数instr(字段名,‘字符串’)>0会得到更精确的查找结果。