首页 数据库 mysql教程 Oracle基本数据类型存储格式浅析(二)数字类型

Oracle基本数据类型存储格式浅析(二)数字类型

Jun 07, 2016 pm 03:44 PM
oracle 基本 存储 数字 数据 格式 类型

这篇文章主要描述NUMBER类型的数据和如何在数据库中存储的。 1 number类型的组成 Oracle的number类型最多由三个部分构成,这三个部分分别是 “最高位表示位”、“数据部分”、“符号位”。 其中负数存在符号位,正数没有符号位。 另外,数0比较特殊,它只包

这篇文章主要描述NUMBER类型的数据和如何在数据库中存储的。

1 number类型的组成

Oracle的number类型最多由三个部分构成,这三个部分分别是“最高位表示位”、“数据部分”、“符号位”。

其中负数存在符号位,正数没有符号位。

另外,数值0比较特殊,它只包含一个数值最高位表示位80,没有数据部分,也没有符号位。

1.1 最高位表示位

正数的最高位表示位大于80,负数的最高位表示位小于80。

一个正数的最高位是个位的话,则最高位表示位为0X C1(即十进制的193),百位、万位依次为C2、C3,百分位、万分为依次为C0、BF。

一个负数的最高位为个位的话,最高位表示位为0X 3E(即十进制的62),百位、万位依次为3D、3C,百分位、万分位依次为3F、40。

1.2 数据部分

数据部分每一字节都表示2位数字。(由)这个两位数字(组成的一个数值)的范围可能是从0到99,如果是数据本身是正数,则分别用六进制的1到64表示,如果数据本身是负数,则使用进制65到2表示。

注意:

在数据部分中,同样是(数据部分中的)0,在正数时用0x01表示,而在负数时用0x65表示。

在数据部分中,同样是数据部分中的)99,在正数时用0x64表示,而在负数时用0x2表示。

1.3 符号位

当数字为负数,才有符号位。符号位用0x66表示。

注意:用0x66表示,因为同样的一个数字,在正数与负数表示时,它们之和为0x66。例如:1的数据部分表示为0x02,而-1的数据部分表示为0x64。这个两个数之和为0x66。

2 实验过程

上面的这些是我通过DUMP结果总结出来的,对于上面提到的这些关系常数,Oracle之所以这样选择是有道理的,我们后面根据例子也可以推导出来,而且会进一步说明为什么会采用这种方式表示。这里列出的意思是使大家先对NUMBER类型数据有一个大概的了解。

下面我们通过一个例子详细说明:

SQL> create table test_number (number_col number);

Table created

SQL> insert into test_number values (0);

1 row inserted

SQL> insert into test_number values (1);

1 row inserted

SQL> insert into test_number values (2);

1 row inserted

SQL> insert into test_number values (25);

1 row inserted

SQL> insert into test_number values (123);

1 row inserted

SQL> insert into test_number values (4100);

1 row inserted

SQL> insert into test_number values (132004078);

1 row inserted

SQL> insert into test_number values (2.01);

1 row inserted

SQL> insert into test_number values (0.3);

1 row inserted

SQL> insert into test_number values (0.00000125);

1 row inserted

SQL> insert into test_number values (115.200003);

1 row inserted

SQL> insert into test_number values (-1);

1 row inserted

SQL> insert into test_number values (-5);

1 row inserted

SQL> insert into test_number values (-20032);

1 row inserted

SQL> insert into test_number values (-234.432);

1 row inserted

SQL> commit;

Commit complete

SQL> col d_number format a50

SQL> select number_col, dump(number_col, 16) d_number from test_number;

NUMBER_COL D_NUMBER

---------- --------------------------------------------------

         0 Typ=2 Len=1: 80

         1 Typ=2 Len=2: c1,2

         2 Typ=2 Len=2: c1,3

        25 Typ=2 Len=2: c1,1a

       123 Typ=2 Len=3: c2,2,18

      4100 Typ=2 Len=2: c2,2a

 132004078 Typ=2 Len=6: c5,2,21,1,29,4f

      2.01 Typ=2 Len=3: c1,3,2

       0.3 Typ=2 Len=2: c0,1f

   1.25E-6 Typ=2 Len=3: be,2,1a

115.200003 Typ=2 Len=6: c2,2,10,15,1,4

        -1 Typ=2 Len=3: 3e,64,66

        -5 Typ=2 Len=3: 3e,60,66

    -20032 Typ=2 Len=5: 3c,63,65,45,66

  -234.432 Typ=2 Len=6: 3d,63,43,3a,51,66

15 rows selected

3 结论解释

下面根据例子得到的结果,对每行进行说明。首先说明两点基本的。DUMP函数返回的TYPE=2表示DUMP的数据类型是NUMBER,LENGTH=N表示数值在数据库中存储的长度是N。

3.1 Dump(0)

