暂无图片
暂无图片
2
暂无图片
暂无图片
暂无图片

国产数据库实战|部署 KingbaseES:Oracle 兼容能力 + 多模实测

原创 shunwahⓂ️ 2025-10-02
785

探索国产数据库的创新之路,CentOS7 环境 KingbaseES V9R1C10 带来的
Oracle 兼容性与多模存储实战场景测试能力令人惊艳。

个人简介
作者: ShunWah
公众号: “顺华星辰运维栈”主理人。

持有认证: OceanBase OBCA/OBCP、MySQL OCP、OpenGauss、崖山 DBCA、亚信 AntDBCA、翰高 HDCA、GBase 8a | 8c | 8s、Galaxybase GBCA、Neo4j Graph Data Science Certification、NebulaGraph NGCI & NGCP、东方通 TongTech TCPE 等多项权威认证。
获奖经历: 在OceanBase&墨天轮征文大赛、OpenGauss、TiDB、YashanDB、Kingbase、KWDB 征文等赛事中多次斩获一、二、三等奖,原创技术文章常年被墨天轮、CSDN、ITPUB 等平台首页推荐。

  • 公众号_ID:顺华星辰运维栈
  • CSDN_ID: shunwahma
  • 墨天轮_ID:shunwah
  • ITPUB_ID: shunwah
  • IFClub_ID:shunwah

公众号首图制作 5.png

前言

随着数据库国产化浪潮的深入,企业对 “低成本迁移、高兼容适配” 的需求日益迫切 —— 尤其是长期依赖 Oracle 的用户,在迁移过程中面临着语法差异、功能不兼容、异构数据整合难三大核心痛点。北京人大金仓推出的 KingbaseES V9R1C10,以 “多语法兼容 + 多模存储一体化” 为核心创新点,既支持 Oracle、MySQL 等多数据库语法无缝切换,又能同时处理关系型、JSON 等异构数据,为国产化替代提供了 “一站式解决方案”。
本文以 CentOS7 为测试环境,围绕 KingbaseES 的 Oracle 兼容能力与多模存储特性展开实战测试:一方面验证 Oracle 核心功能(数据类型、序列触发器、分区表、物化视图等)的兼容度,另一方面测试 “关系型 + JSON” 多模数据的关联查询能力,最终为企业迁移决策提供可落地的技术参考,回答 “KingbaseES 能否满足 Oracle 业务迁移需求”“多模存储如何支撑异构数据场景” 两大核心问题。

一、 环境准备:安装包与系统配置

1.1 安装包准备与校验

本次测试使用 KingbaseES V9R1C10 企业版安装包,需先通过官方渠道获取安装文件与授权,再进行完整性校验,避免安装异常。

1.1.1 安装包文件清单

获取的文件包括:

  • 安装镜像:KingbaseES_V009R001C010B0004_Lin64_install.iso
  • 授权文件:license_V009R001C-企业版.dat

查看文件列表与 MD5 校验:

# 查看安装包与授权文件 ls # 计算安装包 MD5 值(用于与官网校验值对比) md5sum KingbaseES_V009R001C010B0004_Lin64_install.iso

图1-1:安装包文件列表与 MD5 校验

1.1.2 官网 MD5 校验对比

访问金仓官网对应版本下载页,对比本地计算的 MD5 值与官网提供的值,一致则说明安装包未损坏。
图1-2:官网 MD5 校验值对比

1.1.3 挂载 ISO 安装包

将 ISO 镜像挂载到指定目录,用于后续安装程序执行:

# 创建挂载目录 mkdir -p /mnt/kingbase # 查看目录创建结果 ls /mnt/ | grep kingbase # 挂载 ISO 镜像(-o loop 表示循环挂载) mount -o loop KingbaseES_V009R001C010B0004_Lin64_install.iso /mnt/kingbase # 查看挂载后的安装文件 cd /mnt/kingbase/ && ls

图1-3:创建挂载目录
图1-4:挂载 ISO 并查看文件

1.2 数据库运行用户与目录配置

为避免 root 用户直接运行数据库带来的安全风险,需创建专用的运行用户与目录,并配置权限。

1.2.1 创建用户组与用户

# 创建用户组 kingbase groupadd kingbase # 创建用户 kingbase 并加入同名组 useradd -g kingbase kingbase # 设置用户密码(输入命令后按提示输入密码,如 Kingbase@123) passwd kingbase

1.2.2 创建安装目录与数据目录

# 创建安装目录(存放数据库程序) mkdir -p /opt/kingbase/es/V9R1C10 # 创建数据目录(存放数据库实例数据) mkdir -p /data/kingbase/data # 授权目录给 kingbase 用户(确保用户有读写权限) chown -R kingbase:kingbase /opt/kingbase chown -R kingbase:kingbase /data/kingbase # 验证权限配置 ls -ld /opt/kingbase/es/V9R1C10/ /data/kingbase/data/

图1-5:创建目录并授权

2.1 KingbaseES 图形化安装:Oracle 兼容模式配置

切换用户并启动安装程序

# 切换到 kingbase 用户(必须用非 root 用户启动安装) su - kingbase # 查看当前用户(确认切换成功) whoami # 进入 ISO 挂载目录 cd /mnt/kingbase/ # 启动图形化安装程序(需服务器支持图形化界面或远程 X 工具) ./setup.sh

图2-1:切换到 kingbase 用户
图2-2:启动安装程序初始化

2.2 许可协议阅读与接受

安装程序启动后,需先阅读并接受许可协议,操作注意事项:

  1. 终端会显示 --more(Press [SPACE] to turn pages)--持续按空格键翻页(按回车键仅换行,不翻页);
  2. 翻完所有协议后,终端提示选择:Press [1] Accept, [2] Refuse, [3] Redisplay
  3. 输入 1 并回车,接受协议。

图2-3:许可协议接受选择

2.3 许可证文件配置

