金仓数据库 MongoDB 兼容:多模融合下的架构之道与实战体验

金仓数据库 MongoDB 兼容:多模融合下的架构之道与实战体验
097124b49784459c00e0c8885099f04b.png

引言:从“平替”到“超越”的技术跨越

在国产化替代(信创)浪潮下,选择数据库不再只是考量“能否使用”,更多关注其“好用与否”,还要看是否能做到“无缝切换”。提到 MongoDB,想必大家都不生疏,作为 NoSQL 领域的佼佼者,凭借自身灵活的数据架构和飞快的读写效率,斩获诸多互联网及物联网项目,不过须要诚实地表明,一旦关乎到企业核心业务,譬如要确保数据完全一致,执行繁杂的关联查询或者实施统一运作管理时,MongoDB 就常常会有些力不从心。

电科金仓(Kingbase)所给出的多模融合数据库方案颇具趣味,该方案并非仅仅创建一层适配层来博取眼球,其实在架构层面上执行了“降维打击”,经由内核级别的 MongoDB 协议适配 并结合自主研发的 OSON 存储引擎,金仓把“关系型数据库稳定的基础”与“NoSQL 灵活的特性”融合起来,现在,让我们一起探究金仓数据库(KingbaseES,简称为 KES)在适配 MongoDB 时蕴含着哪些技术要点,随后凭借几段实际操作代码,让大家领略到其性能究竟有多么出色。

文章目录


一、 多模融合:底层架构的“混血”优势

以前咱们做架构设计,关系型数据库和非关系型数据库往往是井水不犯河水,结果就是企业里的技术栈被割裂成好几块,维护起来那叫一个头大。金仓 KES 走了一条多模融合的路子,简单说,就是在同一个数据库内核里,既能存表(Table),也能存文档(Document/JSON),让它们在一个锅里吃饭。

1.1 架构解析

大家别以为金仓只是在外面套了个中间件做转发,人家是真刀真枪的内核级支持

统一存储层KingbaseES 内核接口适配层共享缓冲池共享事务日志 WAL结构化数据 (Heap Table)半结构化数据 (OSON)统一解析器 (SQL/Mongo Command)统一优化器统一执行器JDBC/ODBCMongoDB Driver应用层 (Java/Python/Go)

  • 统一存储层:不管是传统的表数据,还是 JSON 文档,底层用的都是同一套事务日志(WAL)和缓冲池(Buffer Pool)。这意味着啥?意味着你的 JSON 数据天生就拥有了关系型数据库最引以为傲的 ACID 事务特性。这一点,可是早期版本的 MongoDB 望尘莫及的强一致性保障。
  • 统一计算层:SQL 解析器被狠狠加强了一波,它现在是个“双语通”,既能听懂标准 SQL,也能解析 MongoDB 风格的查询(或者通过驱动转换过来)。这样一来,想把文档数据和表数据做个 JOIN 关联查询,简直是小菜一碟。

1.2 协议兼容的技术实现

为了让原来的 MongoDB 应用能无缝迁移过来,金仓在兼容适配层上下了不少功夫。

通信协议:KES 可以监听 MongoDB 的 Wire Protocol,也就是能够理解 MongoDB 的“方言”,原先的 Java Driver 或 PyMongo 客户端,只要稍微改动一下连接设置,就可以与 KES 建立联系,这样应用改造所花费的成本就会大幅缩减。

命令映射并非单纯将 find()insert() 等命令转化为 SQL,而是即时转为成 KES 内部高效执行方案,这种“直译”方式可确保执行效率不打折。


二、 核心对决:BSON vs OSON

MongoDB 用的是 BSON (Binary JSON) 格式,而金仓为了追求极致性能,搞出了个自主研发的 OSON (Optimized JSON) 格式。这玩意儿,就是 KES 性能起飞的关键密码。

金仓 OSON 读取: 头部定位读取 OSON 头部偏移表开始读取 user.address.city直接跳转到 city 偏移量获取数据MongoDB BSON 读取: 需遍历扫描 user 字段开始读取 user.address.city扫描 address 字段扫描 city 字段获取数据

image.png
实战点评:试想一下,如果你要频繁读取一个大文档里藏得很深的字段(比如 user.profile.address.city),OSON 的表现通常能甩 BSON 两三倍。原因很简单,OSON 是“直达”,而 BSON 得“跑腿”遍历。

