Oracle数据库问题总结(部分转自网络)

1.Oracle数据库基本类型说明
当你在数据库中创建数据表的时候,你需要定义表中所有字段的类型。ORACLE有许多种数据类型以满足你的需要。数据类型大约分为:character, number, date, LOB, 和RAW等类型。虽然ORACLE8i也允许你自定义数据类型,但是它们是最基本的数据类型。在下面的文章中你将了解到他们在oracle 中的用法、限制以及允许值。

l Character 数据类型

Character 数据类型用来存储字母数字型数据。当你在oracle 中定义一个character 数据时,通常需要制定字段的长度,它是该字段的最大长度。ORACLE提供以下几种character 数据类型:

CHAR(<size>) CHAR数据类型是一种有固定长度和最大长度的字符串。存储在数据类型为CHAR字段中的数据将以空格的形式补到最大长度。长度定义在1——2000字节之间。

当你创建一个CHAR型字段,数据库将保证在这个字段中的所有数据是定义长度,如果某个数据比定义长度短,那么将用空格在数据的右边补到定义长度。如果长度大于定义长度将会触发错误信息。

VARCHAR(<size>) varchar型数据是varchar2型数据的快照。

VARCHAR2(<size>) varchar2数据类型是一种可变长度的、有最大长度的字母数字型数据。Varchar2类型的字段长度可以达到4000字节,Varchar2类型的变量长度可以达到32676字节。

一个空的varchar2(2000)字段和一个空的varchar2(2)字段所占用的空间是一样的。

NCHAR(<size>) 和 NVARCHAR2(<size>) NCHAR(<size>) 和 NVARCHAR2(<size>)数据类型分别与CHAR(<size>) 和 VARCHAR2(<size>)类型是相同的,只不过它们用来存储NLS(National Language Support)数据。

LONG LONG 数据类型是一个遗留下来的而且在将来不会被支持的数据类型。它将被LOB(Large Object)数据类型所代替。

比较规则 Varchar2和char数据类型根据尾部的空格有不同的比较规则。对Char型数据,尾部的空格将被忽略掉,对于Varchar2型数据尾部带空格的数据排序比没有空格的要大些。比如:

Char 型数据: ‘YO’=‘YO ’

Varchar2型数据: ‘YO’<’YO ’

l Numberic 数据类型

Numberic 数据类型用来存储负的和正的整数、分数和浮点型数据,范围在-1*10-103 和9.999…99*10125之间,有38位的精确度。标识一个数据超出这个范围时就会出错。

Number(<p>,<s>) Number数据类型存储一个有p位精确度的s位等级的数据。

l DATE 数据类型

DATE 数据类型用来存储日期和时间格式的数据。这种格式可以转换为其他格式的数据去浏览,而且它有专门的函数和属性用来控制和计算。以下的几种信息都包含在DATE数据类型中:

Ø Century

Ø Year

Ø Month

Ø Day

Ø Hour

Ø Minute

Ø Second

LOB 数据类型

LOB(Large Object) 数据类型存储非结构化数据,比如二进制文件,图形文件,或其他外部文件。LOB 可以存储到4G字节大小。数据可以存储到数据库中也可以存储到外部数据文件中。LOB数据的控制通过DBMS_LOB 包实现。BLOB, NCLOB, 和CLOB 数据可以存储到不同的表空间中,BFILE存储在服务器上的外部文件中。LOB数据类型有以下几种:

Ø BLOB: 二进制数据

Ø CLOB: 字符型数据

Ø BFILE: 二进制文件

其他数据类型

ROWID ROWID 数据类型是ORACLE数据表中的一个伪列,它是数据表中每行数据内在的唯一的标识。


2. 使用SQL Developer问题汇总
1.问题

   Status: Failure -com.mysql.jdbc.Driver
或者
   Status: Failure -Unable to find driver: com.mysql.jdbc.Driver


解决办法
下载MYSQL驱动jar文件如
   mysql-connector-java-5.1.5-bin.jar