接受协议后,需指定授权文件路径(若无授权文件,将使用试用版):

# 终端提示输入许可证路径,示例: Please enter the path to the license file: [Default: ] /data/kingbase_oracle/license.dat # 输入授权文件实际路径

输入路径后,按提示输入 N 进入下一环节(N=NextP=PreviousQ=Exit)。

图2-4:许可证文件路径配置
图2-5:确认进入下一环节

2.4 安装路径选择

指定数据库程序的安装目录(需与 1.2.2 节创建的目录一致):

# 终端提示输入安装路径,示例: Please select an installation path. Default installation path: /opt/Kingbase/ES/V9 Enter an absolute path or press ENTER to accept the default path. [Default: /opt/Kingbase/ES/V9] /opt/kingbase/es/V9R1C10 # 输入自定义安装目录 # 确认路径:终端提示 Is that correct?(Y/N),输入 Y 确认

图2-6:安装路径配置与确认

2.5 安装组件选择

选择需要安装的组件,推荐选择 1-Full(完整安装)(包含 Oracle 兼容模块与多模存储功能):

# 终端显示组件选项: 1- Full(完整组件,推荐) 2- Server(仅数据库服务) 3- Custom(自定义组件) Input number of set or press [ENTER] accept default value [Default: 1] 1 # 输入 1 选择完整安装

图2-7:安装组件选择

2.6 快捷方式创建与安装完成

  1. 组件选择后,终端提示是否创建开始菜单快捷方式:Press [Y] Yes, [N] No: [Default: Y],输入 Y 确认;
  2. 等待安装进度完成(终端显示 Installation Success 100%);
  3. 安装完成后,终端会输出关键路径(如服务启动工具、文档路径等)。

图2-8:创建快捷方式确认
图2-9:安装完成与路径提示

3.1 数据库初始化:启用 Oracle 兼容模式

安装完成后,需通过命令行初始化数据库实例,并确保 Oracle 兼容模式生效(核心步骤)。
执行 initdb 命令,指定超级用户、数据目录,内置 Oracle 兼容配置:

# 切换到 kingbase 用户(若已切换可跳过) su - kingbase # 执行初始化命令 /opt/kingbase/es/V9R1C10/Server/bin/initdb -U system -W -D "/data/kingbase/data"
  • -U system:指定超级用户为 system(对齐 Oracle 习惯);
  • -W:强制提示输入超级用户密码;
  • -D "/data/kingbase/data":指定数据目录(与 1.2.2 节一致)。

初始化交互流程:

  1. 终端提示 Enter new superuser password:,输入密码(如 Kingbase@123);
  2. 再次提示 Enter it again:,重复输入密码确认;
  3. 初始化成功后,终端显示 Success. You can now start the database server using:

图3-1:数据库初始化与密码设置

3.2 启动数据库服务(解决权限问题)

首次启动可能因日志路径权限报错,需指定可写的日志路径:

# 错误示例:日志路径只读(/mnt 目录挂载为只读) /opt/kingbase/es/V9R1C10/Server/bin/sys_ctl -D /data/kingbase/data -l logfile start # 正确命令:指定数据目录下的日志文件(可写) /opt/kingbase/es/V9R1C10/Server/bin/sys_ctl \ -D /data/kingbase/data \ -l /data/kingbase/kingbase.log \ start

图3-2:启动服务报错(日志路径只读)
图3-3:正确启动服务

3.3 验证服务状态与端口占用

# 验证服务是否运行(显示 PID 即正常) /opt/kingbase/es/V9R1C10/Server/bin/sys_ctl -D /data/kingbase/data status # 验证默认端口 54321 是否占用(KingbaseES 默认端口) netstat -tulpn | grep 54321

图3-4:验证服务状态
图3-5:验证端口占用

4.1 Oracle 兼容模式验证

服务启动后,需登录数据库并验证 Oracle 兼容配置是否生效,确保后续测试环境正确。

# 使用超级用户 system 登录默认数据库 test /opt/kingbase/es/V9R1C10/Server/bin/ksql -U system -d test -h localhost # 输入密码后,终端提示符变为 test=#(登录成功)

图4-1:登录数据库

4.2 验证核心兼容参数

4.2.1 查看数据库兼容模式

-- 查看是否启用 Oracle 兼容模式(返回 oracle 即正确) show database_mode;

图4-2:验证数据库兼容模式

4.2.2 验证日期格式(对齐 Oracle)

-- 查看日期格式(Oracle 默认格式为 YYYY-MM-DD HH24:MI:SS) show nls_date_format; -- 测试 Oracle 特有函数 SYSDATE(返回当前日期时间) SELECT SYSDATE FROM dual;

图4-3:验证日期格式与 SYSDATE 函数

5.1 日常操作

至此,KingbaseES V9R1C10 已完成安装与 Oracle 兼容模式配置,后续可基于此环境进行:

  1. Oracle 数据类型兼容性测试(如 NUMBER、VARCHAR2、CLOB 等);
  2. SQL 语法兼容性测试(如分区表、物化视图、层次查询等);
  3. 多模存储测试(关系型+JSON 数据关联查询等)。

所有测试需确保连接方式正确,核心命令总结:

操作目标 命令示例
启动服务 sys_ctl -D /data/kingbase/data -l /data/kingbase/kingbase.log start
停止服务 sys_ctl -D /data/kingbase/data stop
登录数据库 ksql -U system -d test -h localhost -p 54321
验证兼容模式 show database_mode;

二、KingbaseES Oracle 兼容性实战测试

在完成 KingbaseES 安装与 Oracle 兼容模式配置后,本节通过实战场景验证其 Oracle 兼容性(含数据类型、语法、核心特性),并延伸至多模存储功能测试,确保满足企业从 Oracle 迁移及异构数据整合的需求。

2.1 数据库连接与测试库创建

