写点什么

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:05905

评论 2 条评论

发布
用户头像
有postgresql, gp, 为什么要用openGauss?
2020 年 10 月 16 日 16:01
回复
只是做个备用吧
2020 年 10 月 18 日 12:30
回复
没有更多了
发现更多内容

做运维,送你7个常用的服务器资源监控工具

华为云开发者社区

工具 监控 内存 服务器 系统

架构师训练营第十三周

我是谁

架构师训练营第 1 期

探索压测奥妙

ninetyhe

分布式系统 压力测试 微服务治理 性能调试

VoltDB成功入选CNCF Landscape云原生数据库全景图

VoltDB

云原生 cncf VoltDB 分布式内存数据库

Filebeat同步写位点文件引发的磁盘IO问题

秦宝齐

ROMA Compose:ROMA的新武器

华为云开发者社区

数据 API ROMA

使用PG_SHOW_PLANS监控PostgreSQL执行计划

PostgreSQLChina

数据库 postgresql 开源

IoT爆发前夕,企业架构要面对哪些变革?

京东科技开发者

物联网

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

Mark

加密数字货币钱包系统软件开发|加密数字货币钱包APP开发

开發I852946OIIO

系统开发

腾讯高工亲授“MySQL学习方法”【思维导图+学习笔记+实战文档+面试题库】让你站在数据库领域的顶峰 笑傲江湖!

比伯

Java 编程 架构 面试 计算机

传统产业高成本低效率该怎么解决?物联网打辅助稳赚上千万!

一只数据鲸鱼

物联网 数据可视化 绿色交通 工业节能 绿色农业

单例设计模式

andy

年底了,你的数据库密码安全吗

Simon

MySQL 数据库

软件测试---BUG的生命周期

测试人生路

软件测试

Alibaba2020年度内部全技术栈PPT总结(基础+架构+算法+大数据+手册)

Crud的程序员

Java 架构 后端 技术栈

Vue 3 组件开发:搭建基于SpreadJS的表格编辑系统(功能拓展)

Geek_Willie

HTTP 请求流程

大导演

浏览器 HTTP 前端进阶训练营

换个角度,聊聊全链路压测

老张

团队管理 性能测试 系统稳定性 全链路压测

自学编程的4大误区,你中招了吗?

田维常

程序员

比易宝betBEB平台获278万美元约合1807万元融资

DT极客

算法学习手册

田维常

算法

再见 2020!Apache RocketMQ 发布 4.8.0,DLedger 模式全面提升!

阿里巴巴云原生

阿里云 开发者 云原生 存储 消息中间件

如何在 OpenShift 中运行 Collabora Office

东风微鸣

openshift

公安合成作战系统开发方案,重点人员大数据分析平台建设

WX13823153201

公安合成作战系统开发

Java多线程并发控制工具信号量Semaphore,实现原理及案例

码农架构

Java Java并发 并发编程 后端

云算力挖矿系统APP开发|云算力挖矿软件开发

开發I852946OIIO

系统开发

28天写作挑战——坚持28天,每天500字

TGO鲲鹏会

活动专区 28天写作

可用性、可维护性、可靠性有什么区别?

陈琦

DevOps 可用性 质量保障 可靠性

Java多线程并发控制工具CountDownLatch,实现原理及案例

码农架构

Java 并发编程 后端

一周信创舆情观察(2020.12.28~2021.1.3)

统小信uos

微服务架构下如何保证事务的一致性

微服务架构下如何保证事务的一致性

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