从 Mysql 迁移到Oracle前需要了解的50件事
英文原文:Taking a Stab at "50" Things to Know Before Migrating MySQL to Oracle
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 BEFOREAFTER,也就是不支持自己制定字段的位置.(我们这边之前有部分应用对字段顺序有严格地要求,不过,从理论上讲,这是业务设计的问题,主要是其大部分情况下都是使用 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).