放入
... sqldeveloper\sqldeveloper\extensions文件夹下

然后进入sqldeveloper -> Tools -> Preferences
   Database -> Third Party JDBC Drivers
选中Add Entry" 后 选择 mysql-connector-java-5.1.5-bin.jar


3. 使用Oracle翻页问题
不同与MYSQL,Oracle中不支持limit功能,翻页的话有如下两种配置方法:
分页查询格式:

SELECT * FROM
(
SELECT A.*, ROWNUM RN
FROM (SELECT * FROM TABLE_NAME) A
WHERE ROWNUM <= 40
)
WHERE RN >= 21

其中最内层的查询SELECT * FROM TABLE_NAME表示不进行翻页的原始查询语句。ROWNUM <= 40和RN >= 21控制分页查询的每页的范围。

上面给出的这个分页查询语句,在大多数情况拥有较高的效率。分页的目的就是控制输出结果集大小,将结果尽快的返回。在上面的分页查询语句中,这种考虑主要体现在WHERE ROWNUM <= 40这句上。

选择第21到40条记录存在两种方法,一种是上面例子中展示的在查询的第二层通过ROWNUM <= 40来控制最大值,在查询的最外层控制最小值。而另一种方式是去掉查询第二层的WHERE ROWNUM <= 40语句,在查询的最外层控制分页的最小值和最大值。这是,查询语句如下:

SELECT * FROM
(
SELECT A.*, ROWNUM RN
FROM (SELECT * FROM TABLE_NAME) A
)
WHERE RN BETWEEN 21 AND 40

对比这两种写法,绝大多数的情况下,第一个查询的效率比第二个高得多。

这是由于CBO优化模式下,Oracle可以将外层的查询条件推到内层查询中,以提高内层查询的执行效率。对于第一个查询语句,第二层的查询条件WHERE ROWNUM <= 40就可以被Oracle推入到内层查询中,这样Oracle查询的结果一旦超过了ROWNUM限制条件,就终止查询将结果返回了。

而第二个查询语句,由于查询条件BETWEEN 21 AND 40是存在于查询的第三层,而Oracle无法将第三层的查询条件推到最内层(即使推到最内层也没有意义,因为最内层查询不知道RN代表什么)。因此,对于第二个查询语句,Oracle最内层返回给中间层的是所有满足条件的数据,而中间层返回给最外层的也是所有数据。数据的过滤在最外层完成,显然这个效率要比第一个查询低得多。

上面分析的查询不仅仅是针对单表的简单查询,对于最内层查询是复杂的多表联合查询或最内层查询包含排序的情况一样有效。

这里就不对包含排序的查询进行说明了,下一篇文章会通过例子来详细说明。下面简单讨论一下多表联合的情况。对于最常见的等值表连接查询,CBO一般可能会采用两种连接方式NESTED LOOP和HASH JOIN(MERGE JOIN效率比HASH JOIN效率低,一般CBO不会考虑)。在这里,由于使用了分页,因此指定了一个返回的最大记录数,NESTED LOOP在返回记录数超过最大值时可以马上停止并将结果返回给中间层,而HASH JOIN必须处理完所有结果集(MERGE JOIN也是)。那么在大部分的情况下,对于分页查询选择NESTED LOOP作为查询的连接方法具有较高的效率(分页查询的时候绝大部分的情况是查询前几页的数据,越靠后面的页数访问几率越小)。

因此,如果不介意在系统中使用HINT的话,可以将分页的查询语句改写为:

SELECT /*+ FIRST_ROWS */ * FROM
(
SELECT A.*, ROWNUM RN
FROM (SELECT * FROM TABLE_NAME) A
WHERE ROWNUM <= 40
)
WHERE RN >= 21