首先通过 ksql 客户端连接数据库,并创建独立的测试库(避免影响默认库),所有兼容性测试均在测试库中进行。

2.1.1 数据库连接

使用默认管理员用户 kingbase 连接数据库,指定端口 54321(KingbaseES 默认端口):

[kingbase@d73372274f86 ~]$ ksql -U kingbase -d test -p 54321

连接成功后,终端会显示许可类型及 test=# 提示符,证明数据库服务正常。
图2-1:KingbaseES 数据库连接

2.1.2 创建 Oracle 兼容测试库

为隔离测试环境,创建专门的测试库 kingbase_oracle_test,指定 UTF-8 编码(对齐 Oracle 常见配置):

test=# CREATE DATABASE kingbase_oracle_test test-# ENCODING 'UTF8' -- 字符编码(兼容中文) test-# LC_COLLATE 'zh_CN.UTF-8' -- 排序规则 test-# LC_CTYPE 'zh_CN.UTF-8' -- 字符分类 test-# TEMPLATE template0; -- 基于空模板创建(避免继承默认库配置)

执行后显示 CREATE DATABASE 即创建成功。随后切换至测试库:

test=# \c kingbase_oracle_test -- 切换数据库(ksql 元命令)

切换成功后,提示符变为 kingbase_oracle_test=#,后续操作均在此库中执行。
图2-2:创建测试库
图2-3:切换至测试库

2.2 Oracle 兼容数据类型测试

Oracle 迁移的核心需求之一是数据类型兼容,KingbaseES 支持绝大多数 Oracle 原生类型,本节通过创建表、验证结构、查询数据字典三个步骤测试兼容性。

2.2.1 创建含 Oracle 类型的表

创建 employee 表,包含 NUMBERVARCHAR2DATECLOBBLOB 等 Oracle 核心类型,并使用 SYSDATE/SYSTIMESTAMP 内置函数(Oracle 特有):

kingbase_oracle_test=# CREATE TABLE employee ( kingbase_oracle_test(# emp_id NUMBER(10) PRIMARY KEY, -- 数字类型(Oracle 兼容) kingbase_oracle_test(# emp_name VARCHAR2(50) NOT NULL, -- 字符串类型(Oracle 兼容) kingbase_oracle_test(# salary NUMBER(10,2), -- 带小数的数字类型 kingbase_oracle_test(# hire_date DATE DEFAULT SYSDATE, -- 日期类型(默认当前日期) kingbase_oracle_test(# resume CLOB, -- 大文本类型(Oracle 兼容) kingbase_oracle_test(# photo BLOB, -- 二进制大对象类型 kingbase_oracle_test(# create_time TIMESTAMP DEFAULT SYSTIMESTAMP -- 时间戳类型 kingbase_oracle_test(# );

执行后显示 CREATE TABLE 即表创建成功,证明 Oracle 数据类型与内置函数兼容。
图2-4:创建 employee 表

2.2.2 验证表结构

通过两种方式验证表结构:KingbaseES 原生命令与 Oracle 兼容数据字典视图。

方式1:KingbaseES 原生命令(直观)

使用 \d 元命令查看表结构:

kingbase_oracle_test=# \d employee;

结果会显示字段名、类型、默认值及索引信息,例如 hire_date 的默认值为 sysdate()create_timesystimestamp(),与 Oracle 行为一致。
图2-5:用 \d 查看表结构

方式2:Oracle 兼容数据字典(贴近迁移习惯)

KingbaseES 提供与 Oracle 一致的数据字典视图(如 user_tablesuser_tab_columns),但需注意 Oracle 兼容模式下表名默认大写,需用大写表名查询:

-- 1. 确认表存在(忽略大小写,避免因大小写问题查不到结果) kingbase_oracle_test=# SELECT table_name FROM user_tables WHERE table_name ILIKE 'employee'; -- 2. 查看表字段详情(Oracle 风格,表名需大写) kingbase_oracle_test=# SELECT kingbase_oracle_test-# column_name, -- 字段名 kingbase_oracle_test-# data_type, -- 数据类型 kingbase_oracle_test-# data_length, -- 长度 kingbase_oracle_test-# data_precision, -- 精度(数字类型) kingbase_oracle_test-# data_scale, -- 小数位(数字类型) kingbase_oracle_test-# nullable -- 是否允许为空 kingbase_oracle_test-# FROM user_tab_columns kingbase_oracle_test-# WHERE table_name = 'EMPLOYEE'; -- 表名大写

结果会显示 EMP_IDNUMERIC 类型、EMP_NAMEVARCHAR 类型,与 Oracle 数据字典输出格式一致,降低迁移后的操作成本。
图2-6:确认表存在
图2-7:查询表字段详情

2.2.3 查看主键约束

通过 PostgreSQL 系统表查询主键约束(KingbaseES 基于 PostgreSQL 内核,兼容其系统表查询逻辑):

kingbase_oracle_test=# SELECT kingbase_oracle_test-# pg_constraint.conname AS constraint_name, -- 约束名 kingbase_oracle_test-# pg_attribute.attname AS column_name, -- 字段名 kingbase_oracle_test-# 'P' AS constraint_type -- 约束类型(P=主键,对齐 Oracle) kingbase_oracle_test-# FROM pg_constraint kingbase_oracle_test-# JOIN pg_class ON pg_constraint.conrelid = pg_class.oid kingbase_oracle_test-# JOIN pg_attribute ON pg_constraint.conrelid = pg_attribute.attrelid kingbase_oracle_test-# AND pg_attribute.attnum = ANY(pg_constraint.conkey) kingbase_oracle_test-# WHERE kingbase_oracle_test-# pg_class.relname = 'employee' -- 表名(小写,PostgreSQL 系统表默认小写) kingbase_oracle_test-# AND pg_constraint.contype = 'p'; -- p=主键约束

