openGauss可替代Oracle吗?从字段类型说起……

2020 年 10 月 16 日

openGauss可替代Oracle吗?从字段类型说起……

本文由 dbaplus 社群授权转载。

背景

随着疫情及国际局势的不确定性增加,数据库作为系统运行中的关键组件,对于国产化数据库替换 Oracle 的呼声也越发高涨。国产数据库中 GaussDB 一直备受关注,去年华为宣布放弃私有云和数据库也引发了诸多争议;但另一方面,华为云在 6 月 30 日将原 GaussDB 100 开源为 openGauss,采用木兰开源协议,并与华为公有云 GaussDB for openGauss 采取共同迭代,为国内开源数据库市场带来了新的血液。

正文

作为 GaussDB 100 的延伸,openGauss 是否可以在 OLTP 场景替代 Oracle?从此篇开始,笔者会按照字段类型、表及索引类型、SQL 语法、函数、PLSQL、连接方式等方面逐一进行兼容性评估与相关阐述,可作为替换 Oracle 的借鉴与参考。

Oracle 数据库的字段总共包含 6 类:字符、数字、日期、大对象、ROWID、RAW。本次验证环境为 centos 7.6,基于 openGauss 1.0.0 版本对 Oracle 字段类型进行验证。

字符

Oracle 中包含 6 种字符类型:char、nchar、varchar、varchar2、nvarchar2、long。其中 char、varchar 为 ANSI 编码,用于单字节来存储数据,适合英文,中文会不兼容,nchar 及 nvarchar2 采用 UNICODE 编码,用两个字节来存储,适合存放汉字;char,nchar 为定长字段;varchar、varchar2、nvarchar2、LONG 为可变长字段,LONG 最大长度限制为 2GB,用于不需要作字符串搜索的长串数据,是一个遗留下来的而且将来不会被支持的数据类型,逐渐被 BLOB,CLOB,NCLOB 等大的数据类型所取代。varchar 是 SQL 标准里面规范的类型,varchar2 是 Oracle 提供的独有的数据类型,主要区别在于:

  • varchar 对于汉字占两个字节,对于数字,英文等是一个字节;varchar2 对数字、英文、汉字都占两个字节;
  • varchar 对空串不处理,varchar2 将空串当做 null 来处理;
  • openGauss 除了 LONG 类型外,对 Oracle 字符类型全部可以兼容,LONG 类型可用 CLOB 替代(见大对象兼容性验证)。验证结果如下:
  • CHAR
    postgres=# create table t_char(col CHAR(20));
    CREATE TABLE
  • NCHAR
    postgres=# create table t_nchar(col NCHAR(20));
    CREATE TABLE
  • VARCHAR
    postgres=# create table t_varchar(col VARCHAR(20));
    CREATE TABLE
  • VARCHAR2
    postgres=# create table t_varchar2(col VARCHAR2(20));
    CREATE TABLE
  • NVARCHAR2
    postgres=# create table t_nvarchar2(col NVARCHAR2(20));
    CREATE TABLE
  • LONG
    postgres=# create table t_long(col LONG);
    ERROR: type “long” does not exist
    LINE 1: create table t_long(col LONG);

数字

Oracle 包含 5 种数字类型:INT、NUMBER、FLOAT、BINARY_FLOAT、BINARY_DOUBLE。INT 为整型,NUMBER 为双精度浮点数,精度可以高达 38 位,它有两个限定符,如:column NUMBER(precision,scale)。precision 表示数字中的有效位。如果没有指定 precision 的话,Oracle 将使用 38 作为精度。scale 表示小数点右边的位数,scale 默认设置为 0。如果把 scale 设成负数,Oracle 将把该数字取舍到小数点左边的指定位数。Oracle 只是在语法上支持 decimal 类型,但是在底层实际上它就是 number 类型,支持 decimal 类型是为了能把数据从 Oracle 数据库移到其他数据库中。