4. Oracle保留字问题
在MYSQL中一个表中某些列可以和数据库中保留字,函数名相同,如一个名为concat的列名是合法的,查询和插入时按正常语法操作也不会有问题,MYSQL会自动识别
在Oracle中最好采取与数据库系统保留字不同的列名,否则会遇到很多问题,如:在对该列插入数据时如果不用引号将列名包起来会报错,查询是如果查询条件中无法使用这个列作为判断条件等。
5. Oracle,MYSQL迁移时数据类型问题
当前系统迁移过程中主要面临的问题是MYSQL中TEXT类型映射到Oracle中问题,现在主要有三种,主要是VARCHAR2, CLOB, BLOB。三种各有特点。
VARCHAR2 在现有系统中操作起来最为方便,现有系统操作数据表字符串类型的方法都不需要改变,可以直接获取String类型数据。主要缺点是现有的数据库迁移工具不支持将TEXT迁移到Oracle的该字段,如果需要用到VARCHAR2必须手动修改数据库,导入现有数据也是一个问题
BLOB特点是现有数据库迁移工具直接可以将TEXT数据结构包括数据内容迁移到Oracle中,转换十分方便,主要缺点是采用BLOB类型的数据入库端和查询端都比较麻烦,需要将二进制流转换到String,采用这种方式现有系统将面临大范围修改
CLOB介于前面两个类型之间,入库端和查询端操作没有BLOB麻烦,但是还是没有VARCHAR2 方便,需要稍作处理,并且现有转换工具也不支持将TEXT直接转换成CLOB。


6. Oracle中Varchar2中char与byte的区别
SQL> create table test(name varchar(5 byte),namec varchar(5 char));
表已创建。

-----------------------byte测试------------------------------------

SQL> insert into test(name) values('12345');
已创建 1 行。

SQL> insert into test(name) values('123456');
insert into test(name) values('123456')
第 1 行出现错误:
ORA-12899: 列 "SCOTT"."TEST"."NAME" 的值太大 (实际值: 6, 最大值: 5)

SQL> insert into test(name) values('天津');
已创建 1 行。

SQL> insert into test(name) values('天津市');
insert into test(name) values('天津市')
第 1 行出现错误:
ORA-12899: 列 "SCOTT"."TEST"."NAME" 的值太大 (实际值: 6, 最大值: 5)

-----------------------char测试------------------------------------

SQL> insert into test(namec) values('12345');
已创建 1 行。

SQL> insert into test(namec) values('123456');
insert into test(namec) values('123456')
第 1 行出现错误:
ORA-12899: 列 "SCOTT"."TEST"."NAMEC" 的值太大 (实际值: 6, 最大值: 5)

SQL> insert into test(namec) values('天津');
已创建 1 行。

SQL> insert into test(namec) values('天津市');
已创建 1 行。

SQL> insert into test(namec) values('天津市北京');
已创建 1 行。

SQL> insert into test(namec) values('天津市北京市');
insert into test(namec) values('天津市北京市')
第 1 行出现错误:
ORA-12899: 列 "SCOTT"."TEST"."NAMEC" 的值太大 (实际值: 6, 最大值: 5)

-------------------------结果------------------------------------
SQL> select * from test;
NAME  NAMEC
----- ----------
12345
天津
             12345
             天津
             天津市
             天津市北京
已选择6行。


-------------------------分析------------------------------------
由于一个汉字在我的GBK系统里占用2个字节,所以byte的只能插入2个汉字,而char的可以插入5个汉字。
所以byte 就是字节数,对于汉字,GBK占用2个字节,如果是UTF-8则占用3个字节。
为了充分利用4000个的上限,给自己减少麻烦,建议存储含有中文文字的字段时,采用char类型。

7. Oracle嵌套查询
不同于Mysql,在Oracle中执行如下的查询是错误的:
Select  * from (select cola, colb from tableB ) A
正确的做法是:
Select  * from (select * from tableB ) A
或是
Select  cola, colb  from (select cola, colb from tableB ) A


8. 附录: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中,临时表是在单个会话内创建并销毁的.

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).

你可能感兴趣的:(数据结构,oracle,sql,mysql,网络应用)