南大通用GBase8s数据库的create distinct type语句详解

原文链接:www.gbase.cn/community/p...

更多精彩内容尽在南大通用GBase技术社区,南大通用致力于成为用户最信赖的数据库产品供应商。

今天,我们将探讨使用CREATE DISTINCT TYPE语句来创建distinct数据类型(单值数据类型)。这种数据类型是基于现有的内置数据类型或其他已定义的复杂数据类型(如不透明类型、命名ROW类型或Distinct类型)创建的。Distinct数据类型与其源类型在物理存储上具有相同的表示法,但在逻辑上是完全独立的,它们不能直接进行比较或操作,除非通过显式强制转型。

CREATE DISTINCT TYPE 语句简介

语法图如下:

参数说明:

元素 描述 限制
distinct_type distinct数据类型声明的名称 在兼容ANSI的数据库中,所有者和数据类型的组合在数据库中必须是唯一的。在不兼容ANSI的数据库中,名称在数据库中的数据类型名称中必须是唯一的
source_type 新类型所基于的现有类型名称 必须为内置数据类型或用CREATE DISTINCT TYPE、CREATE OPAQUE TYPE或CREATE ROW TYPE语句创建的类型

使用说明

(1)Distinct类型是基于内置数据类型或现有不透明数据类型、命名ROW数据类型或其它Distinct数据类型创建的数据类型。Distinct数据类型是强归类的。虽然它与其源类型对数据有相同的物理表示法,但两种类型的值在没有显式强制转型的情况下无法进行比较。

(2)要创建Distinct数据类型,必须拥有对数据库的Resource权限。任何拥有Resource权限的用户均可从内置数据类型创建Distinct类型。

注意:不能在SERIAL、BIGSERIAL或SERIAL8数据类型上创建Distinct类型。

sql 复制代码
> CREATE DISTINCT TYPE test_serial AS SERIAL;

 9656: Cannot create a distinct type of type (serial)
Error in line 1
Near character position 41

要基于不透明类型、命名ROW类型或另一Distinct类型创建Distinct类型,必须是该数据类型的所有者 或对该数据类型拥有Usage权限

缺省情况下,定义了Distinct类型后,该Distinct类型的所有者和DBA可以使用它。Distinct类型的所有者可将对该Distinct类型的Usage权限授予其他用户。

(3)Distinct类型与其源类型有相同的存储结构。以下语句创建了基于内置DATE数据类型的Distinct类型birthday:

sql 复制代码
> CREATE DISTINCT TYPE birthday AS DATE;

Distinct type created.

虽然GBase8s对Distinct类型使用和它的源类型相同的存储格式,但Distinct类型与其源类型不能在一个操作中进行比较,除非显式强制转型到另一个类型。

如果包含了IF NOT EXISTS关键字,当指定名称的Distinct数据类型已经在当前数据库中定义过,则数据库服务器不采取任何操作(而不是向应用程序发送异常)。

sql 复制代码
> CREATE DISTINCT TYPE IF NOT EXISTS birthday AS DATE;
Distinct type created.

> CREATE DISTINCT TYPE birthday AS DATE;

 9996: Distinct type (gbasedbt.birthday) already exists in database.
Error in line 1
Near character position 36

对Distinct类型的权限

要创建Distinct类型,必须拥有对该数据库的Resource权限。创建Distinct类型的所有者对此类型拥有Usage权限。使用GRANT或REVOKE语句可以向其它数据库用户授予或收回Usage权限。

要找出特定类型上存在哪些特权,请在sysxtdtypes系统目录表中检查所有者名称,并在sysxtdtypeauth系统目录表中检查已授予的其它数据类型特权。有关系统目录表的更多信息,请参阅《GBase8sSQL指南:参考》。

DB-Access实用程序也可显示对Distinct类型的特权。

sysxtdtypes系统目录表

sysxtdtypes系统目录表中,存放了数据库中定义的每个 UDT(用户定义的数据类型),这些类型包括不透明和单值数据类型以及复杂数据类型(命名 ROW 类型、未命名 ROW 类型和 COLLECTION 类型)。参数说明如下:

类型 描述
extended_id serial 扩展数据类型的唯一标识代码
domain char(1) UDT的域代码
mode char(1) 对UDT进行分类的代码:B = 基本(不透明)类型C = 集合类型或未命名ROW类型D = 单值类型R = 命名ROW类型' '(空白)= 内置类型
owner char(32) UDT所有者的名称
name varchar(128,0) UDT的名称
type smallint 对UDT分类的代码
source integer sysxtdtypes引用(仅适用于单值类型)零(0)指示从内置数据类型创建了单值UDT。
maxlen integer 可变长度数据类型的最大长度零指示固定长度UDT。
length integer 固定长度数据类型的长度(以字节计);零指示可变长度UDT。
byvalue char(1) "T"= UDT通过值传递"F"= UDT不通过值传递
cannothash char(1) "T"= UDT可通过缺省散列函数散列"F"= UDT不可通过缺省函数散列
align smallint UDT的对齐方式(=1、2、4或8)
locator integer 未命名ROW类型的定位器键
pkg varchar(128,0) 定义该类型的包名

每个扩展数据类型都用唯一标识符(称为扩展标识符(extended_id))、数据标识符(type)以及长度和数据库类型的描述来作为特征。

对于使用内置数据类型创建的单值类型,type列代码对应于SYSCOLUMNS中列出的syscolumns.coltype列(指示源类型)的值,但要加上一个十六进制值0x0000800。文件$GBASEDBTDIR/incl/esql/sqltypes.h包含有关sysxtdtypes.type和syscolumns.coltype代码的信息。

示例如下:

