0

0

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

php中文网

php中文网

发布时间:2016-06-07 15:44:44

|

1482人浏览过

|

来源于php中文网

原创

这篇文章主要描述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

中国工商网电子商务购物中心系统EMall
中国工商网电子商务购物中心系统EMall

完全公开源代码,并无任何许可限制 特别基于大型电子商务网站的系统开发 Microsoft SQL Server 2000后台数据库,充分应用了存储过程的巨大功效 基于类模块的扩展数据访问能力支持任何类型的大型数据库 加密用户登录信息(cookie) 易于安装的系统和应用功能 100%的asp.net的代码,没有COM,java或者其他的格式 完全基于MS建议的系统安全设计 最佳的应用程序,数据库

下载

   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

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
batoto漫画官网入口与网页版访问指南
batoto漫画官网入口与网页版访问指南

本专题系统整理batoto漫画官方网站最新可用入口,涵盖最新官网地址、网页版登录页面及防走失访问方式说明,帮助用户快速找到batoto漫画官方平台,稳定在线阅读各类漫画内容。

127

2026.02.25

Steam官网正版入口与注册登录指南_新手快速进入游戏平台方法
Steam官网正版入口与注册登录指南_新手快速进入游戏平台方法

本专题系统整理Steam官网最新可用入口,涵盖网页版登录地址、新用户注册流程、账号登录方法及官方游戏商店访问说明,帮助新手玩家快速进入Steam平台,完成注册登录并管理个人游戏库。

18

2026.02.25

TypeScript全栈项目架构与接口规范设计
TypeScript全栈项目架构与接口规范设计

本专题面向全栈开发者,系统讲解基于 TypeScript 构建前后端统一技术栈的工程化实践。内容涵盖项目分层设计、接口协议规范、类型共享机制、错误码体系设计、接口自动化生成与文档维护方案。通过完整项目示例,帮助开发者构建结构清晰、类型安全、易维护的现代全栈应用架构。

15

2026.02.25

Python数据处理流水线与ETL工程实战
Python数据处理流水线与ETL工程实战

本专题聚焦 Python 在数据工程场景下的实际应用,系统讲解 ETL 流程设计、数据抽取与清洗、批处理与增量处理方案,以及数据质量校验与异常处理机制。通过构建完整的数据处理流水线案例,帮助开发者掌握数据工程中的性能优化思路与工程化规范,为后续数据分析与机器学习提供稳定可靠的数据基础。

1

2026.02.25

Java领域驱动设计(DDD)与复杂业务建模实战
Java领域驱动设计(DDD)与复杂业务建模实战

本专题围绕 Java 在复杂业务系统中的建模与架构设计展开,深入讲解领域驱动设计(DDD)的核心思想与落地实践。内容涵盖领域划分、聚合根设计、限界上下文、领域事件、贫血模型与充血模型对比,并结合实际业务案例,讲解如何在 Spring 体系中实现可演进的领域模型架构,帮助开发者应对复杂业务带来的系统演化挑战。

1

2026.02.25

Golang 生态工具与框架:扩展开发能力
Golang 生态工具与框架:扩展开发能力

《Golang 生态工具与框架》系统梳理 Go 语言在实际工程中的主流工具链与框架选型思路,涵盖 Web 框架、RPC 通信、依赖管理、测试工具、代码生成与项目结构设计等内容。通过真实项目场景解析不同工具的适用边界与组合方式,帮助开发者构建高效、可维护的 Go 工程体系,并提升团队协作与交付效率。

18

2026.02.24

Golang 性能优化专题:提升应用效率
Golang 性能优化专题:提升应用效率

《Golang 性能优化专题》聚焦 Go 应用在高并发与大规模服务中的性能问题,从 profiling、内存分配、Goroutine 调度、GC 机制到 I/O 与锁竞争逐层分析。结合真实案例讲解定位瓶颈的方法与优化策略,帮助开发者建立系统化性能调优思维,在保证代码可维护性的同时显著提升服务吞吐与稳定性。

9

2026.02.24

Golang 面试题精选:高频问题与解答
Golang 面试题精选:高频问题与解答

Golang 面试题精选》系统整理企业常见 Go 技术面试问题,覆盖语言基础、并发模型、内存与调度机制、网络编程、工程实践与性能优化等核心知识点。每道题不仅给出答案,还拆解背后的设计原理与考察思路,帮助读者建立完整知识结构,在面试与实际开发中都能更从容应对复杂问题。

6

2026.02.24

Golang 运行与部署实战:从本地到云端
Golang 运行与部署实战:从本地到云端

《Golang 运行与部署实战》围绕 Go 应用从开发完成到稳定上线的完整流程展开,系统讲解编译构建、环境配置、日志与配置管理、容器化部署以及常见运维问题处理。结合真实项目场景,拆解自动化构建与持续部署思路,帮助开发者建立可靠的发布流程,提升服务稳定性与可维护性。

5

2026.02.24

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
SQL 教程
SQL 教程

共61课时 | 4.1万人学习

Java 教程
Java 教程

共578课时 | 72.6万人学习

oracle知识库
oracle知识库

共0课时 | 0.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号