三、 实战设计:高可用与索引优化

3.1 索引框架的灵活性

金仓不仅继承了 GIN (Generalized Inverted Index) 索引,还把它打磨得更适合 JSON 文档了。

实战代码示例:

假设咱们有个电商订单表 orders,数据长这样:

{"order_id":"20251223001","customer":{"name":"张三","vip":true},"items":[{"product":"Mate60","price":6999},{"product":"Case","price":99}],"tags":["数码","加急"]}

MongoDB 里,你可能会这么建索引:

db.orders.createIndex({"items.product":1})

到了 KingbaseES,你可以用函数索引或者 GIN 索引达到同样的效果,甚至还能支持全文检索:

-- 创建 GIN 索引,一招鲜吃遍天,加速整个 JSON 文档的键值查询CREATEINDEX idx_orders_json ON orders USING gin (data);-- 或者,如果你追求极致速度,可以针对特定路径建 B-Tree 索引CREATEINDEX idx_orders_product ON orders USINGbtree((data->'items'->0->>'product'));

注:KES 允许你给 JSON 里的特定字段建强类型的 B-Tree 索引,这在做范围查询(Range Scan)的时候,速度比 MongoDB 的索引还要快。

3.2 高可用架构 (HA)

金仓的 KES RAC(读写分离/共享存储集群)方案,给文档数据上了把企业级的“保险锁”:

  • 故障秒级切换:万一主节点挂了,备节点立马顶上,应用端甚至都感觉不到断连。

物理复制依靠 WAL 实现,这种复制方式要比 MongoDB 依赖逻辑 oplog 的复制更为可靠,其延迟时间也更短。


四、 多模数据的统一查询优化

企业开发时最忌惮什么?最忌惮跨库关联查询,在 MongoDB 中,利用 $lookup 执行关联时,其性能常常令人头疼不已,而且存在诸多限制,但在金仓 KES 中,可以直接书写 SQL 来有力地关联 JSON 数据,这简直是一种享受。

场景:我们要查出所有买了“Mate60”而且用户等级是“VIP”的订单详情。

KingbaseES 混合查询示例

SELECT o.data->>'order_id'as order_id, c.user_name, o.data->'items'as item_list FROM orders_doc o -- 这是存 JSON 文档的表JOIN users_table c -- 这是传统的普通表ON(o.data->'customer'->>'name')= c.user_name WHERE o.data @>'{"items": [{"product": "Mate60"}]}'-- JSON 包含查询AND c.vip_level >3;
解析:这条 SQL 把 orders_doc 的 JSON 路径检索和 users_table 的关系型 JOIN 完美融合在了一起。优化器聪明得很,它会自动判断是先过滤 JSON 快,还是先做 JOIN 快,这种智能优化,是传统 NoSQL 很难做到的。

用户/应用SQL解析器混合执行引擎关系型表(Table)文档集合(JSON)发起混合查询 (JOIN SQL)解析 SQL 语法 & JSON 路径生成执行计划扫描用户表 (Index Scan)扫描订单文档 (GIN Index)par[并行扫描]返回符合条件的用户行返回符合条件的 JSON 文档执行 Hash Join / Nested Loop返回融合结果集用户/应用SQL解析器混合执行引擎关系型表(Table)文档集合(JSON)


五、 实操验证:3分钟体验多模能力

为了让大家眼见为实,感受一下金仓 KES 的多模能力,我准备了一套脚本,大家可以直接在 KStudio 或者 psql 里跑跑看。

5.1 环境准备与数据写入

首先,咱们建个带 JSON 字段的表,模拟插入几条 MongoDB 风格的订单数据。

-- 创建测试表,data 字段类型为 JSONB (底层就是 OSON 存储)DROPTABLEIFEXISTS orders_doc;CREATETABLE orders_doc ( id SERIALPRIMARYKEY,data JSONB );-- 写入测试数据 (模拟几笔电商订单)INSERTINTO orders_doc (data)VALUES('{"order_id": "ORD-001", "customer": "Alice", "amount": 299, "tags": ["electronics", "sale"]}'),('{"order_id": "ORD-002", "customer": "Bob", "amount": 1299, "tags": ["mobile", "urgent"]}'),('{"order_id": "ORD-003", "customer": "Charlie", "amount": 59, "tags": ["books"]}');-- [验证点 1] 查一下,确认数据是不是按 OSON 格式存进去了SELECT*FROM orders_doc;
image.png
✅ 验证结果分析
瞧,KES 完美地解析并存储了包含数组(tags)和嵌套对象的 JSON 数据。整个插入过程跟写标准 SQL 没啥两样,这就是“关系型底座”带来的便利。

