DATA BRANCH DIFF¶
语法说明¶
DATA BRANCH DIFF 语句用于比较两个表之间的数据差异。该功能类似于 Git 的 diff 命令,可以显示两个数据分支之间的插入、删除和更新操作。
系统会自动识别两个表之间的最近公共祖先(LCA,Lowest Common Ancestor)。存在 LCA 时,按血缘计算以下增量差异:
INSERT:目标表中存在但基准表中不存在的行
DELETE:基准表中存在但目标表中不存在的行
UPDATE:两个表中主键相同但其他列值不同的行
如果两个表没有共同祖先,系统把两侧视为独立数据镜像:只存在于一侧的行,以及同一键在两侧值不同的行,都会以各自侧的 INSERT 输出。DELETE 和 UPDATE 是有血缘场景的语义,不适用于无 LCA 的全量比较。
语法结构¶
DATA BRANCH DIFF target_table [{ SNAPSHOT = 'snapshot_name' }]
AGAINST base_table [{ SNAPSHOT = 'snapshot_name' }]
[COLUMNS ( col1 [, col2 ...] )]
[OUTPUT output_option]
COLUMNS 投影(v3.0.10 起支持)¶
COLUMNS (col1, col2, ...) 将可见值列严格限定为显式请求的列。主键仍用于内部匹配和最终排序,但不会自动加入输出;只有显式列出时才会显示。列名按大小写不敏感匹配和去重,并保留第一次出现,因此 COLUMNS(name, NAME, name) 只输出一个 name 列。COLUMNS 不能与 OUTPUT FILE 组合。
输出选项¶
output_option:
COUNT -- 仅返回差异行数
| LIMIT number -- 限制返回的差异行数
| FILE 'directory_path' -- 将差异导出为 SQL 文件
| AS table_name -- 将差异持久化到新的普通表
| SUMMARY -- 返回聚合的 INSERT / DELETE / UPDATE 计数
语法释义¶
参数说明¶
参数 |
说明 |
|---|---|
|
目标表(要比较的表) |
|
基准表(作为比较基准的表) |
|
可选参数,指定使用某个快照时刻的数据进行比较 |
|
仅返回差异的行数统计 |
|
按主键完成最终排序后,最多返回 |
|
将差异导出为 SQL 文件到指定目录,支持本地路径或 Stage 路径(如 |
|
新建普通表并持久化差异。结果表包含 |
|
返回三行( |
|
v3.0.10 起支持。仅返回显式列出的值列,不自动包含主键;不能与 |
输出列说明¶
默认输出包含以下列:
列名 |
说明 |
|---|---|
|
显示比较的表名 |
|
差异类型:INSERT、DELETE 或 UPDATE |
其他列 |
表的所有可见列 |
OUTPUT AS¶
OUTPUT AS table_name 将差异物化为持久化普通表。它不会创建数据分支,语句提交后其他会话也可以访问该表。输出保留所选值列的顺序和类型,并增加两个由差异操作填充的元数据列:
__mo_diff_source:该差异行对应的来源表名。__mo_diff_flag:INSERT、DELETE或UPDATE。
如果用户列使用了上述名称,MatrixOne 会自动选择带后缀的安全名称以避免冲突。COLUMNS (...) 以与结果集差异相同的方式控制可见值列,主键列只有在显式请求时才会加入。目标表名可以带数据库名,不能已存在,也不能是快照;语句会执行普通 CREATE TABLE 权限检查。如果 schema 校验或建表失败,部分创建的输出表会被原子清理。
DROP DATABASE IF EXISTS diff_output_demo;
CREATE DATABASE diff_output_demo;
USE diff_output_demo;
CREATE TABLE base (id INT PRIMARY KEY, value VARCHAR(20));
INSERT INTO base VALUES (1, 'old');
CREATE TABLE target (id INT PRIMARY KEY, value VARCHAR(20));
INSERT INTO target VALUES (1, 'new'), (2, 'added');
DATA BRANCH DIFF target AGAINST base COLUMNS (value) OUTPUT AS diff_rows;
SHOW COLUMNS FROM diff_rows;
SELECT __mo_diff_flag, __mo_diff_source, id, value FROM diff_rows ORDER BY id;
DROP TABLE diff_rows;
DROP TABLE target;
DROP TABLE base;
DROP DATABASE diff_output_demo;
使用说明¶
LCA(最近公共祖先)¶
系统会自动检测两个表之间的分支关系:
无 LCA:两个表没有共同的祖先,直接比较所有数据
有 LCA:两个表有共同的祖先,基于祖先计算增量差异
自身为 LCA:一个表是另一个表的祖先
无 LCA 时,两侧独有行以及同一键的不同镜像都标记为对应侧的 INSERT;存在 LCA 时,INSERT、DELETE、UPDATE 表示相对共同祖先的变更。
持久化与排序¶
OUTPUT AS将结果物化为普通表。目标表已存在、目标带快照选项或调用者缺少目标数据库的CREATE TABLE权限时会失败。持久化表使用
__mo_diff_source和__mo_diff_flag保存来源与变更类型。OUTPUT AS参与显式事务:COMMIT会同时持久化表和差异数据,ROLLBACK后表与数据都不存在;空差异在提交后仍会创建空表。如果源列已经使用
__mo_diff_source或__mo_diff_flag,生成的元数据列会采用可用的数字后缀(例如__mo_diff_source_1),源列名保持不变。快照比较会物化所选历史端点可见的 schema;历史映射不兼容时会在创建目标表前失败。OUTPUT LIMIT N在按主键完成最终排序后截取前 N 行,不使用内部存储顺序。OUTPUT SUMMARY返回metric、<target_table>、<base_table>三列,以及INSERTED、DELETED、UPDATED三行,不返回行镜像。
LCA 解析和变更范围计算支持任意 DAG 深度的分支,不仅限于直接的父子关系。多叉树中具有复杂分支历史的结构可以在任意节点对(兄弟节点、表兄弟节点、跨子树节点)之间产生正确的差异。
支持的表类型¶
带主键的表(推荐)
复合主键的表
无主键的表(使用隐藏的 fake primary key)
示例¶
示例 1:基本差异比较¶
比较两个没有共同祖先的表:
-- Expected-Rows: 0
CREATE DATABASE test;
-- Expected-Rows: 0
USE test;
-- Expected-Rows: 0
CREATE TABLE test.t1 (a INT PRIMARY KEY, b VARCHAR(10));
-- Expected-Rows: 0
INSERT INTO test.t1 VALUES (1, '1'), (2, '2'), (3, '3');
-- Expected-Rows: 0
CREATE TABLE test.t2 (a INT PRIMARY KEY, b VARCHAR(10));
-- Expected-Rows: 0
INSERT INTO test.t2 VALUES (1, '1'), (2, '2'), (4, '4');
-- Expected-Rows: 2
DATA BRANCH DIFF test.t2 AGAINST test.t1;
+-------------------+--------+------+------+
| diff t2 against t1 | flag | a | b |
+-------------------+--------+------+------+
| t2 | INSERT | 4 | 4 |
| t1 | INSERT | 3 | 3 |
+-------------------+--------+------+------+
-- Expected-Rows: 2
DATA BRANCH DIFF test.t1 AGAINST test.t2;
+-------------------+--------+------+------+
| diff t1 against t2 | flag | a | b |
+-------------------+--------+------+------+
| t1 | INSERT | 3 | 3 |
| t2 | INSERT | 4 | 4 |
+-------------------+--------+------+------+
-- Expected-Rows: 0
DROP TABLE test.t1;
-- Expected-Rows: 0
DROP TABLE test.t2;
示例 2:比较分支表(有共同祖先)¶
-- Expected-Rows: 0
CREATE TABLE test.t0 (a INT PRIMARY KEY, b INT);
-- Expected-Rows: 0
INSERT INTO test.t0 VALUES (1, 1), (2, 2), (3, 3);
-- 从 t0 创建两个分支
-- Expected-Rows: 0
DATA BRANCH CREATE TABLE test.t1 FROM test.t0;
-- Expected-Rows: 0
INSERT INTO test.t1 VALUES (4, 4);
-- Expected-Rows: 0
DATA BRANCH CREATE TABLE test.t2 FROM test.t0;
-- Expected-Rows: 0
INSERT INTO test.t2 VALUES (5, 5);
-- Expected-Rows: 2
DATA BRANCH DIFF test.t2 AGAINST test.t1;
+-------------------+--------+------+------+
| diff t2 against t1 | flag | a | b |
+-------------------+--------+------+------+
| t2 | INSERT | 5 | 5 |
| t1 | INSERT | 4 | 4 |
+-------------------+--------+------+------+
-- Expected-Rows: 0
DROP TABLE test.t0;
-- Expected-Rows: 0
DROP TABLE test.t1;
-- Expected-Rows: 0
DROP TABLE test.t2;
示例 3:使用快照比较¶
-- Expected-Rows: 0
CREATE TABLE test.t1 (a INT PRIMARY KEY, b INT);
-- Expected-Rows: 0
INSERT INTO test.t1 VALUES (1, 1), (2, 2);
-- Expected-Rows: 0
CREATE SNAPSHOT sp1 FOR TABLE test t1;
-- Expected-Rows: 0
INSERT INTO test.t1 VALUES (3, 3);
-- Expected-Rows: 1
UPDATE test.t1 SET b = 10 WHERE a = 1;
-- Expected-Rows: 0
CREATE SNAPSHOT sp2 FOR TABLE test t1;
-- Expected-Rows: 1
DATA BRANCH DIFF test.t1{SNAPSHOT='sp2'} AGAINST test.t1{SNAPSHOT='sp1'};
+--------------------+--------+------+------+
| diff t1 against t1 | flag | a | b |
+--------------------+--------+------+------+
| t1 | INSERT | 3 | 3 |
+--------------------+--------+------+------+
-- Expected-Rows: 0
DROP SNAPSHOT sp1;
-- Expected-Rows: 0
DROP SNAPSHOT sp2;
-- Expected-Rows: 0
DROP TABLE test.t1;
备注
当比较同一张表的两个快照时,系统会基于快照之间的增量变化进行比较。在此示例中,虽然 UPDATE 操作修改了 a=1 的行,但由于快照比较的特殊机制,只显示了新增的行。
示例 4:仅获取差异数量¶
-- Expected-Rows: 0
CREATE TABLE test.t1 (a INT PRIMARY KEY, b INT);
-- Expected-Rows: 0
INSERT INTO test.t1 SELECT result, result FROM generate_series(1, 1000) g;
-- Expected-Rows: 0
DATA BRANCH CREATE TABLE test.t2 FROM test.t1;
-- Expected-Rows: 0
INSERT INTO test.t2 SELECT result, result FROM generate_series(1001, 2000) g;
-- Expected-Rows: 100
DELETE FROM test.t2 WHERE a <= 100;
-- Expected-Rows: 1
DATA BRANCH DIFF test.t2 AGAINST test.t1 OUTPUT COUNT;
+----------+
| COUNT(*) |
+----------+
| 1100 |
+----------+
-- Expected-Rows: 0
DROP TABLE test.t1;
-- Expected-Rows: 0
DROP TABLE test.t2;
示例 5:限制返回行数¶
-- Expected-Rows: 0
CREATE TABLE test.t1 (a INT PRIMARY KEY, b INT);
-- Expected-Rows: 0
INSERT INTO test.t1 SELECT result, result FROM generate_series(1, 100) g;
-- Expected-Rows: 0
DATA BRANCH CREATE TABLE test.t2 FROM test.t1;
-- Expected-Rows: 0
INSERT INTO test.t2 SELECT result, result FROM generate_series(101, 200) g;
-- Expected-Rows: 5
DATA BRANCH DIFF test.t2 AGAINST test.t1 OUTPUT LIMIT 5;
+--------------------+--------+------+------+
| diff t2 against t1 | flag | a | b |
+--------------------+--------+------+------+
| t2 | INSERT | 101 | 101 |
| t2 | INSERT | 102 | 102 |
| t2 | INSERT | 103 | 103 |
| t2 | INSERT | 104 | 104 |
| t2 | INSERT | 105 | 105 |
+--------------------+--------+------+------+
-- Expected-Rows: 0
DROP TABLE test.t1;
-- Expected-Rows: 0
DROP TABLE test.t2;
备注
OUTPUT LIMIT 返回按主键完成最终排序后的前 N 行差异。
示例 6:导出差异为 SQL 文件¶
-- Expected-Rows: 0
CREATE TABLE test.t1 (a INT PRIMARY KEY, b INT);
-- Expected-Rows: 0
INSERT INTO test.t1 VALUES (1, 1), (2, 2);
-- Expected-Rows: 0
DATA BRANCH CREATE TABLE test.t2 FROM test.t1;
-- Expected-Rows: 0
INSERT INTO test.t2 VALUES (3, 3);
-- Expected-Rows: 1
UPDATE test.t2 SET b = 10 WHERE a = 1;
-- Expected-Rows: 1
DELETE FROM test.t2 WHERE a = 2;
-- Expected-Rows: 1
DATA BRANCH DIFF test.t2 AGAINST test.t1 OUTPUT FILE '/tmp/';
+------------------------------------------+------------------------------------------+
| FILE SAVED TO | HINT |
+------------------------------------------+------------------------------------------+
| /tmp/diff_t2_t1_<UTC-YYYYMMDD_HHMMSS>_<UUID>.sql | DELETE FROM `test`.`t1`, INSERT INTO `test`.`t1` |
+------------------------------------------+------------------------------------------+
-- Expected-Rows: 0
DROP TABLE test.t1;
-- Expected-Rows: 0
DROP TABLE test.t2;
上述路径是格式示意:MatrixOne 每次调用都会生成 UTC 时间戳和 UUID。v4.2 输出 .sql 补丁,其中包含所需的 DELETE FROM ... 和 INSERT INTO ... 语句。
回放补丁文件¶
回放 SQL 文件(增量同步):
mysql -h <mo_host> -P <mo_port> -u <user> -p <db_name> < diff_t2_t1_<UTC-YYYYMMDD_HHMMSS>_<UUID>.sql
示例 6b:导出差异到 Stage(对象存储)¶
Stage 是 MatrixOne 用于连接外部存储(如 S3、HDFS)的逻辑对象,可以将差异文件直接输出到对象存储,便于跨集群/跨环境同步数据。
-- Expected-Rows: 0
CREATE STAGE my_stage URL = 's3://my-bucket/diff-output/?region=us-east-1&access_key_id=xxx&secret_access_key=yyy';
DATA BRANCH DIFF test.t2 AGAINST test.t1 OUTPUT FILE 'stage://my_stage/';
+-------------------------------------------------+------------------------------------------+
| FILE SAVED TO | HINT |
+-------------------------------------------------+------------------------------------------+
| stage://my_stage/diff_t2_t1_<UTC-YYYYMMDD_HHMMSS>_<UUID>.sql | DELETE FROM `test`.`t1`, INSERT INTO `test`.`t1` |
+-------------------------------------------------+------------------------------------------+
SELECT load_file(CAST('stage://my_stage/diff_t2_t1_<UTC-YYYYMMDD_HHMMSS>_<UUID>.sql' AS DATALINK));
-- Expected-Rows: 0
DROP STAGE my_stage;
使用 Stage 的优势:
安全:无需在每次 SQL 中暴露 AK/SK,管理员配置一次即可
便捷:将复杂的 URL 路径封装成简单的对象名
跨集群同步:源端写到对象存储,目标端直接读取执行
示例 7:检测更新操作¶
-- Expected-Rows: 0
CREATE TABLE test.t0 (a INT PRIMARY KEY, b INT, c INT);
-- Expected-Rows: 0
INSERT INTO test.t0 SELECT result, result, result FROM generate_series(1, 100) g;
-- Expected-Rows: 0
DATA BRANCH CREATE TABLE test.t1 FROM test.t0;
-- Expected-Rows: 3
UPDATE test.t1 SET c = c + 1 WHERE a IN (1, 50, 100);
-- Expected-Rows: 0
DATA BRANCH CREATE TABLE test.t2 FROM test.t0;
-- Expected-Rows: 3
UPDATE test.t2 SET c = c + 2 WHERE a IN (1, 25, 75);
-- 比较差异,将检测到冲突的更新
-- Expected-Rows: 6
DATA BRANCH DIFF test.t2 AGAINST test.t1;
+--------------------+--------+------+------+------+
| diff t2 against t1 | flag | a | b | c |
+--------------------+--------+------+------+------+
| t2 | UPDATE | 1 | 1 | 3 |
| t1 | UPDATE | 1 | 1 | 2 |
| t2 | UPDATE | 25 | 25 | 27 |
| t1 | UPDATE | 50 | 50 | 51 |
| t2 | UPDATE | 75 | 75 | 77 |
| t1 | UPDATE | 100 | 100 | 101 |
+--------------------+--------+------+------+------+
-- Expected-Rows: 0
DROP TABLE test.t0;
-- Expected-Rows: 0
DROP TABLE test.t1;
-- Expected-Rows: 0
DROP TABLE test.t2;
示例 8:复合主键表的差异比较¶
-- Expected-Rows: 0
CREATE TABLE test.orders (
tenant_id INT,
order_code VARCHAR(8),
amount DECIMAL(12,2),
PRIMARY KEY (tenant_id, order_code)
);
-- Expected-Rows: 0
INSERT INTO test.orders VALUES
(100, 'A100', 120.50),
(100, 'A101', 80.00),
(101, 'B200', 305.75);
-- Expected-Rows: 0
DATA BRANCH CREATE TABLE test.orders_branch FROM test.orders;
-- 在分支上进行修改
-- Expected-Rows: 1
UPDATE test.orders_branch SET amount = 130.50 WHERE tenant_id = 100 AND order_code = 'A100';
-- Expected-Rows: 1
DELETE FROM test.orders_branch WHERE tenant_id = 100 AND order_code = 'A101';
-- Expected-Rows: 0
INSERT INTO test.orders_branch VALUES (102, 'C300', 512.25);
-- 比较差异
-- Expected-Rows: 3
DATA BRANCH DIFF test.orders_branch AGAINST test.orders;
+-----------------------------------+--------+-----------+------------+--------+
| diff orders_branch against orders | flag | tenant_id | order_code | amount |
+-----------------------------------+--------+-----------+------------+--------+
| orders_branch | UPDATE | 100 | A100 | 130.50 |
| orders_branch | DELETE | 100 | A101 | 80.00 |
| orders_branch | INSERT | 102 | C300 | 512.25 |
+-----------------------------------+--------+-----------+------------+--------+
-- Expected-Rows: 0
DROP TABLE test.orders;
-- Expected-Rows: 0
DROP TABLE test.orders_branch;
-- Expected-Rows: 0
DROP DATABASE test;
示例 9:COLUMNS 投影(v3.0.10)¶
COLUMNS (col1, ..., colN) 只返回显式请求的值列。主键仍用于内部匹配和排序,但仅在显式列出时出现在结果中。
DROP DATABASE IF EXISTS data_branch_diff_columns_demo;
CREATE DATABASE data_branch_diff_columns_demo;
USE data_branch_diff_columns_demo;
CREATE TABLE c1 (
id INT PRIMARY KEY,
name VARCHAR(30),
balance DECIMAL(12,2),
created_at TIMESTAMP,
birthday DATE
);
INSERT INTO c1 VALUES
(1, 'alice', 1000.50, '2024-01-01 10:00:00', '1990-03-15'),
(2, 'bob', 2000.75, '2024-01-02 11:00:00', '1985-07-20'),
(3, 'carol', 3000.00, '2024-01-03 12:00:00', '1992-11-08');
DATA BRANCH CREATE TABLE c1_br FROM c1;
UPDATE c1_br SET balance = 1500.50, name = 'alice_v2' WHERE id = 1;
DELETE FROM c1_br WHERE id = 2;
INSERT INTO c1_br VALUES (4, 'dave', 4000.00, '2024-02-01 09:00:00', '1988-12-25');
-- 全量 diff:所有列。
DATA BRANCH DIFF c1_br AGAINST c1;
-- 仅投影 name 列:可见结果不自动包含 id。
DATA BRANCH DIFF c1_br AGAINST c1 COLUMNS (name);
-- 投影两个非主键列。
DATA BRANCH DIFF c1_br AGAINST c1 COLUMNS (name, balance);
-- 需要显示主键时显式列出主键。
DATA BRANCH DIFF c1_br AGAINST c1 COLUMNS (id, balance);
-- COLUMNS 可以和 OUTPUT LIMIT 组合。
DATA BRANCH DIFF c1_br AGAINST c1 COLUMNS (balance) OUTPUT LIMIT 5;
DROP TABLE c1_br;
DROP TABLE c1;
DROP DATABASE data_branch_diff_columns_demo;
示例 10:线性链式差异(非相邻分支)¶
DATA BRANCH DIFF 支持跨非相邻层级的线性分支链(如 t0 -> t1 -> t2 -> t3)。当对 t3 与 t0 进行差异比较时,LCA 会通过遍历中间的克隆边解析为 t0。链式结构比扁平分叉触发了不同的 LCA 代码路径。中间的包装节点(t1、t2)对差异不可见:仅显示相关分支点之后 t0 和 t3 上的变更。
DROP DATABASE IF EXISTS test_chain_diff;
CREATE DATABASE test_chain_diff;
USE test_chain_diff;
CREATE TABLE t0(a INT PRIMARY KEY, b INT);
INSERT INTO t0 VALUES (1, 1), (2, 2), (3, 3);
DATA BRANCH CREATE TABLE t1 FROM t0;
DATA BRANCH CREATE TABLE t2 FROM t1;
-- 仅在叶子 t2 上写入
INSERT INTO t2 VALUES (4, 4), (5, 5);
UPDATE t2 SET b = b + 100 WHERE a = 1;
DELETE FROM t2 WHERE a = 2;
-- 非相邻差异:t2 与 t0(LCA = t0)
DATA BRANCH DIFF t2 AGAINST t0 OUTPUT SUMMARY;
-- 相邻差异:t2 与 t1(LCA = t1)
DATA BRANCH DIFF t2 AGAINST t1 OUTPUT SUMMARY;
-- 反向差异
DATA BRANCH DIFF t0 AGAINST t2 OUTPUT SUMMARY;
DROP TABLE t2;
DROP TABLE t1;
DROP TABLE t0;
DROP DATABASE test_chain_diff;
示例 11:多叉树差异¶
DATA BRANCH DIFF 支持复杂的多叉分支树(任意 DAG 深度)。LCA 解析覆盖兄弟叶子、表兄弟、跨子树对以及不同深度的节点对。每个差异对都测试树中结构上不同的横截面。下面是缩略伪代码,不是可直接执行的 SQL 脚本:其中有意省略了 t3 至 t18 的创建。完整可执行构造见 MatrixOne 源码中的 test/distributed/cases/git4data/branch/diff/diff_13.sql。
树形结构(4 层,19 个节点):
t0 (根节点)
/ | \\
t1 t2 t3 (第 2 层)
/ \\ | / \\
t4 t5 t6 t7 t8 (第 3 层)
/ \\ / \\ / \\ / \\ / \\
t9 t10 t11 t12 t13 t14 t15 t16 t17 t18 (第 4 层,10 个叶子)
DROP DATABASE IF EXISTS test_tree_diff;
CREATE DATABASE test_tree_diff;
USE test_tree_diff;
CREATE TABLE t0(a INT PRIMARY KEY, b INT);
INSERT INTO t0 SELECT *, * FROM generate_series(1, 20) g;
-- 自顶向下构建树,每个节点上执行 IUD
DATA BRANCH CREATE TABLE t1 FROM t0;
INSERT INTO t1 VALUES (101, 101);
UPDATE t1 SET b = 10000 WHERE a = 1;
DATA BRANCH CREATE TABLE t2 FROM t0;
INSERT INTO t2 VALUES (102, 102);
UPDATE t2 SET b = 20000 WHERE a = 2;
-- 伪代码:按 diff_13.sql 创建 t3、t4-t8 和叶子 t9-t18。
-- 叶子 vs 根节点:跨越 3 条边
DATA BRANCH DIFF t9 AGAINST t0 OUTPUT SUMMARY;
-- 叶子 vs 兄弟叶子:共享祖父节点
DATA BRANCH DIFF t9 AGAINST t10 OUTPUT SUMMARY;
-- 叶子 vs 表兄弟叶子:共享曾祖父节点
DATA BRANCH DIFF t9 AGAINST t11 OUTPUT SUMMARY;
-- 叶子 vs 跨子树表兄弟:对向子树
DATA BRANCH DIFF t9 AGAINST t13 OUTPUT SUMMARY;
-- 反向深度跨子树对
DATA BRANCH DIFF t18 AGAINST t9 OUTPUT SUMMARY;
DROP DATABASE test_tree_diff;
备注
完整的树构建和差异对见测试套件。关键特性:
任意节点对(无论深度差异)的 LCA 解析均正确。
反转方向时差异为镜像关系。
快照作用域的链式差异在每侧回放到指定时间点。
DAG 遍历在任意深度(深度 3 及以上)保持稳定。
注意事项¶
Schema evolution 兼容性:只有在列身份和主键语义仍可证明时,DIFF 才接受 schema evolution。以下矩阵同时适用于 DIFF 和 MERGE;对于 MERGE,源表的变更会合并到目标表。
Schema 变更
DIFF/MERGE 行为
列身份和属性不变、仅调整列顺序
支持
MatrixOne 可以证明血缘关系的列重命名
支持
具有显式主键且定义兼容的目标/源独有可见列
支持;DIFF 会包含该列,MERGE 只写入目标表也存在的列
源表/基准表中的列在目标表中缺失
拒绝
同名列先 DROP 再 ADD(产生新身份)
拒绝
类型、可空性、生成列定义或主键不兼容
拒绝
使用隐藏 fake primary key 的表存在目标独有列
拒绝
OUTPUT AS创建的是新的普通表,不参与上述两张输入表的 schema 兼容性检查。主键要求:虽然支持无主键的表,但建议使用带主键的表以获得更准确的差异结果。
性能考虑:对于大表,差异比较可能需要较长时间。建议使用
OUTPUT COUNT先了解差异规模。快照有效性:使用快照比较时,确保快照存在且有效。
输出文件:使用本地路径时,只要服务进程有权限,MatrixOne 会通过
MkdirAll创建缺失的父目录;最终路径必须可写。生成的 SQL 文件名包含 UTC 时间戳和 UUID,可用于回放同步。LCA 检测:系统会自动检测 LCA,无需手动指定。LCA 的存在会影响差异计算的方式。