DUMP(0) 的结果是0x80,在前面已经提到,0只有高位表示位,没有数据位。由于0的特殊,既不属于正数,也不属于负数,因此使用高位表示位用80表示就足够了,不会和其它数据冲突,Oracle出于节省空间的考虑将后面数据部分省掉了。

但是为什么Oracle选择0x80表示0呢?我们知道正数和负数互为相反数,每个正数都有一个对应的负数。因此如果我们要使用编码表示数值,则表示正数和负数的编码应该各占一半,这样才能保证使Oracle表示数据范围是合理的。而0x80的二进制编码是1000 0000,正好是一个字节编码最大值的一半,因此,Oracle选择0x80来表示0,是十分有道理的。

注释:

0x80的二进制编码是1000 0000,正好是一个字节编码最大值的一半,因为

1·0111 1111共2的8次方-1个(Oracle底层是用C语言实现的,我们知道二进制0在C语言中用作字符串终结符,Oracle为了避免这个问题,故将0这个值去掉),而1000 0001·1111 1111也共2的8次方-1个。

3.2 Dump(1)

DUMP(1)的结果是0xc102,0xc1表示了最高位个位,0x2表示数值是1。首先,Oracle为什么用C1表示个位呢?其实,道理和刚才的差不多。采用科学计数法,任何一个实数S都可以描述为A.B×10n,A 表示整数部分,B表示小数部分,而N表示10的指数部分。当S大于1时,N大于等于0,S小于1时,N小于0。也就是说,采用指数的方式表示,N大于0和 N小于0的情况各占一半左右时,Oracle所表示的范围最广(?)。因此,Oracle选择了C1表示个位是最高位的情况。

SQL> SELECT TO_CHAR(ROUND(TO_NUMBER('81', 'XXX') + (TO_NUMBER('FF', 'XXX') - TO_NUMBER('81', 'XXX') + 1)/2), 'XX') VALUE FROM DUAL;

VALUE

-----

   C1

为什么ORACLE使用0x2表示1,而不直接使用0x1表示1呢?Oracle每个字节表示2位数,因此对于这个2位数,出现的可能是0~99共100种可能,问题出在0这里。

Oracle底层是用C语言实现的,我们知道二进制0在C语言中用作字符串终结符,Oracle为了避免这个问题,因此使用了0x1表示0,并依次类推,使用0x64表示99。

3.3 Dump(2)

DUMP(2)的结果是0xc103。

3.4 Dump(25)

DUMP(25)的结果是0xc11a。前面提到,数据部分是以2位为最小单位保存的。因此对于25来说,最高位表示位仍然是个位,个位上的值是25,根据上面推出的规则,25在存储为0xc11a。

SQL> SELECT TO_CHAR(25 + 1, 'xx') VALUE FROM DUAL;

VALUE

-----

1a

3.5 Dump(123)

DUMP(123)的结果是0xc20218。由于123最高为是百位,所以最高位表示位为0xc2,百位上是1,用0x02表示,个位上是23,用0x18表示。

3.6 Dump(4100)

DUMP(4100)的结果是0xc22a。

注意一点,如果数字最后数位上如果是0,Oracle出于节省空间的考虑不会存储。比如:4100只保存百位上的41,12000000只保存百位位上的12,512000只保存万位上的51和百位上的20。

3.7 Dump(132004078)

DUMP(132004078)的结果是0xc5022101294f。最高位是亿位,因此用0xC5表示,亿位上是1用0x02表示,百万位上是32用0x21表示,万位上是0用0x01表示,百位上是40用0x29表示,个位上78用0x4F表示。

注意:中间数位上的0不能省略。

3.8 Dump(2.01)

DUMP(2.01)的结果是0xc10302。最高位是个位用0xC1表示,个位上是2用0x03表示,百分位上是1用0x02表示。

注意:个位下面一位是百分位不是十分位。

3.9 Dump(0.3)

DUMP(0.3)的结果是0xc01f。最高位是百分位,使用0xC0表示,百分位上是30用0x1F表示。

3.10 DUMP(0.00000125)

DUMP(0.00000125)的结果是0xbe021a。最高位是百万分位,用0xBE表示,最高位上的1用0x02表示,25用0x1a表示。

3.11 DUMP(115.200003)

DUMP(115.200003)的结果是0xc20210150104。





3.12 DUMP(-1)

DUMP(-1)的结果是0x3e6466。最高位个位,用0x3E表示,64表示个位上是1,66是符号位,表示这个数是负数。

负数和正数互为相反数,负数的最高位表示位和它对应的相反数的最高位相加的值是FF。 1的最高位表示位是C1,-1的最高位表示位是3E。负数中1用64表示。负数中的数值和它相反数的数据相加是0x66,也就是符号位。正数1用0x02 表示,负数1用0x64表示,二者相加是0x66。负数多个一个标识位,用0x66表示。由于正数的表示范围是0x01到0x64,负数的表示范围是 0x65到0x02。因此,不会在表示数字时出现的0x66表示。