5.2 JSON 深度查询与索引验证

接下来,咱们试试 JSON 路径查询方不方便,顺便看看索引到底有没有生效。

-- 创建 GIN 倒排索引,给 JSON 查询提提速CREATEINDEX idx_orders_gin ON orders_doc USING gin (data);-- 来个复杂点的过滤查询-- 场景:我要找标签里有 "mobile" 而且金额大于 1000 的订单SELECTdata->>'order_id'AS OrderID,data->>'customer'AS Customer,data->>'amount'AS Amount FROM orders_doc WHEREdata @>'{"tags": ["mobile"]}'AND(data->>'amount')::int>1000;-- 看看执行计划 (检查索引有没有被用到)EXPLAINANALYZESELECT*FROM orders_doc WHEREdata @>'{"tags": ["mobile"]}';
image.png
✅ 验证结果分析
查询很准,结果准确无误地显示为 ORD-002,这表明 KES 在处理 JSON 数组时,其中涉及查询(即 tags 包含 mobile),也存在数值比较(也就是 amount 大于 1000)这样的逻辑,并且这些逻辑全部位于线上。

执行计划如何,细心的朋友也许会注意到 Seq Scan,不要担心,在数据量仅有几条之时,改良器觉得全表扫描要比加載索引更快,这实际上是其聪明之处;等到数据量达到万条以上时,你再去查看,它会自动转为成 Bitmap Index Scan,借助 GIN 索引做到毫秒级定位。

5.3 关系与文档的融合查询

最后,咱们来个重头戏:把传统表和 JSON 文档连起来查。

-- 先建个标准的关系表 (用户等级表) 并填点数据CREATETABLE user_levels ( username VARCHAR(50), level_name VARCHAR(20));INSERTINTO user_levels VALUES('Alice','Silver'),('Bob','Gold'),('Charlie','Bronze');-- 执行跨模态 JOIN 查询-- 场景:我想把所有 "Gold" 级别用户的订单详情找出来SELECT u.level_name AS UserLevel, o.data->>'order_id'as OrderID, o.data->>'amount'as Amount FROM orders_doc o JOIN user_levels u ON o.data->>'customer'= u.username WHERE u.level_name ='Gold';
image.png
✅ 验证结果分析
结果不负众望,成功把 Gold 级别用户 Bob 的订单给捞出来了。这实打实地证明了金仓数据库打破了 NoSQL 和 SQL 的次元壁——咱们再也不用在应用层写一堆代码去分别查 MongoDB 和数据库再拼装了,一条 SQL 搞定跨模态数据关联,既省事又高效。

六、 总结:国产化替代的技术底气

金仓数据库对于 MongoDB 的适配,并非仅仅因为“可以存储 JSON”这么简单,这体现出国产数据库在内核方面有着很强的实力。

拼性能:OSON 格式加上 GIN 索引,把大文档查询的性能瓶颈给打通了。

保可靠: 依靠关系型数据库已有的ACID事务以及HA架构,为NoSQL的数据安全形成稳固保障。

图易用:标准 SQL 和 NoSQL 语法随意切换,开发人员上手几乎没有门槛。

对于正在开展信创改造的企业而言,选择金仓 KES 并非仅仅着眼于达成国产化指标,更多时候更像是一次数据架构的全方位升级,在收获 NoSQL 的灵活性之时,重新寻回关系型数据库那难得的安全感与秩序感。

Read more

从千毫秒到亚毫秒:连接条件下推如何让复杂 SQL 飞起来

从千毫秒到亚毫秒:连接条件下推如何让复杂 SQL 飞起来