BINARY_FLOAT 与 BINARY_DOUBLE 采用二进制精度,而 NUMBER 采用十进制精度,采用二进制精度能够减少占用的存储空间,提供更快的数学运算速度。BINARY_FLOAT 是 32 位的单精度浮点数字数据类型。每个值需要 5 字节存储空间,其中 1 字节用于存储数据值的长度。BINARY_DOUBLE 是 64 位的双精度浮点数字数据类型。每个值需要 9 字节存储空间,其中 1 字节用于存储数据值的长度。

除 BINARY_FLOAT 外,openGauss 兼容 Oracle 其他数字类型,BINARY_FLOAT 可以用 BINARY_DOUBLE 替代。验证结果如下:

  • int
    postgres=# create table t_int(col int);
    CREATE TABLE
  • number
    postgres=# create table t_number(col NUMBER);
    CREATE TABLE
  • float
    postgres=# create table t_float(col float);
    CREATE TABLE
  • BINARY_FLOAT
    postgres=# create table t_bfloat(col BINARY_FLOAT);
    ERROR: type “binary_float” does not exist
    LINE 1: create table t_bfloat(col BINARY_FLOAT);
  • BINARY_DOUBLE
    postgres=# create table t_bdouble(col BINARY_DOUBLE);
    CREATE TABLE

时间 & 日期

Oracle 包含 6 种时间及日期类型:DATE、TIMESTAMP、TIMESTAMP WITH TIME ZONE、TIMESTAMP WITH LOCAL TIME ZONE、INTERVAL YEAR TO MONTH、INTERVAL DAY TO SECOND。

DATE 是 Oracle 最常用的日期类型,常用日期处理都可以采用这种类型。DATE 表示的日期范围可以是公元前 4712 年 1 月 1 日至公元 9999 年 12 月 31 日。DATE 类型在数据库中的存储固定为 7 个字节, 第 1 字节:世纪 +100、 第 2 字节:年、第 3 字节:月、第 4 字节:天、第 5 字节:小时 +1、第 6 字节:分 +1、第 7 字节:秒 +1。

TIMESTAMP 与 DATE 的区别是不仅可以保存日期和时间,还能保存小数秒,小数位数可以指定为 0-9,默认为 6 位,所以最高精度 可以到 ns(纳秒),数据库内部用 7 或者 11 个字节存储,如果精度为 0,则用 7 字节存储,与 date 类型功能相同,如果精度大于 0 则用 11 字节存储。第 1 字节:世纪 +100、第 2 字节:年、第 3 字节:月、第 4 字节:天、 第 5 字节:小时 +1、第 6 字节:分 +1、第 7 字节:秒 +1、 第 8-11 字节:纳秒,采用 4 个字节存储,内部运算类型为整型。

TIMESTAMP WITH TIME ZONE 对 TIMESTAMP 进行了扩展,用于存储时区。时间戳以及时区位移值,其中 fractional_seconds_precision 是数字在第二日期时间字段的小数部分数字的所有值。可接受的值是 0 到 9。默认是 6。默认格式是确定明确的 NLS_DATE_FORMAT 参数或隐式的 NLS_TERRITORY 参数。大小固定为 13 字节。此数据类型包含日期时间字段 YEAR,MONTH,日,小时,分钟,秒 TIMEZONE_HOUR 和 TIMEZONE_MINUTE。它有一个明确的分数秒和时区。

TIMESTAMP WITH LOCAL TIME ZONE 在用户提交时间给数据库时,该类型会转换成数据库的时区来保存数据。默认格式是确定明确的 NLS_DATE_FORMAT 参数或隐式的 NLS_TERRITORY 参数。的大小不同的 7 至 11 个字节,取决于精度。

INTERVAL YEAR TO MONTH 存储期间年数和月的时间,其中 year_precision 是数字的年份日期时间字段的数量。可接受的值是 0 到 9。默认是 2。大小固定为 5 个字节。

Oracle 语法:INTERVAL YEAR [(year_precision )] TO MONTH,用来表示一段时间差, 只精确到年和月. year_precision 是数字年的时间段,接受的值为 0 到 9。默认值是 2。大小固定为 5 个字节。