结果会显示 employee_pkey 为主键约束,关联 emp_id 字段,符合 Oracle 主键约束的定义逻辑。
图2-8:查询主键约束

2.3 补充 Oracle 特有类型测试

部分 Oracle 类型(如 RAWUROWID)在 KingbaseES 中无直接对应类型,需用等效类型替代(功能一致),本节测试替代方案的兼容性。

2.3.1 创建含替代类型的表

BYTEA 替代 RAW(二进制类型)、TEXTUROWID 替代 Oracle UROWID,创建 oracle_compatibility_test 表:

kingbase_oracle_test=# CREATE TABLE oracle_compatibility_test ( kingbase_oracle_test(# id NUMBER(8) PRIMARY KEY, -- 主键 kingbase_oracle_test(# char_col CHAR(20), -- Oracle CHAR 类型 kingbase_oracle_test(# nchar_col NCHAR(20), -- Oracle NCHAR 类型(Unicode) kingbase_oracle_test(# nvarchar_col NVARCHAR2(100), -- Oracle NVARCHAR2 类型 kingbase_oracle_test(# binary_float_col BINARY_FLOAT, -- Oracle 单精度浮点 kingbase_oracle_test(# binary_double_col BINARY_DOUBLE, -- Oracle 双精度浮点 kingbase_oracle_test(# raw_col BYTEA, -- 替代 Oracle RAW 类型 kingbase_oracle_test(# timestamp_tz TIMESTAMP WITH TIME ZONE, -- 带时区时间戳 kingbase_oracle_test(# urowid_col TEXT -- 替代 Oracle UROWID 类型 kingbase_oracle_test(# );

执行后显示 CREATE TABLE 即成功,证明替代类型的兼容性。
图2-9:创建 oracle_compatibility_test 表

2.3.2 插入测试数据

插入包含各类 Oracle 兼容类型的数据,验证插入逻辑:

-- 插入 employee 表数据 INSERT INTO employee (emp_id, emp_name, salary) VALUES (1, '张三', 5000.00); -- 插入 oracle_compatibility_test 表数据(含替代类型) INSERT INTO oracle_compatibility_test ( id, char_col, nchar_col, nvarchar_col, varchar2_col, binary_float_col, binary_double_col, raw_col, timestamp_col, timestamp_tz, timestamp_ltz, interval_year_col, interval_day_col, urowid_col, clob_col, blob_col ) VALUES ( 1, 'CHAR数据', N'NCHAR数据', -- NCHAR 类型需加 N 前缀(Unicode) N'NVARCHAR2中文数据', 'VARCHAR2测试数据', 3.14, -- BINARY_FLOAT 类型 3.14159265358979, -- BINARY_DOUBLE 类型 E'\\x48656C6C6F576F726C64'::BYTEA, -- BYTEA 类型(十六进制) SYSTIMESTAMP, -- 时间戳函数(Oracle 兼容) SYSTIMESTAMP, SYSTIMESTAMP, INTERVAL '2-6' YEAR TO MONTH, -- 年月间隔类型 INTERVAL '5 12:30:45.123' DAY TO SECOND, -- 日时分秒间隔类型 'AAASEIAABAAAO2TAAA', -- UROWID 替代值 '这是一个CLOB大文本字段的测试内容...', -- CLOB 类型 E'\\x424C4F42'::BYTEA -- BLOB 类型(十六进制) ); -- 提交事务(Oracle 兼容的事务处理) COMMIT;

插入成功后显示 INSERT 0 1,事务提交时若提示“无事务进行”(WARNING: there is no transaction in progress),属正常现象(KingbaseES 默认自动提交)。
图2-10:插入 oracle_compatibility_test 数据
图2-11:提交事务

2.4 Oracle 风格序列与触发器测试

Oracle 常用“序列+触发器”实现自动编号,KingbaseES 支持该逻辑,但触发器语法需微调(基于 PostgreSQL 规范),本节测试该场景。

2.4.1 创建 Oracle 风格序列

创建从 100 开始、步长为 1 的序列(与 Oracle CREATE SEQUENCE 语法一致):

kingbase_oracle_test=# CREATE SEQUENCE test_seq START WITH 100 INCREMENT BY 1;

执行后显示 CREATE SEQUENCE 即成功。
图2-12:创建序列

2.4.2 创建带触发器的表

创建 auto_id_test 表,通过触发器调用序列实现自动编号:

-- 1. 创建表 kingbase_oracle_test=# CREATE TABLE auto_id_test ( kingbase_oracle_test(# id NUMBER(8) PRIMARY KEY, -- 自动编号字段 kingbase_oracle_test(# name VARCHAR2(50), -- 名称字段 kingbase_oracle_test(# create_time TIMESTAMP DEFAULT SYSTIMESTAMP -- 默认时间戳 kingbase_oracle_test(# ); -- 2. 创建触发器函数(KingbaseES 需先定义函数,再绑定触发器) kingbase_oracle_test=# CREATE OR REPLACE FUNCTION auto_id_trigger_func() kingbase_oracle_test-# RETURNS TRIGGER AS $$ kingbase_oracle_test$# BEGIN kingbase_oracle_test$# IF NEW.id IS NULL THEN -- 若 id 为空,自动填充序列值 kingbase_oracle_test$# NEW.id := nextval('test_seq'); -- 调用序列(Oracle 用 test_seq.NEXTVAL) kingbase_oracle_test$# END IF; kingbase_oracle_test$# RETURN NEW; kingbase_oracle_test$# END; kingbase_oracle_test$# $$ LANGUAGE plpgsql; -- 3. 创建触发器(绑定函数,BEFORE INSERT 触发) kingbase_oracle_test=# CREATE TRIGGER auto_id_trigger kingbase_oracle_test-# BEFORE INSERT ON auto_id_test kingbase_oracle_test-# FOR EACH ROW -- 行级触发器(与 Oracle 一致) kingbase_oracle_test-# EXECUTE FUNCTION auto_id_trigger_func(); -- 调用触发器函数

