doris 根据文件夹id,一条sql语句获取到它本身及所有子文件、孙文件
·
取决于 Apache Doris 的版本。
Apache Doris 是基于 MySQL 协议开发的 MPP 架构 OLAP 数据库。它的 SQL 兼容性在近年来提升很快,但递归查询的支持情况如下:
1. 核心结论
- Doris 2.0 及以上版本: 支持。可以使用
WITH RECURSIVE语法(与 MySQL 8.0 类似)。 - Doris 1.x 版本: 不支持。旧版本不支持递归 CTE。
方案一:使用递归 CTE (适用于 Doris 2.0+)
如果你的 Doris 集群版本较新(建议 2.0.0 以上),语法与 MySQL 8.0 完全一致。
前提: 表结构为邻接表模型(id, parent_id)。
WITH RECURSIVE FolderTree AS (
-- 1. 锚点:查询起始文件夹
SELECT
id,
parent_id,
name,
0 AS depth
FROM folders
WHERE id = 100 -- 替换为你的文件夹 ID
UNION ALL
-- 2. 递归:查询子节点
SELECT
f.id,
f.parent_id,
f.name,
ft.depth + 1
FROM folders f
INNER JOIN FolderTree ft ON f.parent_id = ft.id
)
SELECT * FROM FolderTree;
注意事项:
- 版本检查:在执行前,请确认
SHOW VERSION;确保是 2.0+。 - 性能警告:Doris 是 OLAP(分析型) 数据库,擅长海量数据聚合,不擅长 这种点查 + 递归的 OLTP(事务型)场景。如果文件夹层级非常深(例如超过 100 层)或数据量极大,递归查询可能会导致 FE(前端节点)负载过高或查询超时。
- 递归深度限制:Doris 内部可能有递归深度限制,如果层级过深可能会报错。
方案二:路径枚举法 (推荐用于 Doris)
这是在 Doris 中更推荐的方案。 由于 Doris 的设计初衷是加速分析查询,避免在查询时进行复杂的递归计算 是最佳实践。通过在写入时维护好 path 字段,查询时只需一次简单的 LIKE 匹配,性能远好于递归 CTE。
1. 表结构建议 增加一个 path 字段,存储从根到当前节点的所有 ID 路径。
CREATE TABLE folders (
id BIGINT,
parent_id BIGINT,
name VARCHAR(255),
path VARCHAR(2048), -- 例如:",1,5,100,"
INDEX idx_path (path) -- Doris 支持前缀索引或倒排索引优化 LIKE
) ENGINE=OLAP
DUPLICATE KEY(id)
DISTRIBUTED BY HASH(id) BUCKETS 10;
2. 数据示例
- 根节点 (ID 1):
path = ',1,' - 子节点 (ID 5):
path = ',1,5,' - 孙节点 (ID 100):
path = ',1,5,100,'
3. 查询语句 假设你要查 ID 为 100 的文件夹及其所有子孙。首先你需要知道 100 的 path 是 ',1,5,100,'。
-- 方法 A: 如果你已知该节点的路径
SELECT * FROM folders
WHERE path LIKE ',1,5,100,%';
-- 方法 B: 如果你只知道 ID,不知道路径,可以结合子查询 (依然是一条 SQL)
SELECT * FROM folders
WHERE path LIKE (
SELECT CONCAT(path, '%')
FROM folders
WHERE id = 100
);
为什么在 Doris 中推荐方案二?
- 性能极高:
LIKE 'prefix%'可以利用索引,避免递归计算开销。 - 兼容性好:支持所有 Doris 版本(包括 1.x)。
- 符合 OLAP 特性:将计算复杂度从“读时”转移到了“写时”(插入/更新文件夹时维护 path),更适合 Doris 的批量写入和快速查询模型。
总结建议
| 场景 | 推荐方案 | 原因 |
|---|---|---|
| Doris 2.0+ 且层级浅 | WITH RECURSIVE | 语法标准,无需改表结构,适合临时查询。 |
| 生产环境 / 高频查询 | 路径枚举 (path 字段) | 最推荐。查询性能最好,不依赖版本,避免递归带来的 FE 压力。 |
| Doris 1.x | 路径枚举 (path 字段) | 唯一可行的一条 SQL 方案。 |
特别提醒: 文件/文件夹的层级关系通常属于元数据(Metadata),数据量相对较小但关系复杂。
- 如果这是核心业务元数据,通常建议存放在 MySQL / PostgreSQL 中。
- 如果存放在 Doris 中,通常是为了配合文件的其他业务数据(如文件大小、创建时间、日志等)进行联合分析。如果是这种情况,方案二(路径枚举) 是绝对的首选。
更多推荐
所有评论(0)