sql 复制代码
> select * from sysxtdtypes where name='birthday';
extended_id  2048
domain
mode         D
owner        gbasedbt
name         birthday
type         2055
source       0
maxlen
length       4
byvalue      T
cannothash   F
align        1
locator      0
pkg

1 row(s) retrieved.

> select * from sysxtddesc where extended_id=2048;
extended_id  2048
seqno        1
description  date

1 row(s) retrieved.

支持函数和强制转型

当创建Distinct类型时,GBase8s自动定义两种显式强制转型:

(1)从Distinct类型到其源类型的强制转型

(2)从源类型到Distinct类型的强制转型

因为这两个数据类型具有相同的表示法(相同的长度和对齐方式),所以实现以上强制转型不需要支持函数。

可以在Distinct类型与其源类型之间创建隐式强制转型。要创建隐式强制转型,请使用Table Options子句来指定外部数据的格式。注意,需要先删除Distinct类型与其源类型之间的缺省显式强制转型。

在源类型上定义的所有支持函数和强制转型可用于Distinct类型,但对Distinct类型定义的强制转型和支持函数对源类型不可用。请使用Table Options子句指定外部数据的格式。

操纵Distinct类型

当将Distinct类型与其源类型进行比较或操纵它们的数据时,在以下情况中必须显式地将一种类型强制转型为另一类型:

(1)使用一种类型的值插入或更改另一类型的列。

(2)使用关系运算符来加、减、乘、除、比较或以其它方式操作两个值,其中一个是源类型,另一个是Distinct类型。

示例: 使用版本- GBase8sV8.8_TL_3.5.1_3X1_3

假设基于NUMERIC数据类型,创建了Distinct类型dist_type。然后创建带有两列的表tb1,一个属于dist_type类型,一个属于NUMERIC类型,如下所示:

sql 复制代码
> CREATE DISTINCT TYPE dist_type AS NUMERIC;
Distinct type created.

> CREATE TABLE tb1(col1 dist_type, col2 NUMERIC);
Table created.

> info columns for tb1;
Column name          Type                                    Nulls

col1                 dist_type                               yes
col2                 decimal(16)                             yes

要直接将Distinct类型与其源类型进行比较或者将源类型的值分配到Distinct类型的列上,必须将一种类型强制转型到其它类型,如下所示:

sql 复制代码
> INSERT INTO tb1 (col1) VALUES (3.5::dist_type);
1 row(s) inserted.

> INSERT INTO tb1 (col1, col2) VALUES (4.5::dist_type, 4.5);
1 row(s) inserted.

> INSERT INTO tb1 (col1, col2) VALUES (5.5,5.5);
 9632: Value does not match the type of column (col1).
Error in line 1
Near character position 44

> INSERT INTO tb1 (col1, col2) VALUES (5.5,5.5::dist_type);
 9632: Value does not match the type of column (col1).
Error in line 1
Near character position 55

> INSERT INTO tb1 (col1, col2) VALUES (5.5::dist_type,5.5);
1 row(s) inserted.

> UPDATE tb1 SET col1 = 4.8::dist_type WHERE col2 = 4.5;
1 row(s) updated.

> DELETE FROM tb1 WHERE col1::NUMERIC < 3.6;
1 row(s) deleted.

> SELECT col1, col2 FROM tb1 WHERE (col1::NUMERIC) > col2;

col1  4.8000000000000000
col2  4.50000000000000
1 row(s) retrieved.

> SELECT col1, col2, (col1 + col2::dist_type) sum_col , (col1::NUMERIC - col2) diff_col FROM tb1;

col1      4.8000000000000000
col2      4.50000000000000
sum_col   9.3000000000000000
diff_col  0.30000000000000

col1      5.5000000000000000
col2      5.50000000000000
sum_col   11.0000000000000000
diff_col  0.00000000000000

2 row(s) retrieved.

有关在本地数据库外的表内存取DISTINCT数据类型的查询和其它分布DML操作的信息,请参阅分布式操作中的DISTINCT类型。

如果您有任何进一步的修改意见或补充内容,欢迎随时提出。

原文链接:www.gbase.cn/community/p...

更多精彩内容尽在南大通用GBase技术社区,南大通用致力于成为用户最信赖的数据库产品供应商。

相关推荐
星迹日几秒前
MySQL:数据库设计
数据库·mysql
听闻风很好吃16 分钟前
Redis高级数据类型解析(二)——Set、Sorted Set与Geo实战指南
数据库·redis·缓存
小刘同学++17 分钟前
Qt 使用 MySQL 数据库的基本方法
数据库·qt·mysql
编程在手天下我有23 分钟前
缓存与数据库数据一致性:旁路缓存、读写穿透和异步写入模式解析
数据库·缓存·oracle·软件开发·架构设计·数据一致性
云攀登者-望正茂34 分钟前
Redis 及其在系统设计中的作用
数据库·redis·缓存
博睿谷IT99_1 小时前
PostgreSQL性能优化实用技巧‌
数据库·postgresql·性能优化
Leo.yuan1 小时前
数据仓库是什么?数据仓库架构有哪些?
大数据·数据库·数据仓库·架构·数据分析
云边有个稻草人1 小时前
【金仓数据库征文】从云计算到区块链:金仓数据库的颠覆性创新之路
数据库·云计算·区块链·金仓数据库 2025 征文·数据库平替用金仓·金仓数据库概述·金仓数据库的产品优化提案
冼紫菜2 小时前
基于Redis实现高并发抢券系统的数据同步方案详解
java·数据库·redis·后端·mysql·缓存·性能优化
屿暖_2 小时前
Rocky Linux 安装 PostgreSQL 数据库完整指南(2025版)
数据库