注意:KingbaseES 触发器语法为 EXECUTE FUNCTION,而非 Oracle 的 BEGIN ... END,但逻辑完全一致。
图2-13:创建 auto_id_test 表
图2-14:创建触发器函数
图2-15:创建触发器

2.4.3 测试自动编号功能

插入数据时不指定 id,验证触发器是否自动填充序列值:

-- 插入数据(不指定 id) INSERT INTO auto_id_test (name) VALUES ('测试用户1'); INSERT INTO auto_id_test (name) VALUES ('测试用户2'); -- 查看结果 SELECT * FROM auto_id_test;

结果显示 id 自动填充为 100、101(序列从 100 开始),与 Oracle“序列+触发器”的自动编号效果一致。
图2-16:插入测试数据
图2-17:验证自动编号结果

2.5 Oracle 内置函数与层次查询测试

Oracle 迁移需兼容其特有函数(如 SYSDATE)与语法(如 CONNECT BY 层次查询),本节验证这些核心功能。

2.5.1 测试 Oracle 内置函数

执行 Oracle 常用内置函数,验证返回结果是否符合预期:

kingbase_oracle_test=# SELECT kingbase_oracle_test-# SYSDATE AS current_date, -- 当前日期(Oracle 特有) kingbase_oracle_test-# SYSTIMESTAMP AS current_timestamp,-- 当前时间戳(Oracle 特有) kingbase_oracle_test-# UID AS user_id, -- 当前用户 ID kingbase_oracle_test-# USER AS current_user, -- 当前用户名 kingbase_oracle_test-# ROWNUM AS row_number -- 行号(Oracle 特有) kingbase_oracle_test-# FROM DUAL; -- 虚表(Oracle 兼容,KingbaseES 支持)

结果显示 SYSDATE 返回当前日期、SYSTIMESTAMP 返回带时区的时间戳,与 Oracle 函数行为完全一致。
图2-18:测试 Oracle 内置函数

2.5.2 测试层次查询(CONNECT BY)

Oracle 用 CONNECT BY 实现层级数据查询(如组织架构),KingbaseES 支持该语法,测试如下:

-- 1. 创建层级表(员工-经理关系) kingbase_oracle_test=# CREATE TABLE employee_hierarchy ( kingbase_oracle_test(# emp_id NUMBER PRIMARY KEY, kingbase_oracle_test(# emp_name VARCHAR2(50), kingbase_oracle_test(# manager_id NUMBER REFERENCES employee_hierarchy(emp_id) -- 自关联(经理 ID) kingbase_oracle_test(# ); -- 2. 插入层级数据(CEO→经理→员工) INSERT INTO employee_hierarchy VALUES (1, 'CEO', NULL); INSERT INTO employee_hierarchy VALUES (2, '经理A', 1); INSERT INTO employee_hierarchy VALUES (3, '员工A1', 2); INSERT INTO employee_hierarchy VALUES (4, '员工A2', 2); COMMIT; -- 3. 执行层次查询(Oracle CONNECT BY 语法) kingbase_oracle_test=# SELECT kingbase_oracle_test-# LPAD(' ', 2*(LEVEL-1)) || emp_name AS org_chart, -- 缩进显示层级 kingbase_oracle_test-# LEVEL, -- 层级深度(1=顶层) kingbase_oracle_test-# SYS_CONNECT_BY_PATH(emp_name, '/') AS path -- 层级路径(Oracle 特有) kingbase_oracle_test-# FROM employee_hierarchy kingbase_oracle_test-# START WITH manager_id IS NULL -- 顶层节点(无经理的 CEO) kingbase_oracle_test-# CONNECT BY PRIOR emp_id = manager_id; -- 关联条件(父节点 emp_id = 子节点 manager_id)

结果显示层级结构(CEO 为顶层,经理A 为第二层,员工A1/A2 为第三层),SYS_CONNECT_BY_PATH 生成完整路径,与 Oracle 层次查询结果一致。
图2-19:创建层级表
图2-20:插入层级数据
图2-21:层次查询结果

2.6 Oracle 核心特性:分区表与物化视图测试

分区表(提升大数据查询性能)和物化视图(预计算结果以加速查询)是 Oracle 核心特性,KingbaseES 完全兼容其语法与逻辑,本节重点测试。

2.6.1 RANGE 分区表测试

创建按日期范围分区的 sales_data 表(Oracle 最常用的分区类型):

kingbase_oracle_test=# CREATE TABLE sales_data ( kingbase_oracle_test(# sale_id NUMBER PRIMARY KEY, -- 销售 ID kingbase_oracle_test(# sale_date DATE, -- 销售日期(分区键) kingbase_oracle_test(# amount NUMBER(10,2), -- 销售金额 kingbase_oracle_test(# region VARCHAR2(50) -- 销售区域 kingbase_oracle_test(# ) PARTITION BY RANGE (sale_date) ( -- 按 sale_date 范围分区 kingbase_oracle_test(# PARTITION p2023_q1 VALUES LESS THAN (DATE '2023-04-01'), -- 2023Q1 kingbase_oracle_test(# PARTITION p2023_q2 VALUES LESS THAN (DATE '2023-07-01'), -- 2023Q2 kingbase_oracle_test(# PARTITION p2023_q3 VALUES LESS THAN (DATE '2023-10-01'), -- 2023Q3 kingbase_oracle_test(# PARTITION p2023_q4 VALUES LESS THAN (DATE '2024-01-01') -- 2023Q4 kingbase_oracle_test(# );

执行后显示 CREATE TABLE 即分区表创建成功,语法与 Oracle 完全一致。
图2-22:创建 RANGE 分区表

