찾다
데이터 베이스MySQL 튜토리얼ORACLE数值类型详解--NUMBER、BINARY

在9i之前,ORACLE为我们提供了Number数类型,在10g中,ORACLE又引入了BINARY_FLOAT和BINARY_DOUBLE数据类型。除此之外,还有integer,smallint等数据类型,但这些类型的底层实现依然是NUMBER、BINARY_FLOAT、BINARY_DOUBLE。 因此,我们可以认为ORACLE总共为

        在9i之前,ORACLE为我们提供了Number数值类型,在10g中,ORACLE又引入了BINARY_FLOAT和BINARY_DOUBLE数据类型。除此之外,还有integer,smallint等数据类型,但这些类型的底层实现依然是NUMBER、BINARY_FLOAT、BINARY_DOUBLE。因此,我们可以认为ORACLE总共为我们提供了三种存储数值的数据类型:NUMBER、BINARY_FLOAT、BINARY_DOUBLE。通过这三种数值类型,可以存储正值,负值,0,无穷大和NAN(not a number)。

NUMBER

        number类型在oracle中会占用0~22个字节的存储空间,是一种变长数据类型,采用oracle内部算法,是一种软数据类型,因此具有较好的数据精确度,通用性和可移植性较强,但是其运算效率相对一浮点类型(硬件运算)偏低。在0~22个字节的存储空间中,一个字节用于存储数据长度,21个字节用于存储数据(其中一个字节存储与符号和指数相关的内容,20个字节用于存储数据)。

        number存储数据的范围如下:

        正数:1 x 10-130 to 9.99...9 x 10125 ,数据精度为38个有效数字

      负数:-1 x 10-130 to 9.99...99 x 10125 ,数据精度为38个有效数字

      零:0

      无穷大:仅仅只可以从oracle 5中导入

number有效数字

        可以通过如下格式来指定:COLUMN_NAME number(precision ,scale),其中precision指number可以存储的最大数字长度(不包括左右两边的0),scale指在小数点右边的最大数字长度(包括左侧0)。如果我们指定了p和s,可以按照如下算法来判读数据是否有效:如果s>=0,首先我们从小数点从左向右数s个数字,如果在此之右,仍然有数据,则将其截断,然后我们在当前位置再向左侧数p个数字,如果在此之左仍有非零数字,则数字不合法,否则数据合法;如果s

        如果我们没有指定phes如:column_name number,则数字按照输入格式存储;如果我们指定了p,但是没有指定s,则s默认为0,如column_name number(p);如果我们指定了s但是没有指定p,则p默认为38,如column_name number(*,s)。

        p的取值范围为1-38,在官方文档中有这样一段话:

       Oracle guarantees the portability of numbers with precision of up to 20 base-100 digits, which is equivalent to 39 or 40 decimal digits depending on the position of the decimal point.由于在内部采用20个字节存储数据,每个字节存储2位数字,因此最多可以存放40个数字,及文档中谈及的40,但是如果小数点左侧的数字数量为奇数,则左侧补一位0,那么这是有效数字就最大为39。在语法上,oracle规定precision为38,可能是为了稳妥或者其他的原因。

        s的取值范围为-84~127,这也是与number的内部存储格式有关,不做过多的讨论。

