Oracle
Oracle 能在所有主流平台上运行(包括Windows)。完全支持所有的工业标准。采用完全开放策略。可以使客户选择最适合的解决方案。如果Windows NT不能满足需要,用户可以把数据库移到UNIX中。Oracle的并行服务器对各种UNIX平台的集群机制都有着相当高的集成度。
Oracle 在兼容性、可移植性、可联结性、高生产率上、开放性也存在优点。
Oracle的产品可运行于很宽范围的硬件与操作系统平台上。可以安装在70种以上 不同的大、中、小型机上;可在VMS、DOS、UNIX、WINDOWS等多种操作系统下工作。能与多种通讯网络相连,支持各种协议(TCP/IP、 DECnet、LU6.2等)。Oracle良好的兼容性、可移植性、可连接性和高生产率是 Oracle RDBMS具有良好的开放性。
Oracle价格是比较昂贵的。据说一套正版的Oracle软件早在2006年年底的时候在市场上的价格已经达到了6位数。所以如果你的项目不是那种超级大的项目,还是放弃Oracle吧。
SQL Server
SQL Server 是 Microsoft推出一套产品,它具有使用方便、可伸缩性好、与相关软件集成程度高等优点,逐渐成为Windows平台下进行数据库应用开发较为理想的 选择之一。
SQLServer是目前流行的数据库之一,它已广泛应用于金融、保险、电力、行政管理等与数据库有关的行业。而且,由于其易操作性及友好的界 面,赢得了广大用户的青睐,尤其是SQLServer与其它数据库,如Access、FoxPro、Excel等有良好的ODBC接口,可以把上述数据库 转成SQLServer的数据库,因此目前越来越多的读者正在使用SQLServer。
SQL Server由于是微软的产品,又有着如此强大的功能,所以他的影响力是几种数据库系统中比较大,用户也是比较多的。它一般是和同是微软产品的.net平台一起搭配使用。当然其他的各种开发平台,都提供了与它相关的数据库连接方式。因此,开发软件用SQL Server做数据库是一个正确的选择。
MySQL
MySQL不支持事务处理(文章尾部有介绍mysql的事务处理),没有视图,没有存储过程和触发器,没有数据库端的用户自定义函数,不能完全使用标准的SQL语法。
从数据库行家听说的第一件事就是MySQL缺乏transactions,rollbacks, 和subselects的功能。如果你计划使用MySQL写一个关于银行、会计的应用程序,或者计划维护一些随时需要线性递增的不同类的计数器,你将缺乏transactions功能。在现有的发布版本的 MySQL下,请不要有任何的这些想法。(请注意,MySQL的测试版3.23.x系列现在已经支持transactions了)。
MySQL没法处理复杂的关联性数据库功能,例如,子查询(subqueries),虽然大多数的子查询都可以改写成join 。另一个MySQL没有提供支持的功能是事务处理(transaction)以及事务的提交(commit)/撤销(rollback)。
一个事务指的是被当作一个单位来共同执行的一群或一套命令。如果一个事务没法完成,那么整个事务里面没有一个指令是真正执行下去的。对于必须处理线上订单的商业网站来说,MySQL没有支持这项功能,的确让人觉得很失望。但是可以用MaxSQL,一个分开的服务器,它能通过外挂的表格来支持事务功能。
外键(foreignkey)以及参考完整性限制(referentialintegrity)可以让你制定表格中资料间的约束,然后将约束 (constraint)加到你所规定的资料里面。这些MySQL没有的功能表示一个有赖复杂的资料关系的应用程序并不适合使用MySQL。
总体总结如下:
一、Oracle:最贵,功能最多,安装最不方便,Oracle环境里的其他相关组件最多,支持平台数据量一般,使用中等方便,开发中等方便,不开源,速度最慢、最安全。
二、Microsoft SQL Server:中等贵,功能最少,安装中等方便,sqlserver环境里的其他相关组件最少,支持平台最少,使用最方便,开发最方便,运维最方便,不开源,速度中等,一般安全
三、Mysql:免费,功能中等,安装最方便,mysql环境里的其他相关组件数量中等,支持平台最多,使用最不方便,开发最不方便,运维最不方便,有开源版本,速度最快,最不安全。
操作上的区别
自动增长的数据类型处理
MySQL有自动增长的数据类型,插入记录时不用操作此字段,会自动获得数据值。Oracle没有自动增长的数据类型,需要建立一个自动增长的序列号,插入记录时要把序列号的下一个值赋于此字段。
CREATE SEQUENCE 序列号的名称(表名+序列号标记)INCREMENT BY 1 START WITH 1 MAXVALUE 99 CYCLE NOCACHE;
其中最大的值按字段的长度来定,如果定义的自动增长的序列号NUMBER(6),最大值为99
INSERT语句插入这个字段值为:序列号的名称.NEXTVAL
单引号的处理
MySQL里可以用双引号包起字符串,Oracle里只可以用单引号包起字符串。在插入和修改字符串前必须做单引号的替换:把所有出现的一个单引号替换成两个单引号。
翻页的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;
长字符串的处理
长字符串的处理Oracle也有它特殊的地方。INSERT和UPDATE时最大可操作的字符串长度小于等于4000个单字节,如果要插入更长的字符串,请考虑字段用CLOB类型,方法借用Oracle里自带的DBMS_LOB程序包。插入修改记录前一定要做进行非空和长度判断,不能为空的字段值和超出长度字段值都应该提出警告,返回上次操作。
字符串的模糊比较
MySQL里用字段名like%‘字符串%’,Oracle里也可以用字段名like%'字符串%'但这种方法不能使用索引,速度不快,用字符串比较函数instr(字段名,‘字符串’)>0会得到更精确的查找结果。
程序和函数里,操作数据库的工作完成后请注意结果集和指针的释放。
主键
MySQL一般使用自动增长类型,在创建表时只要指定表的主键为auto increment,插入记录时,不需要再指定该记录的主键值,MySQL将自动增长;Oracle没有自动增长类型,主键一般使用的序列,插入记录时将序列号的下一个值付给该字段即可;只是ORM框架是只要是native主键生成策略即可。
Oracle实现了ANSIISQL中大部分功能,如,事务的隔离级别、传播特性等而MySQL在这方面还是比较的弱
字符串拼接
Sqlserver | + |
Mysql | concat() |
Oracle | || |
空值处理数
Sqlserver | isnull() |
Mysql | ifnull() 注意:mysql也有isnull()函数,但意义不一样 select a.mobile,isnull(a.mobile) ,ifnull(a. mobile,'空') from ud_connect_new a; |
Oracle | Nvl() |
获取系统时间
Sqlserver | getdate() |
Mysql | now() |
Oracle | sysdate |
日期格式化(以常用的yyyymmdd格式为例)
Sqlserver | convert(varchar(8),getdate(),112) |
Mysql | date_format(xcs_received_date,'%Y%m%d') |
Oracle | to_char(sysdate,'yyyymmdd') |
检查是否有表再删除
Sqlserver | IF OBJECT_ID('xxx') IS NOT NULL 需要用到系统表(dbo.sysobjects )来判断 |
Mysql | drop table if exists tablename |
Oracle | select count(1) from user_tables where table_name = 'xxx' |
查询部分记录
Sqlserver | top关键字 |
Mysql | limit |
Oracle | 不支持mysql中limit功能,但可以通过rownum来限制返回的结果集的行数 |
Rollup()
Sqlserver | group by with rollup(xx) order by xx desc |
Mysql | group by with rollup(xx) --mysql这边不能带order by 语句 |
Oracle | group by rollup(xx) --区别于sqlserver及mysql没有with |
定义变量
Sqlserver | Begin
DECLARE @count int SET @count=123 Select @count
end |
Mysql | set @num1=(select max(rank) From tmp_ud_test where is_member=1)/3; set @num2=(select max(rank) From tmp_ud_test where is_member=1)/3*2; set @num3=(select max(rank) From tmp_ud_test where is_member=1)/3*3;
update tmp_ud_test a set type= case when a.rank<=@num1 then 1 when @num1<a.rank and a.rank<=@num2 then 2 when @num2<a.rank and a.rank<=@num3 then 3 end where a.is_member=1; |
Oracle | declare count number := 20; currtime date := sysdate;
begin update xxx set aa= count ,bb= currtime; end; |
如何实现取每组的前几名(场景:查询出每个班级成绩最高的前三名学生,用到的表名及字段如下:)
Table:tmp_class_score
班级:class_id
成绩:score
Sqlserver | Select From (select a.*,row_number() over(partition by class_id order by score) rank from tmp_class_score a) where rank<=3 |
Mysql | select * from ( select b.*,@rownum:=@rownum+1 , if(@pdept=b.class_id,@rank:=@rank+1,@rank:=1) as rank, @pdept:=b.class_id from ( select * from tmp_class_score order by class_id, score desc ) b ,(select @rownum :=0 , @pdept := null ,@rank:=0) c ) result where rank<=3; |
Oracle | Select From (select a.*,row_number() over(partition by class_id order by score) rank from tmp_class_score a) where rank<=3; |
Sqlserver 及Mysql还有rank () OVER 用替换row_number()over 实现并列排序,就是如果一个班级最高的成绩有2个人那用这个函数,取出来的排序,这2个同学显示序号都是1,这2个同学下面的同学显示的序号就会跳过2直接为3。
Oracle对子查询的支持非常好。而Mysql中的子查询效率就非常低
提交方式
Sqlserver | 默认是自动提交 |
Mysql | mysql默认是自动提交 |
Oracle | 默认不自动提交,需要用户手动提交。Sql脚本中经常用到commit; |
sqlserver、mysql及oracle差别实在太多,这里例举的还是部分情况