INTERVAL DAY TO SECOND 格式为:INTERVAL DAY [(day_precision)] TO SECOND [(fractional_seconds)],是存储一段时间以天,小时,分钟和秒,其中 day_precision 是数字在 DAY 日期时间字段的最大数量。可接受的值是 0 到 9。默认是 2。fractional_seconds_precision 是数字中的第二个字段的小数部分的数量。可接受的值是 0 到 9。默认是 6。大小固定为 11 个字节。

除 TIMESTAMP WITH LOCAL TIME ZONE 外,openGauss 兼容其他日期及时间类型,TIMESTAMP WITH LOCAL TIME ZONE 可用 TIMESTAMP WITH TIME ZONE 替代,验证结果如下:

  • DATE
    postgres=# create table t_date(col DATE);
    CREATE TABLE
  • TIMESTAMP
    postgres=# create table t_timestamp(col TIMESTAMP);
    CREATE TABLE
  • TIMESTAMP WITH TIME ZONE
    postgres=# create table t_timezone(col TIMESTAMP WITH TIME ZONE);
    CREATE TABLE
  • TIMESTAMP WITH LOCAL TIME ZONE
    postgres=# create table t_localtimezone(col TIMESTAMP WITH LOCAL TIME ZONE);
    ERROR: syntax error at or near "WITH LOCAL"
    LINE 1: create table t_localtimezone(col TIMESTAMP WITH LOCAL TIME Z…
  • INTERVAL YEAR TO MONTH
    postgres=# create table t_interval_ym(col INTERVAL YEAR TO MONTH);
    CREATE TABLE
  • INTERVAL DAY TO SECOND
    postgres=# create table t_interval_ds(col INTERVAL DAY TO SECOND);
    CREATE TABLE

大对象

Oracle 包含 4 种大对象类型 BLOB、CLOB、NCLOB、BFILE,存储长度都为 4G。CLOB 与 NCLOB 适用于存储超长文本,CLOB 主要存储单字节字符型数据,NCLOB 存储多字节国家字符型数据。BLOB 存储二进制数据。适用于存储图像、视频、音频等。BFILE 在数据库外部保存的大型二进制对象文件,这种外部的 LOB 类型,通过数据库记录变化情况,但是数据的具体保存是在数据库外部进行的,Oracle 可以读取、查询 BFILE,但是不能写入,不参与事务。

openGasus 可以兼容 BLOB 及 CLOB 类型,无法兼容 NCLOB 及 BIFLE 类型,NCLOB 和 BFILE 可用 CLOB 及 BLOB 替代,验证结果如下:

  • BLOB
    postgres=# create table t_blob(col BLOB);
    CREATE TABLE
  • CLOB
    postgres=# create table t_clob(col CLOB);
    CREATE TABLE
  • NCLOB
    postgres=# create table t_nclob(col NCLOB);
    ERROR: type “nclob” does not exist
    LINE 1: create table t_nclob(col NCLOB);
  • BFILE
    postgres=# create table t_bfile(col BFILE);
    ERROR: type “bfile” does not exist
    LINE 1: create table t_bfile(col BFILE);

ROWID

ROWID 类型及 UROWID 类型为 Oracle 特有类型,ROWID 为该表行的唯一标识,是一个伪列。在表中创建 ROWID 数据类型的情况下,Oracle 不保证该值是合法的 ROWID,用户必须确保该 ROWID 值是真实合法的,UROWID 支持逻辑和物理的 ROWID。

openGauss 无法兼容 ROWID,由于 ROWID 字段 Oracle 并无验证合法机制,实际使用中可用 char(20) 替代,ROWID 兼容性的验证结果如下:

  • ROWID
    postgres=# create table t_rowid(col ROWID);
    ERROR: type “rowid” does not exist
    LINE 1: create table t_rowid(col ROWID);
  • UROWID
    postgres=# create table t_urowid(col UROWID);
    ERROR: type “urowid” does not exist
    LINE 1: create table t_urowid(col UROWID);

RAW

RAW 与 LONG RAW 中存储的为可变长二进制数据,是一种较老的数据类型,用这种格式来保存的图形文件或带格式的文本文件,如 Microsoft Word 文档。RAW 支持的最大长度为 2000,LONG RAW 最大长度是 2GB。将来会逐渐被 BLOB、CLOB、NCLOB 等大的对象数据类型所取代。

openGauss 可支持 RAW,但不支持 LONG RAW,遇到 LONG RAW 场景可用 BLOB 替代,验证结果如下:

postgres=# create table t_raw(col RAW(10));
CREATE TABLE
postgres=# create table t_longraw(col LONG RAW);
ERROR: syntax error at or near "RAW"
LINE 1: create table t_longraw(col LONG RAW);

总结

总体而言,openGauss 可全面兼容 Oracle 所有数据类型,对于常见数据类型无需进行改造,对于少数非常用数据类型,需要进行少量代码改造,可采取下列替代方案进行替换。

分类字段类型是否兼容替代方案
字符CHAR
NCHAR
VARCHAR
VARCHAR2
NVARCHAR2
LONG×CLOB
数字INT
FLOAT
NUMBER
BINARY_FLOAT×BINARY_DOUBLE
BINARY_DOUBLE
时间 & 日期DATE
TIMESTAMP
TIMESTAMP WITH TIME ZONE
TIMESTAMP WITH LOCAL TIME ZONE×TIMESTAMP WITH TIME ZONE
INTERVAL YEAR TO MONTH
INTERVAL DAY TO SECOND
大对象BLOB
CLOB
NCLOB×CLOB
BFILE×BLOB
ROWIDROWID×CHAR(20)
UROWID×CHAR(40)
RAWRAW
LONG RAW×BLOB

作者介绍

洪烨,openGauss Contributor,多年银行业系统架构设计及 DBA 实战经验,《DB2 数据库内部解析与性能调优》作者。

原文链接

openGauss 可替代 Oracle 吗?从字段类型说起……

2020 年 10 月 16 日 10:05 2

评论

发布
暂无评论
发现更多内容

第4周学习总结

嘻哈

进击的Serverless

傅轶

Kubernetes Knative Faas

第四周作业:互联网应用系统

Larry

Week04-总结

张磊

week4作业二

任鑫

架构

第四周-作业&总结

qh12346

架构师训练营 W4 作业

Kun

极客大学架构师训练营

架构师训练营 第四周 大型网站的架构概述1

极客

架构师训练营第四周心得

路人

极客大学架构师训练营

经济学家朱嘉明:2020年是区块链与产业结合的重要年份

CECBC区块链专委会

CECBC 区块链技术 应用落地 产业结合

学习总结 -- Week 4

吴炳华

极客大学架构师训练营

架构师训练营 W4 学习总结

Kun

极客大学架构师训练营

Week003 作业

徐培

架构师训练营第四周 - 作业

Lost Horizon

极客大学架构师训练营

架构师课程第四周总结

dongge

2020-06-27-第四周学习总结

路易斯李李李

网站架构进化史

dongge

架构培训 -04 学习总结 系统架构

刘敏

架构师训练营第四周 - 总结

Larry

一个典型的大型互联网应用系统使用了哪些技术方案和手段(四)

麻辣

架构师培训 -04 系统架构

刘敏

第四周学习总结

CP

第四周作业

Geek_2b3614

极客大学架构师训练营

架构师训练营第四周作业

talen

Week4作业总结

丿淡忘

极客大学架构师训练营

聊聊视频会议的昨天、今天和明天

拍乐云Pano

音视频 WebRTC 音视频会议 云服务 RTC

架构师训练营 - 第四周作业

teslə

互联网技术个人理解

嘻哈

Redis作者辞去Redis项目的领导者和维护者职务,对此你怎么看?

互联网架构师小马

数据库 redis 离职 Redis项目 Redis作者

第四周·互联网架构-总结

刘璐

大型互联网应用系统技术方案

张磊

openGauss可替代Oracle吗?从字段类型说起……-InfoQ