[sql

SQL> create table t6(c1 number,c2 number(*,1),c3 number(9),c4 number(9,2),c5 number(9,1),c6 number(6),c7 number(7,-2));  

  

表已创建。  

  

SQL> insert into t6 values(7456123.89,7456123.89,7456123.89,7456123.89,7456123.89,7456123.89,7456123.89);  

insert into t6 values(7456123.89,7456123.89,7456123.89,7456123.89,7456123.89,7456123.89,7456123.89)  

                                                                             *  

第 1 行出现错误:  

ORA-01438: 值大于为此列指定的允许精度  

  

  

SQL> insert into t6 values(7456123.89,7456123.89,7456123.89,7456123.89,7456123.89,0,7456123.89);  

  

已创建 1 行。  

  

SQL> commit;  

[sql

SQL> select * from t6;  

  

      C1           C2       C3       C4       C5       C6       C7  

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

  7456123.89    7456123.9      7456124   7456123.89    7456123.9        0      7456100  

number存储结构

        number数据类型的存储结构,可以通过dump函数来展现,在探究number存储结构之前,让我们先来看一下dump函数的使用方法。

        DUMP函数的输出格式类似:

类型 ,符号/指数位 [数字1,数字2,数字3,……,数字20]

        其中各参数的含义如下:

·类型指字段数据类型,Number型,Type=2(类型代码可以从Oracle的文档上查到);

·长度指存储的字节数;

·符号/指数位用于代表数字的正负及指数值;

·数据存储。

 

        oracle采用21个字节存储number,第一个字节为头信息,随后20个字节存储有效数字。

         头信息        数据域1      数据域2   .............. 数据域n (n

         XXXXXXXXXXXXXXXX XXXXXXXX ............XXXXXXXX

         |  |                   |-一个字节存储2个十进制数字,可以存储0-99,因为0在c语言中作为特殊字符,因此用1-100来存储0-99,即在原值上加1。在数据域不存储正负符号,为了

         |  |                   |-排序的方便,对于负数,我们用101-2来存储0-99(为什么不用100-1,请高手指教),在负数的最后会添加一个值为102的字节,这是为了避免排序错误

         |  |-数据指数范围标识位,当正数时,该数值与64做差(x-64),其结果为指数,当负数时,63与该数值做差(63-x),其结果为指数。在oracle中0X80,代表0,因此对于

         |  |-正数,其指数范围为-63~0(小数) 1~63(非小数);对于负数,指数范围为63~1(非小数),0~-64(小数)

         |-符号信息位,1代表正数,0代表负数

          查询是,对于存储在数据域的数据,oracle会将每个字节转换为十进制,然后拼接各个字节。如果指数域的值为正数n,那么会将小数点定位在第n个字节的后面,如果为0,则小数点在第一个字节的前面,如果为负数,则小数点在第一个字节向前推进n个字节。

 

        下面,我们通过实例来看一下上面的说法正不正确:

[sql] 

desc tab1  

名称 空值 类型              

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

C1    NUMBER          

C2    VARCHAR2(300)   

 

 

ORACLE数值类型详解--NUMBER、BINARY

 

 

如果负数的精度很 大,102比较位可能会被舍弃,因此此时102已经起不到任何作用了。

       

[sql

SQL> insert into tab1 values(-111111111111111111111111111111111111111111111111111111111111);  

  

已创建 1 行。  

  

SQL> select dump(c1) from tab1;  

  

DUMP(C1)  

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

Typ=2 Len=2: 193,2  

Typ=2 Len=3: 62,100,102  

Typ=2 Len=1: 128  

Typ=2 Len=6: 197,2,24,46,68,90  

Typ=2 Len=7: 58,100,78,56,34,12,102  

Typ=2 Len=12: 58,100,78,56,34,12,3,25,47,69,91,102  

Typ=2 Len=11: 197,2,24,46,68,90,99,77,55,33,11  

Typ=2 Len=21: 33,90,90,90,90,90,90,90,90,90,90,90,  

90,90,90,90,90,90,90,90,90  

 

number变种

        除number类型外,oracle还为我们提供了一些number的变种数据类型,这些类型其内部实现仍然是number,我们可以将其理解为number的特定别名。

NUMERIC(p,s):完全映射至NUMBER(p,s)。如果p未指定,则默认为38.

DECIMAL(p,s)或DEC(p,s):完全映射至NUMBER(p,s)。如果p为指定,则默认为38

INTEGER或INT:完全映射至NUMBER(38)类型。

SMALLINT:完全映射至NUMBER(38)类型。

 

FLOAT(b):映射至NUMBER类型。

 

DOUBLE PRECISION:映射至NUMBER类型。

 

REAL:映射至NUMBER类型。

在这里需要特别注意的是float类型,参加官方文档:

        The FLOAT data type is a subtype of NUMBER. It can be specified with or without precision, which has the same definition it has for NUMBER and can rangefrom 1 to 

126. Scale cannot be specified, but is interpreted from the data. Each FLOAT value requires from 1 to 22 bytes.

        To convert from binary to decimal precision, multiply n by 0.30103. To convert from decimal to binary precision, multiply the decimal precision by 3.32193. The maximum of 126 digits of binary precision is roughly equivalent to 38 digits of decimal precision.

        由此可知,float中的有效数指的是二进制格式的有效数,转换为10进制为b*0.30103. 如果结果不是整数,则采用上侧整数作为底层number存储的precision。如:

[sql

SQL> desc tab1  

 名称                                      是否为空? 类型  

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

 C1                                                 FLOAT(2)  

 C2                                                 FLOAT(4)  

 C3                                                 FLOAT(6)  

 C4                                                 FLOAT(7)  

 C5                                                 FLOAT(9)  

 C6                                                 FLOAT(11)  

 C7                                                 FLOAT(13)  

  

SQL> insert into tab1 values(1234567890.0987654321,1234567890.0987654321,1234567890.0987654321,1234567890.0987654321,1234567890.0987654321,1234567890.0987654321,1234567890.0987654321);  

  

已创建 1 行。  

  

SQL> select * from tab1;  

  

        C1         C2         C3         C4         C5         C6         C7  

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

1000000000 1200000000 1200000000 1230000000 1230000000 1235000000 1235000000  

PLS_INTEGER和BINARY_INTEGER

        PLS_INTEGER和BINARY_INTEGER是plsql数据类型,无法在表中直接使用。在11g的官方文档中,官方指出PLS_INTEGER和BINARY_INTEGER两者是相同的,是有符号的整数类型,其取值范围为-2^31 ~  2^31,共占用32个比特位。其内部存储格式,尚无资料表明,通过dump函数查看其为number类型,这可能是不正确的(补充:后来dump varchar2和nvarchar2数据类型时,其typ均为1,由此可见dump可能对相似的数据类型使用相同的typ),因为官方文档明确指出了PLS_INTEGER BINARY_INTEGER通number的一下区别:

       1.存储空间要比number小

       2.计算效率要比number高,因此可以直接硬件运算,而number是软运算。

        如果赋值范围超出了PLS_INTEGER和BINARY_INTEGER的范围,将会发生溢出异常;

[sql

DECLARE  

  p1 PLS_INTEGER := 2147483647;  

  p2 PLS_INTEGER := 1;  

  n NUMBER;  

BEGIN  

  n := p1 + p2;  

END;  

/  

Result:  

DECLARE  

*  

ERROR at line 1:  

ORA-01426: numeric overflow  

ORA-06512: at line 6  

        在11g中,oracle引入了simple_integer,该类型是PLS_INTEGER的子类型,取值范围相同,但是该类型不会进行空值和溢出检测(必须人为保证非空和不会发生溢出),因此与PLS_INTEGER相比,具有更高的性能。如果可以确定某个值为非空并且不会发生溢出操作,可以使用simple_integer来存储。由于不会进行溢出检测,simple_integer的运算结果可能会发生正负值的转换,例如:

[sql

DECLARE  

  n SIMPLE_INTEGER := 2147483645;  

BEGIN  

  FOR j IN 1..4 LOOP  

    n := n + 1;  

    DBMS_OUTPUT.PUT_LINE(TO_CHAR(n, 'S9999999999'));  

  END LOOP;  

  FOR j IN 1..4 LOOP  

   n := n - 1;  

   DBMS_OUTPUT.PUT_LINE(TO_CHAR(n, 'S9999999999'));  

  END LOOP;  

 12  END;  

 13  /  

+2147483646  

+2147483647  

-2147483648  

-2147483647  

-2147483648  

+2147483647  

+2147483646  

+2147483645  

  

PL/SQL 过程已成功完成。  

         如果将simple_integer转换为pls_integer, 会转换为pls_integer not null。

BINARY_FLOAT和BINARY_DOUBLE

        oracle根据IEEE754实现单精度和双精度浮点型,要了解IEEE754,请参照http://blog.csdn.net/yidian815/article/details/12912661 

        由于存储结构上的不同,BINARY_FLOAT和BINARY_DOUBLE较number,可以存储更大范围的数据,但是其精度并不如number。如果存储金融数据,建议使用number,而如果进行科学运算,建议使用BINARY_FLOAT和BINARY_DOUBLE,因为浮点型数据使用的是硬件计算,其计算效率是非常高的。

 

        我们可以通过如下方式来判断某个浮点型是否为无穷或者非数值。

        

        expr is [not] NAN

        expr is [not] INFINITE

        ORACLE可以对NAN排序,排序规则是,NAN最大,NAN与NAN比较时,其值相等。infinity和infinity相比,其值相等。

[sql

SQL> create table tab1(id number,c1 binary_float,c2 binary_double);  

  

表已创建。  

  

SQL> insert into tab1 values(1,1,1);  

  

已创建 1 行。  

  

SQL> insert into tab1 values(2,nan,nan);  

insert into tab1 values(2,nan,nan)  

                              *  

第 1 行出现错误:  

ORA-00984: 列在此处不允许  

  

  

SQL> insert into tab1 values(2,binary_float_nan,binary_double_nan);  

  

已创建 1 行。  

  

SQL> insert into tab1 values(3,binary_float_infinity,binary_double_infinity);  

  

已创建 1 行。  

  

SQL> insert into tab1 values(4,-binary_float_infinity,-binary_double_infinity);  

  

已创建 1 行。  

  

SQL> commit;  

  

提交完成。  

  

SQL> select * from tab1;  

  

    ID         C1     C2  

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

     1   1.0E+000   1.0E+000  

     2        Nan    Nan  

     3        Inf    Inf  

     4       -Inf   -Inf  

  

SQL> select * from tab1 order by c1;  

  

    ID         C1     C2  

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

     4       -Inf   -Inf  

     1   1.0E+000   1.0E+000  

     3        Inf    Inf  

     2        Nan    Nan  

  

SQL> select * from tab1 where c1 is infinite;  

  

    ID         C1     C2  

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

     3        Inf    Inf  

     4       -Inf   -Inf  

  

SQL> select * from tab1 where c1 is nan;  

  

    ID         C1     C2  

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

     2        Nan    Nan  

  

SQL> select * from tab1 where c1 = binary_float_infinity;  

  

    ID         C1     C2  

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

     3        Inf    Inf  

  

SQL> select * from tab1 where c1 != binary_float_infinity;  

  

    ID         C1     C2  

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

     1   1.0E+000   1.0E+000  

     2        Nan    Nan  

     4       -Inf   -Inf  

  

SQL> select * from tab1 where c1 = (select c1 from tab1 where id =2);  

  

    ID         C1     C2  

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

     2        Nan    Nan  

  

SQL> select * from tab1 where c1 = nan;  

select * from tab1 where c1 = nan  

                              *  

第 1 行出现错误:  

ORA-00904: "NAN": 标识符无效  

  

  

SQL> select * from tab1 where c1 = binary_float_nan;  

  

    ID         C1     C2  

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

     2        Nan    Nan  

  

SQL> select * from tab1 where c1 = (select c1 from tab1 where id =3);  

  

    ID         C1     C2  

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

     3        Inf    Inf  

  

SQL>   

优先级:在数据转换时,优先转换为高级别的数据类型

date type > binary_double > binary_float > number > char

 

성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
MySQL에서 데이터베이스 업그레이드를 어떻게 처리합니까?MySQL에서 데이터베이스 업그레이드를 어떻게 처리합니까?Apr 30, 2025 am 12:28 AM

MySQL 데이터베이스를 업그레이드하는 단계에는 다음이 포함됩니다. 1. 데이터베이스 백업, 2. 현재 MySQL 서비스 중지, 3. 새 버전의 MySQL 설치, 4. 새 버전의 MySQL 서비스 시작, 5. 데이터베이스 복구. 업그레이드 프로세스 중에 호환성 문제가 필요하며 Perconatoolkit과 같은 고급 도구를 테스트 및 최적화에 사용할 수 있습니다.

MySQL에 사용할 수있는 다른 백업 전략은 무엇입니까?MySQL에 사용할 수있는 다른 백업 전략은 무엇입니까?Apr 30, 2025 am 12:28 AM

MySQL 백업 정책에는 논리 백업, 물리적 백업, 증분 백업, 복제 기반 백업 및 클라우드 백업이 포함됩니다. 1. 논리 백업은 MySQLDump를 사용하여 데이터베이스 구조 및 데이터를 내보내며 소규모 데이터베이스 및 버전 마이그레이션에 적합합니다. 2. 물리적 백업은 데이터 파일을 복사하여 빠르고 포괄적이지만 데이터베이스 일관성이 필요합니다. 3. 증분 백업은 이진 로깅을 사용하여 변경 사항을 기록합니다. 이는 큰 데이터베이스에 적합합니다. 4. 복제 기반 백업은 서버에서 백업하여 생산 시스템에 미치는 영향을 줄입니다. 5. AmazonRDS와 같은 클라우드 백업은 자동화 솔루션을 제공하지만 비용과 제어를 고려해야합니다. 정책을 선택할 때 데이터베이스 크기, 가동 중지 시간 허용 오차, 복구 시간 및 복구 지점 목표를 고려해야합니다.

MySQL 클러스터링이란 무엇입니까?MySQL 클러스터링이란 무엇입니까?Apr 30, 2025 am 12:28 AM

mysqlclusteringenhancesdatabaserobustness andscalabilitydaturedingdataacrossmultiplenodes.itusesthendbenginefordatareplicationandfaulttolerance, highavailability를 보장합니다

MySQL의 성능을 위해 데이터베이스 스키마 설계를 어떻게 최적화합니까?MySQL의 성능을 위해 데이터베이스 스키마 설계를 어떻게 최적화합니까?Apr 30, 2025 am 12:27 AM

MySQL에서 데이터베이스 스키마 설계 최적화는 다음 단계를 통해 성능을 향상시킬 수 있습니다. 1. 인덱스 최적화 : 공통 쿼리 열에서 인덱스 생성, 쿼리의 오버 헤드 균형 및 업데이트 삽입. 2. 표 구조 최적화 : 정규화 또는 정상화를 통한 데이터 중복성을 줄이고 액세스 효율을 향상시킵니다. 3. 데이터 유형 선택 : 스토리지 공간을 줄이기 위해 Varchar 대신 Int와 같은 적절한 데이터 유형을 사용하십시오. 4. 분할 및 하위 테이블 : 대량 데이터 볼륨의 경우 파티션 및 하위 테이블을 사용하여 데이터를 분산시켜 쿼리 및 유지 보수 효율성을 향상시킵니다.

MySQL 성능을 어떻게 최적화 할 수 있습니까?MySQL 성능을 어떻게 최적화 할 수 있습니까?Apr 30, 2025 am 12:26 AM

tooptimizemysqlperformance, followthesesteps : 1) 구현 properIndexingToSpeedUpqueries, 2) useExplaintoAnalyzeanDoptimizeQueryPerformance, 3) AdvertServerConfigUrationSettingstingslikeInnodb_buffer_pool_sizeandmax_connections, 4) uspartOflEtOflEtOflestoI

데이터 처리 및 계산에 MySQL 기능을 사용하는 방법데이터 처리 및 계산에 MySQL 기능을 사용하는 방법Apr 29, 2025 pm 04:21 PM

MySQL 기능은 데이터 처리 및 계산에 사용될 수 있습니다. 1. 기본 사용에는 문자열 처리, 날짜 계산 및 수학 연산이 포함됩니다. 2. 고급 사용에는 복잡한 작업을 구현하기 위해 여러 기능을 결합하는 것이 포함됩니다. 3. 성능 최적화를 위해서는 WHERE 절에서 기능 사용 및 GroupBy 및 임시 테이블 사용을 피해야합니다.

MySQL에 데이터를 일괄 삽입하는 효율적인 방법MySQL에 데이터를 일괄 삽입하는 효율적인 방법Apr 29, 2025 pm 04:18 PM

MySQL에 데이터 삽입을위한 효율적인 방법은 다음과 같습니다. 1. InsertInto 사용 ... 값 구문 사용 ... 값 구문, 2. 트랜잭션 처리 사용, 3. 트랜잭션 처리 사용, 4. 배치 크기 조정, 5. 인덱스 비활성화, 6. Insertignore 또는 Insert ... ondupliceKeyUpdate를 사용하여 데이터베이스 작동 효율성을 크게 향상시킬 수 있습니다.

MySQL 테이블에 필드를 추가 및 삭제하는 단계MySQL 테이블에 필드를 추가 및 삭제하는 단계Apr 29, 2025 pm 04:15 PM

MySQL에서는 altertabletable_nameaddcolumnnew_columnvarchar (255) 이후에 필드를 추가하여 altertabletable_namedropcolumncolumn_to_drop을 사용하여 필드를 삭제합니다. 필드를 추가 할 때는 쿼리 성능 및 데이터 구조를 최적화하기위한 위치를 지정해야합니다. 필드를 삭제하기 전에 작업이 돌이킬 수 없는지 확인해야합니다. 온라인 DDL, 백업 데이터, 테스트 환경 및 저하 기간을 사용하여 테이블 구조 수정은 성능 최적화 및 모범 사례입니다.

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

ZendStudio 13.5.1 맥

ZendStudio 13.5.1 맥

강력한 PHP 통합 개발 환경

맨티스BT

맨티스BT

Mantis는 제품 결함 추적을 돕기 위해 설계된 배포하기 쉬운 웹 기반 결함 추적 도구입니다. PHP, MySQL 및 웹 서버가 필요합니다. 데모 및 호스팅 서비스를 확인해 보세요.

SecList

SecList

SecLists는 최고의 보안 테스터의 동반자입니다. 보안 평가 시 자주 사용되는 다양한 유형의 목록을 한 곳에 모아 놓은 것입니다. SecLists는 보안 테스터에게 필요할 수 있는 모든 목록을 편리하게 제공하여 보안 테스트를 더욱 효율적이고 생산적으로 만드는 데 도움이 됩니다. 목록 유형에는 사용자 이름, 비밀번호, URL, 퍼징 페이로드, 민감한 데이터 패턴, 웹 셸 등이 포함됩니다. 테스터는 이 저장소를 새로운 테스트 시스템으로 간단히 가져올 수 있으며 필요한 모든 유형의 목록에 액세스할 수 있습니다.

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

DVWA

DVWA

DVWA(Damn Vulnerable Web App)는 매우 취약한 PHP/MySQL 웹 애플리케이션입니다. 주요 목표는 보안 전문가가 법적 환경에서 자신의 기술과 도구를 테스트하고, 웹 개발자가 웹 응용 프로그램 보안 프로세스를 더 잘 이해할 수 있도록 돕고, 교사/학생이 교실 환경 웹 응용 프로그램에서 가르치고 배울 수 있도록 돕는 것입니다. 보안. DVWA의 목표는 다양한 난이도의 간단하고 간단한 인터페이스를 통해 가장 일반적인 웹 취약점 중 일부를 연습하는 것입니다. 이 소프트웨어는