联系我们
18591797788
hubin@rlctech.com
北京市海淀区中关村南大街乙12号院天作国际B座1708室
18681942657
lvyuan@rlctech.com
上海市浦东新区商城路660号乐凯大厦26c-1
18049488781
xieyi@rlctech.com
广州市越秀区东风东路华宫大厦808号1608房
029-81109312
service@rlctech.com
西安市高新区天谷七路996号西安国家数字出版基地C座501
适用版本:OceanBase 4.x MySQL 兼容模式
适用场景:视图创建、版本发布、SQL比对、跨库迁移、故障复盘、代码评审
文档价值:从用户现象 → SQL全生命周期 → 内核AST原理 → 指针替换机制 → 同类现象汇总 → 生产风险与规范完整闭环
读者对象:DBA、后端开发、数据开发、架构师、发布运维
在 OceanBase MySQL 模式创建视图时,开发者手写 ORDER BY 字段名,数据库持久化后自动变为ORDER BY 列序号,功能等价但源码不一致。
sql
CREATE OR REPLACE VIEW v_test_mysql_style AS
SELECT
t1.col_a,
t1.col_b,
t1.col_c,
t1.col_d,
t1.col_e
FROM test_sort_table t1
ORDER BY
t1.col_b ASC,
t1.col_d DESC;
sql
CREATE VIEW `v_test_mysql_style` AS
select
`t1`.`col_a` AS `col_a`,
`t1`.`col_b` AS `col_b`,
`t1`.`col_c` AS `col_c`,
`t1`.`col_d` AS `col_d`,
`t1`.`col_e` AS `col_e`
from `test`.`test_sort_table` `t1`
order by 2, 4 desc
所有视图定义不一致问题,全部发生在解析、重写、AST存储、反解析四个阶段。
一条 CREATE VIEW SQL 完整内核流程:
Plain Text
客户端 SQL 字符串
↓
【1.词法分析 Lexer】 → 拆解关键字、标识符、符号 Token
↓
【2.语法分析 Parser】 → 生成标准抽象语法树 AST
↓
【3.语义分析 Binder】 → 校验表列、权限、类型推导、列绑定
↓
【4.查询重写 Rewriter】 → 等价逻辑改写、规范化(核心差异发生点)
↓
【5.计划生成 Optimizer】 → 生成物理执行计划
↓
【6.AST序列化存储】 → 存入系统表持久化
↓
【7.反解析 Deparser】 → SHOW CREATE VIEW 时从AST还原SQL文本
关键核心:视图存储的不是“你写的文本”,而是“规范化后的AST语法树”。
SHOW CREATE VIEW 不是读取原始文本,而是AST 反向生成 SQL。
刚解析完成的AST,排序节点保存的是列名引用:
Plain Text
SortNode {
order_items: [
{ expr: ColumnRef("col_b", table="t1"), direction: ASC },
{ expr: ColumnRef("col_d", table="t1"), direction: DESC }
]
}
此时仍然保留原始字段名。
OceanBase 在 Binder 阶段会执行 列解析与规范化:
1.遍历 ORDER BY 中的字段
2.匹配该字段在 SELECT 列表中的绝对位置
3.将列名引用指针替换为「SELECT位置索引指针」
AST结构发生不可逆替换:
ColumnRef("col_b") → SelectPositionRef(position=2)
ColumnRef("col_d") → SelectPositionRef(position=4)
OceanBase 内核C++实现中:
替换完成后:AST 永久丢失原始列名字符串信息,无法逆向还原。
系统表存储的是:带位置序号的标准化AST,不再存在任何字段名排序信息。
SHOW CREATE VIEW 执行逻辑:
最终呈现:ORDER BY 2,4 DESC
| 设计维度 | 详细底层说明 |
|---|---|
| 双模式统一架构 | OB同时兼容MySQL/Oracle,Oracle原生依赖位置排序。统一转为序号引用,一套优化器、一套执行引擎支撑双模式。 |
| 分布式执行简化 | 分布式并行排序、分片排序无需解析表名、别名、关联关系,直接按列索引排序,降低跨节点计算开销。 |
| 彻底消除列名歧义 | 多表JOIN、同名字段、别名覆盖场景,列名存在歧义,位置索引绝对唯一,无解析错误。 |
| 提升执行计划缓存命中率 | 消除写法差异(带表名/不带表名/别名),归一化SQL结构,大幅减少计划缓存碎片。 |
| 视图物化与合并优化 | 视图展开、嵌套视图改写、物化视图计算时,列位置映射更稳定,避免解析失败、逻辑错乱。 |
所有「源码与SHOW CREATE不一致」问题,全部来自 AST规范化+反解析不可逆 机制:
| 现象场景 | 用户原始写法 | OB落地展示结果 | 统一内核原理 |
|---|---|---|---|
| 排序语句改写 | ORDER BY col_b | ORDER BY 2 | 列名指针替换为位置指针 |
| CASE语句补空分支 | CASE WHEN ... END | CASE ... ELSE NULL END | 隐式语法显式归一化 |
| CAST字符集补全 | CAST(col AS CHAR) | CAST(col AS CHAR CHARSET utf8mb4) | 反解析补全默认参数 |
| 标识符大小写归一 | select * from tEsT | select * from test | 内核统一标识符格式 |
| 字符串转义归一 | 'O'Reilly' | 'O''Reilly' | 反解析统一转义规则 |
总结:所有差异均不是BUG,是OB内核AST规范化的统一设计。
视图SELECT列顺序变更 → 序号排序静默错乱
例如:视图头部新增字段,原有 ORDER BY 2、4 排序列彻底错位,无报错、无告警,业务数据排序逻辑悄悄变更,属于严重隐形生产风险。
若必须调整列顺序:必须同步手动修正 ORDER BY 序号,重新建视图并核对数据。
批量识别库内所有存在「数字排序、存在错位风险」的视图:
sql
SELECT
TABLE_SCHEMA AS DB_NAME,
TABLE_NAME AS VIEW_NAME,
VIEW_DEFINITION
FROM INFORMATION_SCHEMA.VIEWS
WHERE VIEW_DEFINITION REGEXP 'ORDER BY [0-9]'
AND TABLE_SCHEMA NOT IN ('information_schema','mysql','oceanbase')
ORDER BY TABLE_SCHEMA,TABLE_NAME;