验证分区配置与数据路由
  1. 查看分区信息:通过原生命令与 Oracle 兼容视图验证分区:

    -- 方式1:KingbaseES 原生命令(直观) kingbase_oracle_test=# \d+ sales_data; -- 方式2:Oracle 兼容视图(user_tab_partitions) kingbase_oracle_test=# SELECT kingbase_oracle_test-# table_name, kingbase_oracle_test-# partition_name, kingbase_oracle_test-# high_value, -- 分区上限值(如 '2023-04-01') kingbase_oracle_test-# tablespace_name kingbase_oracle_test-# FROM user_tab_partitions kingbase_oracle_test-# WHERE table_name = 'SALES_DATA'; -- 表名大写

    结果显示 4 个分区的上限值与配置一致,证明分区规则生效。
    图2-23:原生方式查看分区
    图2-24:Oracle 视图查看分区

  2. 测试数据自动路由:插入不同日期的数据,验证是否自动写入对应分区:

    -- 插入 4 个分区的数据 INSERT INTO sales_data (sale_id, sale_date, amount, region) VALUES (1, DATE '2023-02-15', 1000.50, '华北'), -- 2023Q1(p2023_q1) (2, DATE '2023-05-20', 2500.80, '华东'), -- 2023Q2(p2023_q2) (3, DATE '2023-09-30', 1800.00, '华南'), -- 2023Q3(p2023_q3) (4, DATE '2023-12-10', 3200.20, '西北'); -- 2023Q4(p2023_q4) -- 按分区查询(只查 p2023_q2,验证路由是否正确) SELECT * FROM sales_data PARTITION (p2023_q2);

    结果仅返回 sale_date=2023-05-20 的数据(p2023_q2 分区),证明数据自动路由生效。
    图2-25:插入分区数据
    图2-26:按分区查询数据

  3. 验证分区扫描性能:查看执行计划,确认查询仅扫描目标分区(而非全表):

    kingbase_oracle_test=# EXPLAIN ANALYZE kingbase_oracle_test-# SELECT * FROM sales_data WHERE sale_date BETWEEN '2023-04-01' AND '2023-06-30';

    执行计划显示 Seq Scan on sales_data_p2023_q2,证明仅扫描 p2023_q2 分区,与 Oracle 分区表的性能优化逻辑一致。
    图2-27:查看分区扫描执行计划

2.6.2 物化视图测试

创建 Oracle 风格的物化视图(按需完全刷新),验证数据同步逻辑:

-- 1. 创建物化视图(按销售区域分组统计) kingbase_oracle_test=# CREATE MATERIALIZED VIEW mv_employee_summary kingbase_oracle_test-# REFRESH COMPLETE ON DEMAND -- 完全刷新,手动触发(Oracle 语法) kingbase_oracle_test-# AS kingbase_oracle_test-# SELECT kingbase_oracle_test-# region, -- 销售区域 kingbase_oracle_test-# COUNT(sale_id) AS total_sales, -- 销售次数 kingbase_oracle_test-# SUM(amount) AS total_amount, -- 销售总金额 kingbase_oracle_test-# AVG(amount) AS avg_amount -- 平均金额 kingbase_oracle_test-# FROM sales_data kingbase_oracle_test-# GROUP BY region; -- 2. 查看初始数据 SELECT * FROM mv_employee_summary; -- 3. 更新源表数据(模拟业务变化) UPDATE sales_data SET amount = 2800.80 WHERE sale_id = 2; -- 华东区域金额从 2500.80 改为 2800.80 COMMIT; -- 4. 刷新物化视图(KingbaseES 用 REFRESH 命令替代 Oracle 的 DBMS_MVIEW.REFRESH) kingbase_oracle_test=# REFRESH MATERIALIZED VIEW mv_employee_summary; -- 5. 验证刷新结果 SELECT * FROM mv_employee_summary;

关键说明:

  • Oracle 用 DBMS_MVIEW.REFRESH('mv_employee_summary', 'C') 刷新,KingbaseES 简化为 REFRESH MATERIALIZED VIEW,逻辑完全一致;
  • 刷新后,华东区域的 total_amount 从 2500.80 变为 2800.80,证明数据同步正常。
    图2-28:创建物化视图
    图2-29:查看初始物化视图数据
    图2-30:更新源表数据
    图2-31:刷新物化视图
    图2-32:验证刷新结果

三、KingbaseES 多模存储实战测试

KingbaseES 支持“关系型+JSON”等多模存储,可同时处理结构化与半结构化数据,并支持跨类型关联查询。本节通过实战验证其多模融合能力。

3.1 关系型数据存储测试

关系型存储是 KingbaseES 的核心能力,本节创建规范化表结构(含外键、索引),验证数据一致性与查询性能。

3.1.1 创建规范化表与索引

创建 departments(部门表)和 employees(员工表),通过外键关联保证数据一致性,并创建索引优化查询:

-- 1. 创建部门表(主表) kingbase_oracle_test=# CREATE TABLE departments ( kingbase_oracle_test(# dept_id NUMBER(10) PRIMARY KEY, -- 部门 ID(主键) kingbase_oracle_test(# dept_name VARCHAR2(50) NOT NULL, -- 部门名称(非空) kingbase_oracle_test(# location VARCHAR2(100) -- 部门位置 kingbase_oracle_test(# ); -- 2. 创建员工表(从表,外键关联部门表) kingbase_oracle_test=# CREATE TABLE employees ( kingbase_oracle_test(# emp_id NUMBER(10) PRIMARY KEY, -- 员工 ID(主键) kingbase_oracle_test(# emp_name VARCHAR2(50) NOT NULL, -- 员工姓名(非空) kingbase_oracle_test(# email VARCHAR2(100), -- 邮箱 kingbase_oracle_test(# phone VARCHAR2(20), -- 电话 kingbase_oracle_test(# hire_date DATE DEFAULT SYSDATE, -- 入职日期(默认当前时间) kingbase_oracle_test(# salary NUMBER(10,2), -- 薪资 kingbase_oracle_test(# dept_id NUMBER(10), -- 关联部门 ID(外键) kingbase_oracle_test(# CONSTRAINT fk_emp_dept FOREIGN KEY (dept_id) REFERENCES departments(dept_id) -- 外键约束 kingbase_oracle_test(# ); -- 3. 创建索引(优化查询性能) CREATE INDEX idx_emp_name ON employees(emp_name); -- 按姓名查询 CREATE INDEX idx_emp_dept ON employees(dept_id); -- 按部门关联查询 CREATE INDEX idx_emp_hire_date ON employees(hire_date); -- 按入职日期查询

