Successfully reported this slideshow.

Oracle 数据类型

2,523 views

Published on

Oracle 数据类型分享

Published in: Technology, News & Politics
  • Be the first to comment

Oracle 数据类型

  1. 1. Oracle 数据类型<br />叶正盛<br />Alibaba-inc<br />2010-05<br />http://blog.csdn.net/yzsind<br />
  2. 2. 主题<br />数值型(NUMBER)<br />字符型(STRING)<br />日期型(DATETIME)<br />大字段(LOB)<br />
  3. 3. 数值型<br />NUMBER(p,s)<br />p:整数位数+小数位数 取值范围: 1-38<br />s:小数位数取值范围:-47-127<br />Number(6,2)表示总位数为6位,整数最大可以是4位,存储的小数为2位,小数超过2位会自动四舍五入<br />Number(6,-2) ???<br />Number(1,-2) ??? 949,950<br />DATA_LENGTH===22 ???<br />
  4. 4. Number存储结构<br />实际用1-21个字节存储,具体的长度与数值有关系<br />0用1个字节(0x80)存储,<br />1用2个字节(0xC1,0x02)存储,<br />-1用了3个字节(0x3E,0x64,0x66)存储。<br />SQL> select dump(123456789,16) from dual;<br />DUMP(123456789,16)<br />-----------------------------<br />Typ=2 Len=6: c5,2,18,2e,44,5a<br />
  5. 5. unDumpNumber<br /> if Bytes(0) = 128 then --128表示0<br /> result := 0;<br />elsif Bytes(0) > 128 then --大于128表示正数<br />for i in 1 .. vlength - 1 loop<br /> result := result +<br /> (Bytes(i) - 1) * power(100, (Bytes(0) - 193) - i+1);<br /> end loop;<br /> else --小于128表示负数<br />for i in 1 .. vlength - 2 loop --负数的最后一个字节总是102,所以可以忽略<br />result := result +<br /> (Bytes(i) - 101) * power(100, (62 - Bytes(0)) - i+1);<br /> end loop;<br /> end if;<br /> return(Result);<br />
  6. 6. 新数值类型(10g)<br />BINARY_FLOAT <br />单精度浮点型数据,内部采用4字节存储<br />BINARY_DOUBLE<br />双精度浮点型数据,内部采用8字节存储<br />牺牲精度,提高性能<br />
  7. 7. 性能测试结果Number VS Binary_Float<br />insert into t(c_number,c_float) select rownum/100,rownum/100 from dual connect by rownum<1000000<br />
  8. 8. 同义词<br />NUMERIC(p,s):完全映射至NUMBER(p,s)<br />DECIMAL(p,s)或DEC(p,s):完全映射至NUMBER(p,s)<br />INTEGER 或INT,SMALLINT:完全映射至NUMBER类型,但是小数位精度为0。<br />FLOAT(p):映射至NUMBER(p) 类型,但小数位精度不限制。<br />DOUBLE PRECISION:相当于FLOAT(126),映射至NUMBER 类型。<br />REAL:相当于FLOAT(63)映射至NUMBER 类型。<br />
  9. 9. 字符型<br />CHAR<br />VARCHAR2<br />NCHAR<br />NVARCHAR2<br />
  10. 10. 常见字符集<br />ASCII<br />ANSI(GB2312,BIG5,JIS,GBK)<br />GB2312---------7445字符<br />GBK--------21886字符<br />GB18030------------27484字符<br />CJK,CJKV<br />UNICODE(UCS-2,UTF8,UTF16)<br />ISO-8891-XX<br />Latin-XX<br />
  11. 11. ORACLE字符集<br />数据库字符集<br />Oracle数据库最早支持的编码方案是US7ASCII<br />Oracle的字符集命名遵循以下命名规则:<br /> <Language><bit size><encoding><br />即: <语言><比特位数><编码><br />比如: <br /> ZHS16GBK表示采用GBK编码格式,16位<br />ZHS16DBCS表示CJK编码格式,16位<br />WE8ISO8859P1表示ISO-8859-1编码格式,8位<br />国家字符集<br />用以存储NCHAR, NVARCHAR2, NCLOB等类型数据<br />只能在unicode编码中的AF16UTF16和UTF8中选择,默认值是AF16UTF16<br />
  12. 12. 常用字符类型<br />CHAR(n [BYTE | CHAR]) 1-2000<br />VARCHAR2(n [BYTE | CHAR]) 1-4000<br />NCHAR(n) 1-2000,默认为1<br />NVARCHAR2(n) 1-4000<br />VARCHAR是VARCHAR2的同意词,主要是兼容作用<br />
  13. 13. 状态类型<br />CHAR(1)<br />VARCHAR2(1)<br />NUMBER(1)<br />两者存储的空间和性能在ORACLE完全一样,所以没什么区别,Thomas Kate说CHAR/NCHAR 实际上只是伪装的VARCHAR2/NVARCHAR2,所以个人认为VARCHAR2(1)可以完全代替CHAR(1)使用<br />
  14. 14. Varchar2 VS Number<br />
  15. 15. 随机字符串<br />dbms_random.string函数<br />以下是dbms_random.string函数生成随机的字符型数据类型<br />-- 'u', 'U' - 返回全是大写的字符串 <br />-- 'l', 'L' - 返回全是小写的字符串 <br />-- 'a', 'A' - 返回大小写结合的字符串 <br />-- 'x', 'X' - 返回全是大写和数字的字符串 <br />-- 'p', 'P' - 返回键盘上出现字符的随机组合 <br />
  16. 16. 字符串函数<br />SUBSTR(‘abcdeft’,-3,2)<br />TRIM(‘001234560’,’01’)<br />如何将一串数字转换为对应的汉字?<br />‘34234298’ to ’三四二三四二九八’<br />Translate<br />Select Translate(‘3430387664’,‘1234567890’,’一二三四五六七八九零’) from dual;<br />
  17. 17. 日期型<br />DATE<br />公元前4712年1月1日至公元9999年12月31日<br />TIMESTAMP<br />保存小数秒,小数位数可以指定为0-9,默认为6位<br />
  18. 18. Date内部存储<br />'2010-2-12 10:20:30‘<br />Typ=12 Len=7: 120,110,2,12,11,21,31<br /> 第1字节:世纪+100<br />第2字节:年+100<br />第3字节:月<br /> 第4字节:天<br /> 第5字节:小时+1<br />第6字节:分+1<br />第7字节:秒+1<br />
  19. 19. Timestamp内部存储<br />'2010-2-12 13:24:52.123456‘<br />Typ=180 Len=11: 120,110,2,12,14,25,53,7,91,202,0<br />第1字节:世纪+100<br />第2字节:年+100<br />第3字节:月<br /> 第4字节:天<br /> 第5字节:小时+1<br />第6字节:分+1<br />第7字节:秒+1<br />第8-11字节:纳秒,采用4个字节存储,内部运算类型为整形<br />
  20. 20. TO_CHAR日期转换<br />YYYY-MM-DD HH24:MI:SS<br />如何得到今天是本年的第几天?<br />TO_CHAR(date,’DDD’)<br />TO_CHAR(date,’MM’) <br />EXTRACT(date,’MONTH’)<br />
  21. 21. 求下个月的今天时间?<br />Sysdate+30?<br />Sysdate+31?<br />Sysdate+NUMTOYMINTERVAL(1, 'month')<br />ADD_MONTHS(Sysdate,1)<br />
  22. 22. ADD_MONTHS<br />ADD_MONTHS(date '2010-2-12', 1)<br />ADD_MONTHS(date '2010-2-27', 1)<br />ADD_MONTHS(date '2010-2-28', 1)<br />ADD_MONTHS(date '2010-1-31', 1)<br />
  23. 23. LOB<br />CLOB(字符)<br />BLOB(二进制)<br />NCLOB(国家字符集)<br />BFILE(外部文件存储)<br />9i MaxSize 4G Bytes<br />10g MaxSize 4G BLOCKS<br />
  24. 24. LOB 存储定义语法<br />{ TABLESPACE tablespace<br />| { ENABLE | DISABLE } STORAGE IN ROW<br />| storage_clause<br />| CHUNK integer<br />| PCTVERSION integer<br />| RETENTION<br />| FREEPOOLS integer<br />| { CACHE<br /> | { NOCACHE | CACHE READS } [ logging_clause ]<br /> }<br />}<br />
  25. 25. LOB<br />每个LOB字段有两个段 LOBINDEX,LOGSEGMENT,如果未指定名字,则系统自动命令,如:SYS_LOB0000030371C00001$$<br />名字里会有表的OBJECT#,其中30371就是表的OBJECT<br />lob存储可以指定单独的表空间, lobindex和lobsegment在同一个表空间中。<br />
  26. 26. Lobindex & Lobsegment<br />
  27. 27. LOB ----STORAGE IN ROW<br />ENABLE(默认)<br />小于4000字节与表数据存在一起,会在data_buffer里保存<br />大于4000字节保存在LOB指定的段中<br />DISABLE<br />所有数据都保存在LOB指定的段中<br />
  28. 28. LOG ----CHUNK Size<br />设置LOB段每个单元分配的字节数,要求是数据块大小的整理倍,如果不是数据块大小的整理倍,ORACLE会自动向上取整,缺省为1个数据块大小,最大为32KB<br />CHUNK是每条记录的每个LOB字段存储的最小单位,假设CHUNK=8192,如果LOB字段只有1个字节,也会点用1个CHUNK存储,如果LOB字段有8193个字节,则会点用2个CHUNK<br />
  29. 29. LOB---- UNDO<br />lobindex会像其他段一样生成undo,但是lobsegment不会,ORACLE对LOB字段进行更新时不会重用原有的存储空间,而是先重新分配新的空间,然后调整lobindex的指针到新空间的地址。<br />PCTVERSION percent,默认是10%<br />使用预留百分比的数据块保存旧版本<br />RETENTION<br />保存时间与初始化参数undo_retention相同<br />
  30. 30. LOB----CACHE<br />NOCACHE(默认值)<br />全部直接磁盘读写<br />CACHE<br />读写都通过缓存<br />CACHE READ<br />读的数据会缓存到内存<br />
  31. 31. BFILE<br />create or replace directory MY_DIR as 'e:/download‘;<br />create table t(c_bfilebfile);<br />insert into t values(bfilename('MY_DIR','Version.xml'));<br />BFILE不是读一致性<br />BFILE在数据库中占用的空间是文件名长度<br />
  32. 32. 谢谢!<br />

×