【金仓数据库征文】Oracle到金仓:序列、触发器与自增键改造实践

文章目录

    • 每日一句正能量
    • 导读
    • [1. 背景与问题](#1. 背景与问题)
    • [2. 环境与数据](#2. 环境与数据)
      • [2.1 验证环境](#2.1 验证环境)
      • [2.2 源端对象扫描](#2.2 源端对象扫描)
    • [3. 复现过程](#3. 复现过程)
      • [3.1 复现"历史主键被触发器覆盖"](#3.1 复现“历史主键被触发器覆盖”)
      • [3.2 复现"序列起点低于历史最大值"](#3.2 复现“序列起点低于历史最大值”)
      • [3.3 复现"序列空洞被误判为丢单"](#3.3 复现“序列空洞被误判为丢单”)
      • [3.4 复现并发冲突](#3.4 复现并发冲突)
    • [4. 方案实施](#4. 方案实施)
      • [4.1 方案选择](#4.1 方案选择)
      • [4.2 目标端保留序列](#4.2 目标端保留序列)
      • [4.3 保留触发器时的改造](#4.3 保留触发器时的改造)
      • [4.4 历史装载与序列校准](#4.4 历史装载与序列校准)
      • [4.5 灰度期间使用独立高位号段](#4.5 灰度期间使用独立高位号段)
      • [4.6 权限改造](#4.6 权限改造)
    • [5. 结果对比](#5. 结果对比)
      • [5.1 对象级校验](#5.1 对象级校验)
      • [5.2 数据级校验](#5.2 数据级校验)
      • [5.3 并发验证结果模板](#5.3 并发验证结果模板)
      • [5.4 切换门禁](#5.4 切换门禁)
    • [6. 风险与复盘](#6. 风险与复盘)
      • [6.1 灰度切换步骤](#6.1 灰度切换步骤)
      • [6.2 回退方案](#6.2 回退方案)
      • [6.3 关键风险清单](#6.3 关键风险清单)
      • [6.4 项目复盘](#6.4 项目复盘)
    • [附录 A:对象改造脚本模板](#附录 A:对象改造脚本模板)
    • [附录 B:上线检查清单](#附录 B:上线检查清单)

每日一句正能量

世界上最可怕的事,是你把别人当成了朋友,别人并没拿你当朋友。

人际关系中最深的孤独不是没有朋友,而是你付出的真心被对方视为寻常,甚至利用。这种不对等的情感投射,会让人产生自我怀疑。友谊需要双向确认,单方面的热情只是一厢情愿的冒险。

导读

本文以订单系统迁移为背景,讨论 Oracle 序列、BEFORE INSERT 触发器、应用显式取号和目标端自增机制之间的兼容改造。示例强调可复现验证,不把"SQL 能执行"当作迁移完成,而是把对象依赖、并发唯一性、历史数据装载、生成器校准和可回退性一并纳入验收。

1. 背景与问题

订单系统的主键生成看起来简单:插入一行,得到一个新的订单号。但在真实系统里,主键通常贯穿订单主表、明细、支付流水、物流任务、消息队列和外部接口。迁移时只要生成机制有一处改错,就可能出现重复键、子表找不到主表、历史订单被覆盖,甚至回退时新订单无法写回 Oracle。

本次演练中的 Oracle 源库存在三种取号路径:

sql 复制代码
-- 路径一:应用显式取号
SELECT seq_order_id.NEXTVAL FROM dual;

-- 路径二:插入时不传主键,由触发器赋值
INSERT INTO t_order(order_no, customer_id, amount)
VALUES (:order_no, :customer_id, :amount);

-- 路径三:批量导入时显式传入历史主键
INSERT INTO t_order(order_id, order_no, customer_id, amount)
VALUES (:order_id, :order_no, :customer_id, :amount);

对应的 Oracle 对象如下:

sql 复制代码
CREATE SEQUENCE seq_order_id
    START WITH 100000000
    INCREMENT BY 1
    MAXVALUE 999999999999999999
    NOCYCLE
    CACHE 100
    NOORDER;

CREATE OR REPLACE TRIGGER trg_bi_order_id
BEFORE INSERT ON t_order
FOR EACH ROW
WHEN (NEW.order_id IS NULL)
BEGIN
    SELECT seq_order_id.NEXTVAL
      INTO :NEW.order_id
      FROM dual;
END;
/

真正的迁移难点不在语法替换,而在于以下问题:

  1. 目标端是否继续使用"序列+触发器",还是改为列默认值或身份列;
  2. 迁移历史数据时,触发器是否会覆盖原主键;
  3. 全量迁移和在线增量同时进行时,目标序列从哪里起步;
  4. 应用是否同时存在 NEXTVAL、触发器和 ORM 自动生成三套逻辑;
  5. 序列缓存导致的空洞是否会被业务错误地判断为"丢单";
  6. 切换后产生的新主键能否在回退时写回 Oracle;
  7. 业务账号在目标端是否具有正确的序列和触发器权限。

Oracle 官方文档说明,序列通过 NEXTVAL 生成值,可配置起始值、步长、最大值、循环和缓存;缓存可以提升取号性能,但实例故障时未使用的缓存值可能丢失,因此序列天然不保证连续。KingbaseES 官方文档同样提供 CREATE SEQUENCE,并可通过 nextvalcurrvalsetval 操作序列。两端功能相似,但对象语法、默认值表达式、权限模型和兼容模式仍应按实际版本验证。

主键生成机制兼容评估图

2. 环境与数据

2.1 验证环境

项目 源端 目标端
数据库 Oracle 19c KingbaseES V8 兼容环境
应用 Java 订单服务 同一套迁移分支
数据规模 订单主表约 5000 万行 全量副本
峰值写入 约 3000 单/秒 按相同压测模型验证
主键类型 NUMBER(19,0) NUMERIC(19,0) 或等价整数型
迁移方式 全量 + 增量同步 灰度切换

版本、数据量和性能指标必须替换为真实项目数据。本文数值仅用于展示验证方法。

2.2 源端对象扫描

先扫描序列:

sql 复制代码
SELECT sequence_owner,
       sequence_name,
       min_value,
       max_value,
       increment_by,
       cycle_flag,
       order_flag,
       cache_size,
       last_number
FROM dba_sequences
WHERE sequence_owner = 'OMS'
ORDER BY sequence_name;

LAST_NUMBER 不能直接等同于"最后一个已使用值",尤其在启用缓存时。它只能作为辅助信息,真正安全的起点还要结合业务表最大主键和在线增量。

扫描触发器及状态:

sql 复制代码
SELECT owner,
       trigger_name,
       table_name,
       triggering_event,
       trigger_type,
       status
FROM dba_triggers
WHERE owner = 'OMS'
ORDER BY table_name, trigger_name;

提取触发器定义:

sql 复制代码
SELECT owner, name, type, line, text
FROM dba_source
WHERE owner = 'OMS'
  AND type = 'TRIGGER'
ORDER BY name, line;

扫描列默认值和身份列:

sql 复制代码
SELECT owner,
       table_name,
       column_name,
       data_default,
       identity_column
FROM dba_tab_columns
WHERE owner = 'OMS'
  AND (data_default IS NOT NULL OR identity_column = 'YES')
ORDER BY table_name, column_id;

除了数据库对象,还要搜索应用代码和配置:

text 复制代码
NEXTVAL
CURRVAL
selectKey
useGeneratedKeys
GenerationType.SEQUENCE
GenerationType.IDENTITY
@SequenceGenerator
before insert
order_id

如果同一张表既有触发器,又有 MyBatis selectKey 或 JPA @SequenceGenerator,就必须明确谁负责生成主键。双重取号通常不会直接重复,但会造成大量空洞、逻辑分叉和难以回退。

3. 复现过程

3.1 复现"历史主键被触发器覆盖"

错误触发器常写成无条件赋值:

sql 复制代码
CREATE OR REPLACE TRIGGER trg_bi_order_id
BEFORE INSERT ON t_order
FOR EACH ROW
BEGIN
    :NEW.order_id := seq_order_id.NEXTVAL;
END;
/

当迁移工具显式插入历史主键时,该触发器仍然生成新值,导致:

  • 目标端主键与 Oracle 不一致;
  • 明细表仍引用旧主键,外键装载失败;
  • 外部系统按历史订单 ID 查询不到数据;
  • 回退时无法将目标端数据和源端订单关联。

正确原则是"仅在主键为空时取号":

sql 复制代码
IF :NEW.order_id IS NULL THEN
    :NEW.order_id := seq_order_id.NEXTVAL;
END IF;

迁移历史数据时还可以临时禁用触发器,但必须记录禁用窗口,并在启用前完成序列校准。

3.2 复现"序列起点低于历史最大值"

假设源表最大订单主键为:

sql 复制代码
SELECT MAX(order_id) FROM t_order;
-- 结果:1087654321

目标端却按旧 DDL 创建:

sql 复制代码
CREATE SEQUENCE seq_order_id START WITH 100000000;

历史数据导入后,一旦在线写入,序列迟早会撞上已经存在的主键。这个问题在小规模测试中可能不出现,因为序列尚未增长到冲突区间;正式运行一段时间后才爆发,风险很高。

安全起点至少满足:

text 复制代码
目标序列下一值 > max(
    Oracle 当前最大主键,
    目标端已迁移最大主键,
    增量同步队列中的最大主键,
    灰度期间目标端已生成最大主键
)

建议额外预留安全步长,例如取上述最大值加 10000,但预留量必须结合峰值写入和同步延迟确定,不能随意拍脑袋。

3.3 复现"序列空洞被误判为丢单"

执行:

sql 复制代码
SELECT seq_order_id.NEXTVAL FROM dual;
ROLLBACK;
SELECT seq_order_id.NEXTVAL FROM dual;

序列值通常不会因事务回滚而回退。启用缓存后,数据库重启或节点故障也可能造成未使用号段丢失。因此:

  • 序列负责唯一取号,不负责连续编号;
  • 对账不能用"最大 ID - 最小 ID + 1"推导订单数量;
  • 财务凭证号、发票号等需要连续性监管的编号,应采用独立业务规则,而不是直接依赖数据库序列;
  • 监控应关注重复、越界和生成失败,不应把空洞本身当成数据库错误。

3.4 复现并发冲突

创建最小测试表:

sql 复制代码
CREATE TABLE t_order_pk_test (
    order_id   NUMERIC(19,0) PRIMARY KEY,
    order_no   VARCHAR(64) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

并发测试需要覆盖:

  • 50、100、200 并发线程持续取号并插入;
  • 每事务单行插入;
  • 每事务批量插入 100~1000 行;
  • 部分事务取号后主动回滚;
  • 在线插入与历史主键导入并行;
  • 重启连接池、切换节点或模拟故障后的继续写入。

测试结束后执行:

sql 复制代码
SELECT COUNT(*) AS total_rows,
       COUNT(DISTINCT order_id) AS distinct_ids,
       MIN(order_id) AS min_id,
       MAX(order_id) AS max_id
FROM t_order_pk_test;

重复键验证:

sql 复制代码
SELECT order_id, COUNT(*)
FROM t_order_pk_test
GROUP BY order_id
HAVING COUNT(*) > 1;

不能只看 SQL 成功率,还应记录 TPS、平均延迟、P95/P99、序列锁等待、失败事务数和重试次数。

序列触发器改造流程图

4. 方案实施

4.1 方案选择

订单系统常见三种目标方案:

方案 优点 风险 适用建议
保留序列 + 触发器 与旧逻辑接近,改动较小 触发器隐式、排查链路长 大量旧应用依赖空主键插入时
序列 + 列默认值 逻辑更直观,显式主键仍可导入 应用若显式传 NULL 需验证 推荐作为多数表的改造方向
身份列/自增列 DDL 简洁,ORM 支持较好 历史值装载、重置和回退更复杂 新表或调用链简单的表

不建议全库一刀切改成身份列。订单主表、明细表和接口表应分别评估。

4.2 目标端保留序列

根据实际 KingbaseES 版本和兼容模式确认语法。通用思路如下:

sql 复制代码
CREATE SEQUENCE oms.seq_order_id
    START WITH 2000000000
    INCREMENT BY 1
    MINVALUE 1
    MAXVALUE 999999999999999999
    CACHE 100
    NO CYCLE;

金仓文档说明,创建序列后可使用 nextvalcurrvalsetval。目标表可将序列调用设置为默认值:

sql 复制代码
CREATE TABLE oms.t_order (
    order_id   NUMERIC(19,0)
               DEFAULT nextval('oms.seq_order_id'::regclass)
               PRIMARY KEY,
    order_no   VARCHAR(64) NOT NULL,
    customer_id NUMERIC(19,0) NOT NULL,
    amount     NUMERIC(18,2) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

该方案的关键优点是:

  • 普通插入不传 order_id 时自动取号;
  • 历史迁移显式传入 order_id 时保留原值;
  • 主键生成依赖关系可从列默认值中看到;
  • 比触发器更容易排查。

但应用显式传入 NULL 的行为必须实测,因为"省略列"和"传入 NULL"并不总是等价。

4.3 保留触发器时的改造

若旧应用大量依赖触发器,可先保持调用方式,降低首轮迁移风险。示意代码:

sql 复制代码
CREATE OR REPLACE FUNCTION oms.fn_bi_order_id()
RETURNS trigger
AS $$
BEGIN
    IF NEW.order_id IS NULL THEN
        NEW.order_id := nextval('oms.seq_order_id'::regclass);
    END IF;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg_bi_order_id
BEFORE INSERT ON oms.t_order
FOR EACH ROW
EXECUTE FUNCTION oms.fn_bi_order_id();

不同 KingbaseES 版本、数据库模式和兼容配置对过程语言、触发器语法可能存在差异,必须以项目环境实际执行结果为准,不能仅复制示例。

4.4 历史装载与序列校准

历史数据迁移完成后,先得到所有相关端的最大值:

sql 复制代码
SELECT MAX(order_id) FROM oms.t_order;

目标端校准示意:

sql 复制代码
SELECT setval(
    'oms.seq_order_id'::regclass,
    (SELECT MAX(order_id) FROM oms.t_order) + 10000,
    false
);

第三个参数的具体语义需要按实际版本文档验证。校准后必须立即检查下一值:

sql 复制代码
SELECT nextval('oms.seq_order_id'::regclass);

并确认它大于所有已用值。不要在没有停写或没有纳入增量最大值的情况下直接执行 MAX(id)+1,否则查询结束后新增的 Oracle 订单仍可能占用更高主键。

4.5 灰度期间使用独立高位号段

为了保证回退,灰度阶段可让目标端使用一个与 Oracle 当前号段不重叠的高位区间,例如:

text 复制代码
Oracle 当前主键:1,000,000,000 ~ 1,987,654,321
金仓灰度号段:  8,000,000,000 起

这样有三点好处:

  1. 双端生成的订单不会直接冲突;
  2. 能快速识别订单由哪一端创建;
  3. 回退时可按号段导出金仓新增订单。

前提是 Oracle 主键字段和所有下游系统都能容纳该高位范围。号段设计必须检查:

  • NUMBER(p,0) 或目标类型上限;
  • Java long、前端 JavaScript 数字精度;
  • 消息队列字段类型;
  • 日志、报表和第三方接口;
  • 分库分表路由算法。

4.6 权限改造

业务账号至少要具备:

  • 表的 INSERT 权限;
  • 调用序列 nextval 所需权限;
  • 执行触发器函数所需权限;
  • 对相关模式的必要访问权。

权限验证应使用真实业务账号,而不是 DBA 账号:

sql 复制代码
SET ROLE oms_app_role;

INSERT INTO oms.t_order(order_no, customer_id, amount)
VALUES ('MIG_TEST_001', 10001, 88.60);

SELECT order_id, order_no
FROM oms.t_order
WHERE order_no = 'MIG_TEST_001';

5. 结果对比

5.1 对象级校验

迁移前后对照以下属性:

text 复制代码
序列名称
所属模式
起始值
步长
最小值/最大值
是否循环
缓存大小
顺序属性
拥有者与权限
引用该序列的默认值
引用该序列的触发器
应用中的显式取号 SQL

形成对象改造清单:

对象 源端方式 目标端方式 验证结果
SEQ_ORDER_ID Oracle 序列,CACHE 100 KingbaseES 序列,CACHE 100 下一值高于历史最大值
TRG_BI_ORDER_ID 空值时取号 改为列默认值或目标触发器 显式历史主键不被覆盖
T_ORDER.ORDER_ID NUMBER(19,0) NUMERIC(19,0) 主键范围一致
Java 下单接口 selectKey 保留或改为返回生成键 并发回归通过
批量导入 显式主键 显式主键 主从关联一致

5.2 数据级校验

主表验证:

sql 复制代码
SELECT COUNT(*) AS row_count,
       COUNT(DISTINCT order_id) AS distinct_id_count,
       MIN(order_id) AS min_id,
       MAX(order_id) AS max_id,
       SUM(CASE WHEN order_id IS NULL THEN 1 ELSE 0 END) AS null_id_count
FROM oms.t_order;

主从完整性验证:

sql 复制代码
SELECT COUNT(*) AS orphan_count
FROM oms.t_order_item i
LEFT JOIN oms.t_order o
       ON o.order_id = i.order_id
WHERE o.order_id IS NULL;

订单号和主键映射验证:

sql 复制代码
SELECT order_no, COUNT(*)
FROM oms.t_order
GROUP BY order_no
HAVING COUNT(*) > 1;

分批迁移校验:

sql 复制代码
SELECT migration_batch,
       COUNT(*) AS row_count,
       MIN(order_id) AS min_id,
       MAX(order_id) AS max_id
FROM oms.t_order
GROUP BY migration_batch
ORDER BY migration_batch;

5.3 并发验证结果模板

以下为结果记录模板,不应伪装成真实项目数据:

并发数 持续时间 成功插入 重复主键 P95 延迟 结论
50 待实测 待实测 必须为 0 待实测 待填写
100 待实测 待实测 必须为 0 待实测 待填写
200 待实测 待实测 必须为 0 待实测 待填写

正式投稿时应附上压测命令、线程数、连接池参数、服务器配置、执行时间、TPS、P95/P99 和数据库等待事件截图。

并发验证矩阵

5.4 切换门禁

正式切换前,建议设定以下硬门禁:

  • 目标端重复主键数为 0;
  • 主键空值数为 0;
  • 主从孤儿记录数为 0;
  • 目标序列下一值高于两端所有已用值;
  • 历史显式主键插入不会被默认值或触发器覆盖;
  • 业务账号可正常取号,且无多余高权限;
  • 50、100、200 并发测试均无重复键;
  • 订单创建、取消、支付、拆单、合单和补单流程全部通过;
  • 灰度号段可完整导出并回写 Oracle;
  • 回退演练已完成。

6. 风险与复盘

6.1 灰度切换步骤

  1. 冻结 Oracle 序列、触发器和主键列的结构变更;
  2. 记录源端所有序列定义和依赖对象;
  3. 执行历史全量迁移,显式保留原主键;
  4. 完成目标端序列校准;
  5. 启动增量同步并持续比较两端最大主键;
  6. 使用独立高位号段开放少量金仓写入;
  7. 对灰度订单执行主从、支付和消息链路核对;
  8. 达到门禁后停止 Oracle 写入;
  9. 完成最后增量追平并统一目标端序列;
  10. 保留 Oracle 和差异流水,进入回退观察窗口。

灰度切换与回退路径图

6.2 回退方案

回退触发条件可以包括:

  • 出现任意重复主键;
  • 目标序列下一值进入历史数据区间;
  • 主从关联出现孤儿记录;
  • 高位号段被下游接口截断或转成科学计数法;
  • 应用部分节点仍从 Oracle 取号,形成双重生成;
  • 并发性能明显低于迁移门禁;
  • 增量同步无法在窗口内追平。

回退步骤:

text 复制代码
1. 关闭金仓订单写入口,记录最后成功事务时间。
2. 冻结目标序列,导出灰度号段内新增订单及所有子表记录。
3. 校验这些主键是否在 Oracle 字段、应用和接口范围内。
4. 按主表到子表顺序回放 Oracle,避免外键失败。
5. 将 Oracle 序列校准到回放后最大主键之上。
6. 核对订单、明细、支付、日志和消息数量。
7. 恢复 Oracle 写入,金仓改为只读排查环境。

回退前不要尝试"回收"已经发出但未使用的序列值。序列值空洞不影响唯一性,强行复用反而可能与延迟事务、消息重放或缓存中的旧值冲突。

6.3 关键风险清单

风险一:迁移工具只迁移表,遗漏序列和触发器。

应把序列、默认值、触发器、函数、权限和应用 SQL 作为一个完整依赖组验收。

风险二:目标触发器覆盖历史主键。

触发器必须只在主键为空时取号,历史装载需专项验证。

风险三:MAX(id)+1 在在线环境下失效。

校准过程必须冻结写入,或把增量队列中的最大值纳入计算。

风险四:缓存空洞被误判为数据丢失。

用业务订单号、状态和行数对账,不用主键连续性对账。

风险五:改成身份列后回退困难。

身份列方案要验证显式历史值插入、生成器重置和回写源端。

风险六:高位灰度号段超出下游精度。

尤其要检查 JavaScript、Excel、JSON 消费方和第三方接口。

风险七:应用仍保留旧的 NEXTVAL SQL。

数据库改成默认值后,应用若继续提前取号,可能产生更多空洞或两次取号。

6.4 项目复盘

本次实践最重要的认识是:主键迁移不是一个序列 DDL 的迁移,而是一条完整的"生成---传递---存储---关联---同步---回退"链路改造。

一个可审计的交付包至少应包含:

  • Oracle 序列清单;
  • 触发器和依赖对象清单;
  • 应用取号 SQL 和 ORM 配置清单;
  • 目标端对象改造脚本;
  • 历史最大主键和安全起点计算记录;
  • 并发压测脚本与结果;
  • 主从完整性校验 SQL;
  • 灰度号段设计;
  • 切换门禁;
  • 回退演练记录。

只有当这些证据全部闭环,才能证明迁移后的订单 ID 不仅"能生成",而且在高并发、历史装载、故障恢复和回退场景下都保持唯一、稳定和可追溯。

附录 A:对象改造脚本模板

sql 复制代码
-- 1. 创建目标序列
CREATE SEQUENCE oms.seq_order_id
    START WITH 8000000000
    INCREMENT BY 1
    MINVALUE 1
    MAXVALUE 999999999999999999
    CACHE 100
    NO CYCLE;

-- 2. 设置列默认值
ALTER TABLE oms.t_order
ALTER COLUMN order_id
SET DEFAULT nextval('oms.seq_order_id'::regclass);

-- 3. 历史装载后校准
SELECT setval(
    'oms.seq_order_id'::regclass,
    (SELECT MAX(order_id) + 10000 FROM oms.t_order),
    false
);

-- 4. 验证下一值
SELECT nextval('oms.seq_order_id'::regclass);

-- 5. 验证重复与空值
SELECT COUNT(*) - COUNT(DISTINCT order_id) AS duplicate_count,
       SUM(CASE WHEN order_id IS NULL THEN 1 ELSE 0 END) AS null_count
FROM oms.t_order;

附录 B:上线检查清单

  • 已扫描全部序列及参数。
  • 已扫描全部触发器、默认值和身份列。
  • 已搜索应用中的 NEXTVALselectKey 和 ORM 生成策略。
  • 已确认历史数据插入不会被触发器覆盖。
  • 已计算两端最大已用主键和增量队列最大值。
  • 已校准目标序列并验证下一值。
  • 已验证序列缓存空洞符合业务预期。
  • 已验证业务账号权限。
  • 已完成并发、回滚和批量插入测试。
  • 已完成主从孤儿数据检查。
  • 已验证高位号段的全链路兼容性。
  • 已完成灰度切换和回退演练。

转载自:https://blog.csdn.net/u014727709/article/details/163172999

欢迎 👍点赞✍评论⭐收藏,欢迎指正

相关推荐
承渊政道3 天前
从设备数据到AI洞察:时序数据的多模融合实践
数据库·人工智能·性能优化·金仓数据库·多模融合
水豚老师5 天前
基于会话变量与行快照的跨数据库双向增量同步系统设计与实现 - TriggerAsyn v2:从状态机防循环到事件溯源回放的全面重构
重构·触发器·状态机·异构数据库·多数据库同步
数据库小学妹10 天前
国产数据库选型技术指南:五大主流路线对比与Oracle迁移策略分析
分布式数据库·信创数据库·oracle迁移·国产数据库选型·集中式数据库
肖永威15 天前
金仓数据库麒麟环境SQL终端使用入门实践(增删改查篇)
数据库·sql·金仓数据库
不剪发的Tony老师18 天前
金仓数据库在线体验:简单易用
数据库·金仓数据库
云边有个稻草人2 个月前
深度解析:KingbaseES高可用架构落地原理与生产运维实战
数据库·读写分离·数据库运维·金仓数据库·国产数据库技术·数据备份恢复
Irene19912 个月前
数据库(Oracle/MySQL/Hive)表属性对比:从表的索引、触发器、权限等属性,到一张表的完整生命周期(从设计、存储、约束、关系到维护)
触发器·索引·权限
云边有个稻草人2 个月前
金仓数据库标量子查询消除:解决复杂SQL性能瓶颈
数据库·sql·性能调优·金仓数据库·kes·标量子查询·数据库内核
正在走向自律2 个月前
标量子查询消除:数据库优化器的一场“等价变戏法”
数据库·sql 优化·金仓数据库·数据库性能调优·标量子查询·数据库优化器