3.13 DUMP(-5)

DUMP(-5)的结果是0x3e6066。0x3e表示最高位是个位,0x60表示个位上是5,0x66是符号标识位。0x3E加0xC1是0xFF。0x60加0x06的结果是0x66。

3.14 DUMP(-20032)

DUMP(-20032) 的结果是0x3c63654566。最高位是万位,正数的万位是0xC3,因此负数的万位是0x3C。万位上是2,正数用0x03表示,负数为0x63,百位上是0,正数用0x01表示,负数使用0x65表示,个位上是32,正数用0x21表示,负数使用0x45表示。0x66是负数表示位。

3.15 DUMP(-234.432)

DUMP(-234.432)的结果是0x3d63433a5166。


ORACLE数值类型详解--NUMBER、BINARY_FLOAT、BINARY_DOUBLE、BINARY_INTEGER、FLOAT


 

转贴:http://www.itpub.net/forum.php?mod=viewthread&tid=308317

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1664
14
CakePHP 教程
1421
52
Laravel 教程
1315
25
PHP教程
1266
29
C# 教程
1239
24
oracle打不开怎么办 oracle打不开怎么办 Apr 11, 2025 pm 10:06 PM

Oracle 打不开的解决办法包括:1. 启动数据库服务;2. 启动监听器;3. 检查端口冲突;4. 正确设置环境变量;5. 确保防火墙或防病毒软件未阻止连接;6. 检查服务器是否已关闭;7. 使用 RMAN 恢复损坏的文件;8. 检查 TNS 服务名称是否正确;9. 检查网络连接;10. 重新安装 Oracle 软件。

oracle游标关闭怎么解决 oracle游标关闭怎么解决 Apr 11, 2025 pm 10:18 PM

解决 Oracle 游标关闭问题的方法包括:使用 CLOSE 语句显式关闭游标。在 FOR UPDATE 子句中声明游标,使其在作用域结束后自动关闭。在 USING 子句中声明游标,使其在关联的 PL/SQL 变量关闭时自动关闭。使用异常处理确保在任何异常情况下关闭游标。使用连接池自动关闭游标。禁用自动提交,延迟游标关闭。

oracle怎么循环创建游标 oracle怎么循环创建游标 Apr 12, 2025 am 06:18 AM

Oracle 中,FOR LOOP 循环可动态创建游标, 步骤为:1. 定义游标类型;2. 创建循环;3. 动态创建游标;4. 执行游标;5. 关闭游标。示例:可循环创建游标,显示前 10 名员工姓名和工资。

HDFS配置CentOS需要哪些步骤 HDFS配置CentOS需要哪些步骤 Apr 14, 2025 pm 06:42 PM

在CentOS系统上搭建Hadoop分布式文件系统(HDFS)需要多个步骤,本文提供一个简要的配置指南。一、前期准备安装JDK:在所有节点上安装JavaDevelopmentKit(JDK),版本需与Hadoop兼容。可从Oracle官网下载安装包。环境变量配置:编辑/etc/profile文件,设置Java和Hadoop的环境变量,使系统能够找到JDK和Hadoop的安装路径。二、安全配置:SSH免密登录生成SSH密钥:在每个节点上使用ssh-keygen命令

oracle日志写满怎么办 oracle日志写满怎么办 Apr 12, 2025 am 06:09 AM

Oracle 日志文件写满时,可采用以下解决方案:1)清理旧日志文件;2)增加日志文件大小;3)增加日志文件组;4)设置自动日志管理;5)重新初始化数据库。在实施任何解决方案前,建议备份数据库以防数据丢失。

甲骨文在商业世界中的作用 甲骨文在商业世界中的作用 Apr 23, 2025 am 12:01 AM

Oracle不仅是数据库公司,还是云计算和ERP系统的领导者。1.Oracle提供从数据库到云服务和ERP系统的全面解决方案。2.OracleCloud挑战AWS和Azure,提供IaaS、PaaS和SaaS服务。3.Oracle的ERP系统如E-BusinessSuite和FusionApplications帮助企业优化运营。

oracle数据库怎么停止 oracle数据库怎么停止 Apr 12, 2025 am 06:12 AM

要停止 Oracle 数据库,请执行以下步骤:1. 连接到数据库;2. 优雅关机数据库(shutdown immediate);3. 完全关机数据库(shutdown abort)。

oracle视图怎么导出 oracle视图怎么导出 Apr 12, 2025 am 06:15 AM

可以通过 EXP 实用程序导出 Oracle 视图:登录 Oracle 数据库。启动 EXP 实用程序,指定视图名称和导出目录。输入导出参数,包括目标模式、文件格式和表空间。开始导出。使用 impdp 实用程序验证导出。

See all articles