当前位置:K88软件开发文章中心编程全书编程全书01 → 文章内容

达梦数据库6.0之数据类型使用体验

减小字体 增大字体 作者:佚名  来源:翔宇亭IT乐园  发布时间:2019-1-3 2:25:04

:2010-12-08 21:44:26

登陆达梦数据库
C:\dmdbms\bin>isql
isql V6.0.2.51-Build(2009.12.23)
SQL>login
server name:localhost
user name:test
password:
port:12345
dm_login time used:190.370(ms)

首先看一下字符类型CHAR和VARCHAR:

SQL>create table t_type
2   (id number, name varchar2(30));
create table t_type
(id number, name varchar2(30));
time used: 436.197(ms) clock tick:729306570.
SQL>create table t_char(col char(8000));
create table t_char(col char(8000));
列定义长度超长.error code = -1334
SQL>create table t_char(col char(4000));
create table t_char(col char(4000));
列定义长度超长.error code = -1334
SQL>create table t_char(col char(3000));
create table t_char(col char(3000));
time used: 20.943(ms) clock tick:35001630.

达梦为了兼容Oracle的字符类型,因此VARCHAR2这种Oracle特殊的类型也是支持的。和Oracle不同的是,CHAR类型和VARCHAR类型的最大长度都是8188,但是这个值并不是固定的,当数据库页面大小不同的时候,这个最大值也是不固定的,比如32K页面大小,字符类型CHAR或VARCHAR的最大值是8188,而如果是16K页面大小,则字符类型最大值是8000,对于当前8K页面大小,字符类型最大值只有3900,而如果页面大小为4K,则字符类型最大长度只要1900。

对于Oracle数据库而言,CHAR类型最大值是2000而VARCHAR2是4000,虽然达梦数据库绝大部分情况下,都比这个范围要大,不过个人并不认为这是一个很好的设计。不同数据库之前的迁移对于一个成熟系统而言是很常见的,而不同数据库的页面大小不同也是很平常的事情,达梦的这种设计虽然使得不同页面的最大值尽量扩大,但是却给不同页面间数据库的迁移埋下了问题。当数据库向页面更大的数据库迁移不会存在问题,但是反之可能造成表无法创建、数据丢失或数据被截断的情况。而且感觉达梦数据库在实现VARCHAR类型的时候还有一定的问题:

SQL>insert into t_type values (1, 'a ');
insert into t_type values (1, 'a ')
1 rows affected
time used: 0.464(ms) clock tick:765250.
SQL>select id, name || 'a' from t_type;
select id, name || 'a' from t_type;
id
1       1       a a
1 rows got

至此没有问题,VARCHAR类型中的空ge被保留,但是对VARCHAR类型进行查询的时候:

SQL>select * from t_type where name = 'a ';
select * from t_type where name = 'a ';
id              name
1       1       a
1 rows got
time used: 29.588(ms) clock tick:49459510.
SQL>select * from t_type where name = 'a';
select * from t_type where name = 'a';
id              name
1       1       a
1 rows got
time used: 0.314(ms) clock tick:517060.
SQL>select * from t_type where name = 'a    ';
select * from t_type where name = 'a    ';
id              name
1       1       a
1 rows got
time used: 0.421(ms) clock tick:694830.

显然在比较的时候,空ge是没有被考虑在内的,这对于CHAR类型是没有问题的,但是VARCHAR类型似乎并不应该具有这样的特性:

SQL>insert into t_type values (2 ,'a');
insert into t_type values (2 ,'a')
1 rows affected
time used: 0.401(ms) clock tick:661320.
SQL>select * from t_type
2   where name = 'a';
select * from t_type
where name = 'a';
id              name
1       1       a
2       2       a
2 rows got
time used: 0.397(ms) clock tick:653730.
SQL>alter table t_type add primary key (name);
alter table t_type add primary key (name);
违反唯一性约束.error code = -3100

显然在达梦中即使VARCHAR类型的字段也认为’a’和’a_’(这里用下划线来标识空ge)是相等的,这种情况会引发歧义,我们认为已经相等的数据在经过相同的处理后就会变得又不相等了:

SQL>select id, name || 'a' from t_type;
select id, name || 'a' from t_type;
id
1       1       a a
2       2       aa
2 rows got
time used: 36.391(ms) clock tick:60834180.

 下面看看数值类型:

SQL>create table t_num
2   (c1 number,
3   c2 number(4, 1),
4   c3 number(4, -1),
5   c4 number(2, 3));
第4行: '-'附近有语法错误
SQL>create table t_num
2   (c1 number,
3   c2 number(4, 1),
4   c4 number(2, 3));
create table t_num
(c1 number,
c2 number(4, 1),
c4 number(2, 3));
无效的数据类型.error code = -2520
SQL>create table t_num
2   (c1 number,
3   c2 number(4, 1));
create table t_num
(c1 number,
c2 number(4, 1));
time used: 42.803(ms) clock tick:71554500.

虽然达梦支持数值类型NUMBER和Oracle的NUMBER类型十分相似,但是二者还是有区别的,显然达梦不支持标度小于0的情况,而且不支持精度小于标度的情况,而这些情况在Oracle中都是支持的,下面是Oracle中的情况:

SQL> create table t_num
  2  (c1 number,
  3  c2 number(4, 1),
  4  c3 number(4, -1),
  5  c4 number(2, 3));
表已创建。
SQL> insert into t_num
  2  values (1, 234.4, 3225, 0.023);
已创建 1 行。
SQL> select * from t_num;
        C1         C2         C3         C4
---------- ---------- ---------- ----------
         1      234.4       3230       .023

虽然NUMBER类型和Oracle的NUMBER类型并不完全一致,但是二者对于精度和标度的描述还是一致的。不过Oracle如果NUMBER不指定精度,则默认是38,而在达梦中,默认是20。

SQL>insert into t_num values
2   (1234567890123456789012, 123.1);
insert into t_num values
(1234567890123456789012, 123.1)
数据溢出.error code = -2502
SQL>create table t_num2
2   (c1 number(*, 0));

第2行: '*'附近有语法错误,另外达梦中也不支持NUMBER(*, 0)的写法。达梦和SQLSERVER、SYBASE等数据库一样,对于表示整数的数据类型实现了自增列:

SQL>CREATE TABLE T_INC
2   (ID NUMBER(5, 0) IDENTITY (1, 2),
3   NAME VARCHAR);
CREATE TABLE T_INC
(ID NUMBER(5, 0) IDENTITY (1, 2),
NAME VARCHAR);
time used: 15.516(ms) clock tick:25924810.
SQL>INSERT INTO T_INC (NAME)
2   VALUES ('A');
INSERT INTO T_INC (NAME)
VALUES ('A')
1 rows affected
time used: 36.438(ms) clock tick:60908390.
SQL>INSERT INTO T_INC (NAME)
2   VALUES ('B');
INSERT INTO T_INC (NAME)
VALUES ('B')
1 rows affected
time used: 0.655(ms) clock t

[1] [2]  下一页


达梦数据库6.0之数据类型使用体验