Sql/mp的Numeric和Decimal
发表于:2007年06月28日  分类:技术  添加评论  1,913 次浏览 

Sql/mp是hp的NSK系统上的数据库,应该是老版本的了,新的叫SQL/MX。
SQL/mp里为什么要弄这么多的数值型的数据类型:NUMERIC,SMALLINT,INTEGER,LARGEINT,FLOAT,REAL,DOUBLE PRECISION,DECIMAL等。
而且这些类型好像还都能用在DDL语句里,而有些又是互相重合的,真的有点混。

今天主要看了一下NUMERIC和DECIMAL这两个类型。
这两个光看字面很难区分,numeric就是数字的意思,decimal是十进制的意思,不像int和float那样有没有小数点那么区别明显。
其实这两个类型的区别应该是在内部存贮上:
Numeric就是binary的,也就是内部形式。比如1,会存为0×0001
Decimal是基于ascii的,比如1会存为0×0031

这么说不太明显还是做个实验来看看。测试是有小数点的情况。
Col_dec,col_num都是最大为5为,2位小数的字段,就是说最大值是999.99。

>>CREATE Table table3
+>(
+> id INTEGER DEFAULT SYSTEM NOT NULL,
+> col_dec DECIMAL(5,2) DEFAULT SYSTEM NOT NULL,
+> col_num NUMERIC(5,2) DEFAULT SYSTEM NOT NULL,
+> PRIMARY KEY (id)
+>)
+>;
— SQL operation complete.
>>
>>insert into table3 values (1,2,3);
— 1 row(s) inserted.
>>insert into table3 values (4,5.66,7.88);
— 1 row(s) inserted.
>>insert into table3 values (9,111.11,1);
— 1 row(s) inserted.
>>insert into table3 values (2,-344.55,-66.77);
— 1 row(s) inserted.
>>insert into table3 values (100,0,999.99);
— 1 row(s) inserted.
>>
>>select * from table3;

ID COL_DEC COL_NUM
———– ——- ————

1 2.00 3.00
2 -344.55 -66.77
4 5.66 7.88
9 111.11 1.00
100 .00 999.99

— 5 row(s) selected.

插入了5条数据,要测试的两个字段的数据有正有负。

因为fup不能看那个table3的文件内容,所以把这些数据导入到文件里。
首先要创建一个格式化文件。
先看看table3表的大小:
>>select colname,colsize,datatype,scale,precision from $system.cata.columns wh
ere tablename like “%TABLE3%”;

COLNAME COLSIZE DATATYPE SCALE PRECISION
—————————— ——- —————— —— ———

ID 4 INT SIGNED 0 10
COL_DEC 5 DECIMAL LSIGNED 0 5
COL_NUM 4 NUMERIC SIGNED 0 5

— 3 row(s) selected.
计算一下各个字段的长度,一个record的长度应该是4+5+4=13,但是这个是不对的,看record长度要用fup来看

-info table3,detail
。。。
REC 14
。。。
KEY ( COLUMN 0, OFFSET 0, LENGTH 4, ASC )
为什么是14?因为decimal是有符号的,而定义时的5不包括符合位,所以系统自己给加了一个符号位(就是+或者-,占1byte),所以就变成14个字节了。而int或者numeric则由第一个bit标识正负符号,不要再加一个byte来额外的存放符号了。
用下面的命令建立文件
-create tb3,type k,rec 14,keyoff 0,keylen 4
CREATED – $VOL.SUBVOL.TB3

在sqlci里,load数据到文件。
>> load table3,tb3
File Name Reads/Writes

$VOL.SUBVOL.TABLE3 5
$VOL.SUBVOL.TB3 5

$VOL.SUBVOL 15:29 107> fup copy tb3,,h
这条语句的意思是用二进制方式显示这个格式化文件的内容。
结果如下:
$VOL.SUBVOL.TB3 RECORD 0 LEN 14 28JUN07 15:29
000: 0000 0001 2B30 3032 3030 0000 012C ….+00200…,

$VOL.SUBVOL.TB3 RECORD 1 LEN 14
000: 0000 0002 2D33 3434 3535 FFFF E5EB ….-34455….

$VOL.SUBVOL.TB3 RECORD 2 LEN 14
000: 0000 0004 2B30 3035 3636 0000 0314 ….+00566….

$VOL.SUBVOL.TB3 RECORD 3 LEN 14
000: 0000 0009 2B31 3131 3131 0000 0064 ….+11111…d

$VOL.SUBVOL.TB3 RECORD 4 LEN 14
000: 0000 0064 2B30 3030 3030 0001 869F …d+00000….
5 RECORDS TRANSFERRED

首先,结果是按record显示的,000:只是个行号类似的东西。
首先看每个记录的前4个字节,比如0000 0001,换成10进制就是1,0000 0064换成10进制就是100。这个字段占4个字节。

接下来的6个字节为decimal(5,2)的字段,其中第一个字段标识符号,比如2B标识加号,即正数,2D标识减号,即负数。拿第二条记录来说,344.55这个数字共有5个数字,和一个小数点,因为小数点的位置是固定的,所以这个字段中根本不用存小数点,只需要存储34455(即33 3434 3535)这5个字节。也就是说,decimal字段的存储就类似于文本文件,用二进制查看的话0就是0×30.

于decimal相对,numeric则称为binary数据,看第三个字段。拿最后一个记录来说,1869f就是十进制的99999,加上两位小数点,就是999.99。负数的话,4个byte的第一位是1,如第二条所示。

噢,原来如此。

固定链接: http://liubin.nanshapo.com/2007/06/28/132/ | 其实我是一个程序员
【上篇】
【下篇】

报歉!评论已关闭.