1 MYSQL到ORACLE程序迁移的注意事项
有很多应用项目, 刚起步的时候用MYSQL数据库基本上能实现各种功能需求,随着应用用户的增多,数据量的增加,MYSQL渐渐地出现不堪重负的情况:连接很慢甚至宕机, 于是就有把数据从MYSQL迁到ORACLE的需求,应用程序也要相应做一些修改。本人总结出以下几点注意事项,希望对大家有所帮助。1. 自动增长的数据类型处理
MYSQL有自动增长的数据类型,插入记录时不用操作此字段,会自动获得数据值。ORACLE没有自动增长的数据类型,需要建立一个自动增长的序列号,插入记录时要把序列号的下一个值赋于此字段。
CREATE SEQUENCE 序列号的名称 (最好是表名+序列号标记) INCREMENT BY 1 START WITH 1 MAXVALUE 99999 CYCLE NOCACHE;
其中最大的值按字段的长度来定, 如果定义的自动增长的序列号 NUMBER(6) , 最大值为999999
INSERT 语句插入这个字段值为: 序列号的名称.NEXTVAL
2. 单引号的处理
MYSQL里可以用双引号包起字符串,ORACLE里只可以用单引号包起字符串。在插入和修改字符串前必须做单引号的替换:把所有出现的一个单引号替换成两个单引号。
3. 翻页的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;
4. 长字符串的处理
长字符串的处理ORACLE也有它特殊的地方。INSERT和UPDATE时最大可操作的字符串长度小于等于4000个单字节, 如果要插入更长的字符串, 请考虑字段用CLOB类型,方法借用ORACLE里自带的DBMS_LOB程序包。插入修改记录前一定要做进行非空和长度判断,不能为空的字段值和超出长 度字段值都应该提出警告,返回上次操作。
5. 日期字段的处理
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;
6. 空字符的处理
MYSQL的非空字段也有空的内容,ORACLE里定义了非空字段就不容许有空的内容。按MYSQL的NOT NULL来定义ORACLE表结构, 导数据的时候会产生错误。因此导数据时要对空字符进行判断,如果为NULL或空字符,需要把它改成一个空格的字符串。
7. 字符串的模糊比较
MYSQL里用 字段名 like '%字符串%',ORACLE里也可以用 字段名 like '%字符串%' 但这种方法不能使用索引, 速度不快,用字符串比较函数 instr(字段名,'字符串')>0 会得到更精确的查找结果。
8. 程序和函数里,操作数据库的工作完成后请注意结果集和指针的释放。
转载:http://blog.csdn.net/seawavecau/article/details/1333537
2 Oracle Mysql 迁移
从Oracle迁移到Mysql之前必须知道的50件事
50 things to know before migrating Oracle to MySQLby Baron Schwartz,Translated by Jametong
1. 对子查询的优化表现不佳.
2. 对复杂查询的处理较弱
3. 查询优化器不够成熟
4. 性能优化工具与度量信息不足
5. 审计功能相对较弱
6. 安全功能不成熟,甚至可以说很粗糙.没有用户组与角色的概念,没有回收权限的功能(仅仅可以授予权限).当一个用户从不同的主机/网络以同样地用户名/密 码登录之后,可能被当作完全不同的用户来处理.没有类似于Oracle的内置的加密功能.
7. 身份验证功能是完全内置的.不支持LDAP,Active Directory以及其它类似的外部身份验证功能.
8. Mysql Cluster可能与你的想象有较大差异.
9. 存储过程与触发器的功能有限.
10. 垂直扩展性较弱.
11. 不支持MPP(大规模并行处理).
12. 支持SMP(对称多处理器),但是如果每个处理器超过4或8个核(core)时,Mysql的扩展性表现较差.
13. 对于时间、日期、间隔等时间类型没有秒以下级别的存储类型.
14. 可用来编写存储过程、触发器、计划事件以及存储函数的语言功能较弱.
15. 没有基于回滚(roll-back)的恢复功能,只有前滚(roll-forward)的恢复功能.
16. 不支持快照功能.
17. 不支持数据库链(database link).有一种叫做Federated的存储引擎可以作为一个中转将查询语句传递到远程服务器的一个表上,不过,它功能很粗糙并且漏洞很多.
18. 数据完整性检查非常薄弱,即使是基本的完整性约束,也往往不能执行。
19. 优化查询语句执行计划的优化器提示非常少.
20. 只有一种表连接类型:嵌套循环连接(nested-loop),不支持排序-合并连接(sort-merge join)与散列连接(hash join).
21. 大部分查询只能使用表上的单一索引;在某些情况下,会存在使用多个索引的查询,但是查询优化器通常会低估其成本,它们常常比表扫描还要慢.
22. 不支持位图索引(bitmap index).每种存储引擎都支持不同类型的索引.大部分存储引擎都支持B-Tree索引.
23. 管理工具较少,功能也不够成熟.
24. 没有成熟能够令人满意的IDE工具与调试程序.可能不得不在文本编辑器中编写存储过程,并且通过往表(调试日志表)中插入记录的方式来做调试.
25. 每个表都可以使用一种不同的存储引擎.
26. 每个存储引擎在行为表现、特性以及功能上都可能有很大差异.
27. 大部分存储引擎都不支持外键.
28. 默认的存储引擎(MyISAM)不支持事务,并且很容易损坏.
29. 最先进最流行的存储引擎InnoDB由Oracle拥有.
30. 有些执行计划只支持特定的存储引擎.特定类型的Count查询,在这种存储引擎中执行很快,在另外一种存储引擎中可能会很慢.
31. 执行计划并不是全局共享的,,仅仅在连接内部是共享的.
32. 全文搜索功能有限, 只适用于非事务性存储引擎. Ditto用于地理信息系统/空间类型和查询.
33. 没有资源控制.一个完全未经授权的用户可以毫不费力地耗尽服务器的所有内存并使其崩溃,或者可以耗尽所有CPU资源.
34. 没有集成商业智能(business intelligence), OLAP 多维数据集等软件包.
35. 没有与Grid Control类似的工具(http://solutions.mysql.com/go.php?id=1296&t=s)
36. 没有类似于RAC的功能.如果你问”如何使用Mysql来构造RAC”,只能说你问错了问题.
37. 不支持用户自定义类型或域(domain).
38. 每个查询支持的连接的数量最大为61.
39. MySQL支持的SQL语法(ANSI SQL标准)的很小一部分.不支持递归查询、通用表表达式(Oracle的with 语句)或者窗口函数(分析函数).支持部分类似于Merge或者类似特性的SQL语法扩展,不过相对于Oracle来讲功能非常简单.
40. 不支持功能列(基于计算或者表达式的列,Oracle11g 开始支持计算列,以及早期版本就支持虚列(rownum,rowid)).
41. 不支持函数索引,只能在创建基于具体列的索引.
42. 不支持物化视图.
43. 不同的存储引擎之间,统计信息差别很大,并且所有的存储引擎支持的统计信息都只支持简单的基数(cardinality)与一定范围内的记录数 (rows-in-a-range). 换句话说,数据分布统计信息是有限的.更新统计信息的机制也不多.
44. 没有内置的负载均衡与故障切换机制.
45. 复制(Replication)功能是异步的,并且有很大的局限性.例如,它是单线程的(single-threaded),因此一个处理能力更强的 Slave的恢复速度也很难跟上处理能力相对较慢的Master.
46. Cluster并不如想象的那么完美.或许我已经提过这一点,但是这一点值得再说一遍.
47. 数据字典(INFORMATION_SCHEMA)功能很有限,并且访问速度很慢(在繁忙的系统上还很容易发生崩溃).
48. 不支持在线的Alter Table操作.
49. 不支持Sequence.
50. 类似于ALTER TABLE或CREATE TABLE一类的操作都是非事务性的.它们会提交未提交的事务,并且不能回滚也不能做灾难恢复.Schame被保存在文件系统上,这一点与它使用的存储引 擎无关.
Mysql 迁移到Oracle前需要了解的50件事
- 1. 有些人说Oracle没有限制,实际上他们说得可能是Oracle不支持LIMIT语法.不过可以rownum虚列来实现,不过会更加麻烦.
- 2. Oracle不支持偏移(offset)语法.
- 3. Oracle的复制功能可能比MySQL更加健壮,不过也更加难以配置.
- 4. 对于多个Master类型的系统,大部分用户都希望你使用更加复杂也更加昂贵的Oracle RAC(虽然可能NDB更加健壮).
- 5. Oracle的分区功能非常健壮,但是它不是内置的,并需要专门为此付费(分区功能是在Enterprise Edition里面是内置的).
- 6. 在Linux/Unix上,Oracle并不象Mysql那么方便,很多Linux/Unix发行版默认就会自带Mysql.(我对这一点的理解与翻译可 能都有偏差)
- 7. INSERT … ON DUPLICATE KEY UPDATE语法将不再可用,不过你需要学习更加复杂(但是符合SQL标准)的MERGE语法.
- 8. Oracle的ROLE架构与MySQL有很大差异,无法再使用root角色来完整所有工作.(不过Sys用户的权限仍然与root相差无几,只是为了安 全着想,不建议这么使用了).
- 9. Role 帐户与特定的Schema联系在一起(反之也一样),类似于MySQL数据库中的Database概念.(Role并不完全与Schema联系在一起,系 统有一些固定的role,这些Role包含部分已经定义好的权限集(privilege set),也可以再自定义部分新的role).
- 10. 事实上,丢弃一切已知的关于连接访问的设置吧,Oracle使用一套全新的系统来处理连接访问.
- 11. 支持全文搜索,不过语法完全不同.
- 12. Oracle的文档非常丰富,不过,如果需要Oracle的专业服务,你需要拥有Metalink的访问权限.
- 13. 在非数据库社区很难找到相关的支持信息(例如,PHP论坛或者网站开发者的网志)
- 14. 自增功能可以通过Trigger与sequence对象来实现.
- 15. 大量日常熟悉的SHOW命令将不再可用,想要获取系统信息,需要你学习Oracle的数据字典(或信息Schema),深入一点的还需要学习Oracle 动态性能.
- 16. MySQL为信息Schema添加了多个非标准的扩展,在Oracle中将很难找到这些信息.
- 17. 为了管理好生产系统与非生产系统的的转入转出,需要你深入理解Oracle的授权规则.
- 18. 大体上讲,Oracle的数值类型更加简单,如果你确实需要类似于MySQL的多粒度的数值类型,就需要你自己来实现它,或者通过制定不同的精度 (Number(n,x))来实现.
- 19. 在Oracle中,表可以做到无限制的增长,但是大部分情况下,都建议通过表空间(tablespace)来对此作细粒度的管理.
- 20. Oracle不支持ALTER TABLE ADD COLUMN BEFORE|AFTER,也就是不支持自己制定字段的位置.(我们这边之前有部分应用对字段顺序有严格地要求,不过,从理论上讲,这是业务设计的问题, 主要是其大部分情况下都是使用select *或者insert table values来处理数据,而不是在select,insert中指定具体需要处理的字段名列表).
- 21. 如果你习惯于通过图形界面(GUI)来管理数据库,你一定会喜欢上Oracle,但是如果你倾向于使用类似与Mysql 命令行的客户端,你可能会对sql*plus这个客户端工具感到失望(需要一个习惯的过程,sql*plus还是蛮好用的).
- 22. Oracle的数据校验比Mysql更加严格,依赖于MySQL的模糊规则可能会导致应用无法运行.MySQL接受”0000-00-00″来作为日期类 型的值就是个典型的例子.
- 23. 虽然Oracle的PL/SQL功能更强,但是它不支持标准的PSM语言来编写存储过程,因此你可能不得不学习它的非标准的语法.
- 24. Oracle不支持ENUM数据类型,只能通过使用基于文本的check约束或者创建外键关联表来实现.
- 25. Mysql的一些更加神秘的表类型(例如,blackhole,csv),在Oracle中找不到相对应的功能. (不清楚blockhole是何种类型,不过Oracle的外部表(external table)确实是支持csv格式的,在11g版本中还支持对此文件的压缩/加密以及其他处理).
- 26. Oracle中的Group By语句必须是确定的,它需要select list中出现的所有列都必须包含在group by从句中.
- 27. Oracle的exp命令输出的dmp文件无法象Mysql的转储文件一样可以手工修改.
- 28. Oracle的底层实现有较大变化,需要你学习UNDO与REDO segment,归档,以及DBWR进程. (个人认为Oracle相对于其他数据库的主要的优势可能就是其UNDO/REDO的设计了.)
- 29. Oracle不是开源软件,因此你无法在上面进行修补/优化/修复/实现你自己的东西.
- 30. Oracle的查询优化是一件需要专家介入的工作.它的优化器比MySQL的要成熟的多,这意味着查询计划也相应的更加难以解释.如果你有一个大的应用, 请准备好聘用一位了解如何有效进行此项工作的伙计.
- 31. Oracle的基于成本的优化器的有效运行需要精确的统计信息.对于发生变化的表,需要定期的为其收集统计信息.批量数据加载进程也需要在处理过程中不时 的执行estimate/compute statistics命令来收集统计信息以取得满意的性能.
- 32. 在Oracle中,创建连接是个代价高昂的操作.性能良好的Oracle应用都倾向于使用连接池来最小化登陆的开销.
- 33. Oracle应用需要应用prepared statement以获取可观的性能.如果你的应用不使用prepared statement的话,需要对应用进行调整.这是应用Oracle数据库的标准编程实践.(此处的prepared statement应该更多的是指使用绑定变量).
- 34. 应用需要关闭结果集游标,否则很快就会遇到著名的”ORA-01000 Too many open cursors”错误.在Oracle中,这被认为是一个用户错误,需要你去调整你的代码.
- 35. 繁忙系统上的长查询可能会遭遇到” ORA-01555 Snapshot too old”错误.可以通过调整redo 段的大小(有时通过调整应用)来消除此错误,但是还是需要你关注这一点.(此处的redo segments的表述是有点问题,此处应该是Undo tablespace以及对应的Undo Retention,Oracle没有所谓的redo segment的说法).
- 36. Oracle没有类似于非事务表的概念.大部分Oracle用户都认可这一点.
- 37. Oracle的临时表定义是持久的SQL对象,并且对所有用户都可见(此处应该理解成以此用户登陆的会话,Session).这一点与MySQL中使用的 轻量级表有区别,在MySQL中,临时表是在单个会话内创建并销毁的.
Denish Patel
- 38. 在Oracle中,多个Alter Table操作不能在同一个SQL语句中执行,例如alter table emp modify name varchar(64) not null, add gender char(1) not null;
- 39. 默认情况下,Oracle不会自动提交.
- 40. KILL命令在Oracle中无效,它使用alter system kill命令.(不清楚第一个kill是什么概念,操作系统级别的kill,Oracle还是支持的,我经常使用).
- 41. Oracle在Order by语句中不支持使用减号(-).(不清楚这个具体的减号是什么东西).
- 42. Oracle的sqlplus命令行接口不支持高亮显示.
- 43. Oracle不支持group_concat或者类似的分组函数.需要你通过循环调取游标来实现,或者通过组合XMLAGG与XMLQUERY来实现你需 要的查询.(在Oracle 9R2之后,可以使用自定义聚合函数来实现这个功能,到Oracle 11gR1之后,Oracle自己还提供了一个新的listagg分组函数来实现这个功能).
- 44. 对于count(distinct expression)函数,Oracle只支持一个表达式(要么一个列名,要么*),而Mysql支持一组表达式. (在Oracle中要实现一组表达式,可以通过使用子查询来实现).
- 45. Oracle对子查询的支持非常好.不要因为Mysql中的习惯而不去使用它.
- 46. Oracle不支持用户变量(@num).如果你需要利用它来计算运行时总和,可以利用分析函数(窗口函数)来实现.如果用用户变量来实现特定的汇总函数 功能,你将发现Oracle已经有内置得功能支持这些功能.(另外在Oracle中,可以通过在package中应用dbms_session来设置 context以实现用户变量).
- 47. Oracle没有区分TIME与DATE类型,Oracle的Date类型实际上就是一个DATETIME类型(但是比MySQL支持一个更大的日期范 围).
- 48. 相对于MySQL来讲,Oracle的存储过程与触发器功能与性能都要好很多.不要习惯性地不去使用它们.
- 49. 如果需要在Oracle中编写存储过程,记得在开始编码前花点时间了解下Oracle是不是有相应的内置package.你将发现大部分问题已经解决掉 了,或者至少大量的基础代码已经在那儿了.
- 50 如果你在MySQL中有使用BLOB类型或者TEXT类型,你可能会将他们迁移到Oracle地BLOB与CLOB中.然而,与MySQL不 同,Oracle并不是透明地实体化这些数据.在大部分情况下,这确实是件好事情,但是它也意味着如果你只是想把BLOB/CLOB当作文本处理,你将需 要花费大量琐碎的时间来使用LOB函数,在使用之初,LOB函数还是蛮让人气馁的.(LOB相关函数确实挺烦人,LOB的处理效率也非常差,即使是使用 Oracle 11g的SecureFile).