文章目录 * 前言 * 一、问题背景 * 1.1 客户场景中的典型痛点 * 1.2 业界普遍面临的两大难点 * 1.2.1 语义安全性(Equivalence) * 1.2.2 代价评估(Cost) * 二、传统方案的局限 * 三、金仓数据库基于代价的连接条件下推设计 * 3.1 能不能推:等价性判定(Equivalence) * 3.2 值不值推:代价模型(Cost) * 四、效果验证 * 4.1 最小化用例 * 4.2 复杂场景验证 * 五、总结 前言 在真实的业务系统中,SQL 往往远比教科书示例复杂。随着业务逻辑的不断演进,CTE、

By Ne0inhk
最新Spring Security实战教程(十七)企业级安全方案设计 - 多因素认证(MFA)实现

最新Spring Security实战教程(十七)企业级安全方案设计 - 多因素认证(MFA)实现

🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志 🎐 个人CSND主页——Micro麦可乐的博客 🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战 🌺《RabbitMQ》专栏19年编写主要介绍使用JAVA开发RabbitMQ的系列教程,从基础知识到项目实战 🌸《设计模式》专栏以实际的生活场景为案例进行讲解,让大家对设计模式有一个更清晰的理解 🌛《开源项目》本专栏主要介绍目前热门的开源项目,带大家快速了解并轻松上手使用 ✨《开发技巧》本专栏包含了各种系统的设计原理以及注意事项,并分享一些日常开发的功能小技巧 💕《Jenkins实战》专栏主要介绍Jenkins+Docker的实战教程,让你快速掌握项目CI/CD,是2024年最新的实战教程 🌞《Spring Boot》专栏主要介绍我们日常工作项目中经常应用到的功能以及技巧,代码样例完整 🌞《Spring Security》专栏中我们将逐步深入Spring Security的各个技术细节,带你从入门到精通,全面掌握这一安全技术 如果文章能够给大家带来一定的帮助!欢迎关注、评

By Ne0inhk
KingbaseES数据库:用 ksql 实现本地库创建 / 查看 / 切换 / 删除(附避坑技巧)

KingbaseES数据库:用 ksql 实现本地库创建 / 查看 / 切换 / 删除(附避坑技巧)

KingbaseES数据库:用 ksql 实现本地库创建 / 查看 / 切换 / 删除(附避坑技巧) 本文围绕本地 KingbaseES 数据库的全生命周期操作展开,先明确操作前的关键前提 —— 根据不同兼容模式确认 “权限库”(普通模式连任意已存库,SQLServer 兼容模式需连 master 库),并通过 \du 命令核查用户是否具备 CREATEDB 权限。核心讲解两种创建方式:推荐用 CREATE DATABASE 语句自定义编码、表空间等配置,也可通过 createdb 工具在系统终端快速创建。后续依次介绍 \l 查看所有库列表、\l + 查单库详情、\c 切换库的方法,强调切换前需提交事务避免数据回滚。删除操作重点提醒需先切换至其他库,建议加 IF EXISTS 选项,并做好数据备份以防丢失。最后针对权限不足、数据库被占用等高频报错,给出具体排查解决步骤,

By Ne0inhk
Flutter 组件 angel3_orm_mysql 的适配 鸿蒙Harmony 实战 - 驾驭专业 ORM 映射引擎、实现鸿蒙端与 MySQL 数据库的透明映射与高性能 SQL 审计方案

Flutter 组件 angel3_orm_mysql 的适配 鸿蒙Harmony 实战 - 驾驭专业 ORM 映射引擎、实现鸿蒙端与 MySQL 数据库的透明映射与高性能 SQL 审计方案

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 组件 angel3_orm_mysql 的适配 鸿蒙Harmony 实战 - 驾驭专业 ORM 映射引擎、实现鸿蒙端与 MySQL 数据库的透明映射与高性能 SQL 审计方案 前言 在鸿蒙(OpenHarmony)生态向企业级中台应用、大屏数字化面板、以及需要直接操作中心数据库的特定内网管理工具拓展时,“数据库连接与对象关系映射(ORM)”是构建数据闭环的关键桥梁。虽然移动端通常通过 API 与后端交互。但在某些高性能、低延迟的私有云场景下(如:工厂本地监控大屏)。鸿蒙端需要直接与 MySQL 建立高压连接。并实现从 SQL 表结构到 Dart 实体的自动转换。 如果手动编写繁琐的 SELECT * 语句并逐字段进行 Map

By Ne0inhk