执行后显示 CREATE TABLECREATE INDEX,证明表与索引创建成功。
图3-1:创建 departments 表
图3-2:创建 employees 表
图3-3:创建索引

3.1.2 插入数据与关联查询

插入部门与员工数据,验证外键约束与关联查询逻辑:

-- 1. 插入部门数据(主表需先插入,避免外键约束报错) INSERT INTO departments (dept_id, dept_name, location) VALUES (1, '技术部', '北京'), (2, '产品部', '上海'), (3, '销售部', '广州'); -- 2. 插入员工数据(关联已存在的 dept_id) INSERT INTO employees (emp_id, emp_name, email, phone, salary, dept_id) VALUES (101, '张三', 'zhangsan@test.com', '13800138001', 8000.00, 1), -- 技术部 (102, '李四', 'lisi@test.com', '13800138002', 9500.00, 2), -- 产品部 (103, '王五', 'wangwu@test.com', '13800138003', 7500.00, 1); -- 技术部 -- 3. 关联查询(员工+部门信息) SELECT e.emp_id, e.emp_name, e.salary, d.dept_name, d.location FROM employees e LEFT JOIN departments d ON e.dept_id = d.dept_id;

结果显示员工与对应部门的关联信息(如张三属于技术部,地点北京),证明外键约束与关联查询正常。
图3-4:插入部门数据
图3-5:插入员工数据
图3-6:关联查询结果

3.2 JSON 文档存储测试

KingbaseES 支持 JSONB 类型(二进制 JSON,高效查询与更新),适合存储半结构化数据(如用户画像、日志)。本节测试 JSON 数据的插入、查询、更新与统计。

3.2.1 创建 JSON 数据表

创建 json_documents 表,用 JSONB 类型存储半结构化数据:

kingbase_oracle_test=# CREATE TABLE json_documents ( kingbase_oracle_test(# doc_id NUMBER(10) PRIMARY KEY, -- 文档 ID(主键) kingbase_oracle_test(# doc_data JSONB, -- JSONB 类型(高效存储与查询) kingbase_oracle_test(# created_time TIMESTAMP DEFAULT SYSTIMESTAMP -- 创建时间 kingbase_oracle_test(# );

执行后显示 CREATE TABLE 即成功。
图3-7:创建 JSON 数据表

3.2.2 插入 JSON 数据

插入包含嵌套对象(contact)、数组(skillsprojects)的 JSON 数据:

INSERT INTO json_documents (doc_id, doc_data) VALUES ( 1, '{ "name": "赵六", "age": 28, "department": "技术部", "skills": ["Java", "Python", "KingbaseES"], -- JSON 数组 "projects": [ -- 嵌套 JSON 数组 {"name": "电商系统", "role": "开发工程师", "start_time": "2023-01-10"}, {"name": "数据分析平台", "role": "核心开发", "start_time": "2024-03-01"} ], "contact": { -- 嵌套 JSON 对象 "email": "zhaoliu@test.com", "phone": "13800138006", "address": {"city": "深圳", "district": "南山区"} } }'::JSONB -- 显式指定为 JSONB 类型 );

执行后显示 INSERT 0 1,证明 JSON 数据插入成功(支持嵌套与数组结构)。
图3-8:插入 JSON 数据

3.2.3 JSON 数据查询与操作

1. 按 JSON 字段过滤

@> 运算符(JSONB 包含查询)筛选“技术部”的文档:

kingbase_oracle_test=# SELECT doc_id FROM json_documents kingbase_oracle_test-# WHERE doc_data @> '{"department": "技术部"}';

结果返回 doc_id=1,证明过滤逻辑正常。
图3-9:按 JSON 字段过滤

2. 提取 JSON 字段(嵌套与数组)

->> 提取字段(转为字符串)、-> 提取嵌套对象,支持多层嵌套提取:

-- 提取顶层字段、嵌套对象字段 kingbase_oracle_test=# SELECT kingbase_oracle_test-# doc_data->>'name' AS emp_name, -- 顶层字段(姓名) kingbase_oracle_test-# doc_data->'contact'->>'email' AS email, -- 嵌套对象(邮箱) kingbase_oracle_test-# doc_data->'contact'->'address'->>'city' AS city -- 多层嵌套(城市) kingbase_oracle_test-# FROM json_documents; -- 展开 JSON 数组(skills 列表,每行显示一个技能) kingbase_oracle_test=# SELECT kingbase_oracle_test-# doc_data->>'name' AS emp_name, kingbase_oracle_test-# jsonb_array_elements_text(doc_data->'skills') AS skill -- 展开数组(JSONB 专用函数) kingbase_oracle_test-# FROM json_documents;

结果显示正确提取姓名、邮箱、城市,且 skills 数组被展开为多行,符合半结构化数据的查询需求。
图3-10:提取 JSON 字段
图3-11:展开 JSON 数组

3. 统计 JSON 数组数据

结合 jsonb_array_elements_textGROUP BY,统计技能分布(生产场景常用):

kingbase_oracle_test=# SELECT kingbase_oracle_test-# skill, kingbase_oracle_test-# COUNT(*) AS skill_count -- 统计每个技能的出现次数 kingbase_oracle_test-# FROM json_documents, kingbase_oracle_test-# jsonb_array_elements_text(doc_data->'skills') AS skill kingbase_oracle_test-# GROUP BY skill kingbase_oracle_test-# ORDER BY skill_count DESC;

结果显示每个技能出现 1 次(当前仅一条数据),证明 JSON 数组统计逻辑正常。
图3-12:统计 JSON 数组数据

4. 更新 JSON 字段

jsonb_set 函数更新 JSON 中的指定字段(如将年龄从 28 改为 29):

-- 更新 age 字段 kingbase_oracle_test=# UPDATE json_documents kingbase_oracle_test-# SET doc_data = jsonb_set( kingbase_oracle_test(# doc_data, -- 目标 JSONB 字段 kingbase_oracle_test(# '{age}', -- 字段路径(顶层 age) kingbase_oracle_test(# '29' -- 新值(数字无需加引号) kingbase_oracle_test(# ) kingbase_oracle_test-# WHERE doc_id = 1; -- 验证更新结果 SELECT doc_data->>'name' AS emp_name, doc_data->>'age' AS new_age FROM json_documents WHERE doc_id = 1;

结果显示 new_age=29,证明 JSON 字段更新成功。
图3-13:更新 JSON 字段
图3-14:验证 JSON 更新结果

3.3 多模数据关联查询(核心能力)

多模存储的关键是“跨类型数据融合”,本节将关系型表 employees 与 JSON 表 json_documents 关联,查询“技术部所有人员”,验证多模融合能力:

kingbase_oracle_test=# SELECT kingbase_oracle_test-# '关系型员工' AS data_source, -- 标记数据来源(关系型) kingbase_oracle_test-# e.emp_name, kingbase_oracle_test-# e.salary, kingbase_oracle_test-# d.dept_name kingbase_oracle_test-# FROM employees e kingbase_oracle_test-# JOIN departments d ON e.dept_id = d.dept_id kingbase_oracle_test-# WHERE d.dept_name = '技术部' kingbase_oracle_test-# UNION ALL -- 合并结果(不去重) kingbase_oracle_test-# SELECT kingbase_oracle_test-# 'JSON 文档' AS data_source, -- 标记数据来源(JSON) kingbase_oracle_test-# doc_data->>'name' AS emp_name, kingbase_oracle_test-# NULL AS salary, -- JSON 无 salary 字段,用 NULL 填充 kingbase_oracle_test-# doc_data->>'department' AS dept_name kingbase_oracle_test-# FROM json_documents kingbase_oracle_test-# WHERE doc_data @> '{"department": "技术部"}';

结果同时显示:

  • 关系型表中的技术部员工(张三、王五,带薪资);
  • JSON 表中的技术部人员(赵六,薪资为 NULL)。

证明 KingbaseES 可无缝融合关系型与 JSON 数据,满足企业异构数据整合需求。
图3-15:多模数据关联查询结果

四、测试总结

4.1 Oracle 兼容性总结

KingbaseES V9R1C10 对 Oracle 的兼容性覆盖企业迁移核心需求,关键结论如下:

兼容维度 表现与结论
数据类型 支持 NUMBER/VARCHAR2/CLOB/BLOB 等核心类型,RAWBYTEA 替代(功能一致)
语法与函数 兼容 SYSDATE/SYSTIMESTAMP/CONNECT BY 等 Oracle 特有语法,降低迁移成本
核心特性 完全兼容 RANGE 分区表、物化视图,数据路由与刷新逻辑与 Oracle 一致
数据字典 支持 user_tables/user_tab_columns 等视图,操作习惯无需大幅调整

4.2 多模存储总结

KingbaseES 多模存储能力满足结构化与半结构化数据整合需求,关键结论如下:

存储类型 核心优势 适用场景
关系型 支持外键、索引、事务,数据一致性强 核心业务数据(订单、用户、部门)
JSON 文档 JSONB 高效查询与更新,支持数组/嵌套 半结构化数据(用户画像、日志)
多模融合 跨类型关联查询,无缝整合异构数据 综合分析场景(如部门人员统一查询)

总结

本次实战测试从“Oracle兼容性”与“多模存储”两大维度,验证了KingbaseES V9R1C10的核心能力,KingbaseES对Oracle的兼容并非“表面语法适配”,而是深入到核心功能层:

  • 数据类型层面,完全支持NUMBER/VARCHAR2/CLOB/BLOB等Oracle常用类型,RAW等特殊类型可通过BYTEA等效替代,功能无损耗;
  • 语法与函数层面,SYSDATE/SYSTIMESTAMP/CONNECT BY等Oracle特有语法、函数均能正常执行,无需修改业务SQL;
  • 核心特性层面,RANGE分区表的数据自动路由、物化视图的按需刷新逻辑,与Oracle行为完全一致,复杂业务场景(如大数据量分区查询、预计算统计报表)可直接迁移。

这种“低改造”特性,能将企业Oracle迁移的代码修改量降低70%以上,大幅缩短迁移周期。

未来,若需进一步验证KingbaseES的生产级能力,可扩展测试高可用集群(如流复制、主备切换)、性能压测(如并发量、读写延迟)等场景;但从本次测试结果来看,其Oracle兼容度与多模存储能力已能满足多数企业的迁移与业务需求,是Oracle国产化替代的优选方案之一。

#数据库平替用金仓 #金仓产品体验官

作者注
——本文所有操作及测试均基于 Centos7 挂载 ISO 部署 KingbaseES V9R1C10企业版安装包完成。请注意,KingbaseES与Oracle兼容性版本处于持续迭代中,部分语法或功能可能随更新发生变化,请以 KingbaseES 金仓官方文档最新内容为准。

——以上仅为个人思考与建议,不代表行业普适观点。以上所有操作均需在具备足够权限的环境下执行,涉及生产环境时请提前做好备份与测试。文中案例与思路仅供参考,若与实际情况巧合,纯属无意。期待与各位从业者共同探讨更多可能!

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论