思源笔记能用 sql 寻找文件大于 500kb 的文件吗?
如何用 sql 找到文件大小大于 500k 的
相关帖子
-
这有两种种情况,
如果你说的是引用资源,用 SQL 办不到,思源数据库并未存储引用资源占用大小,需要查询结果后通过 js 来读取文件实现,
如果你说的是思源笔记文档占用,这又分两种情况,
如果你想查看的是.sy 文件的占用大小,这通过 SQL 也办不到,需要查询后 js 来读取文件实现,
如果你说的是,纯文本内容,比如 Markdown 占用大小,这又分两种情况,
如果你说的是精确占用,这很难,除非你把查询结果存为文件,然后再读取占用大小,
如果你非得用 SQL 实现精确计算,这是非常困难的,除非你能考虑所有特殊情况,
如果你说仅仅估算大小,SQL 还是可以算算的,
如果你需要的不是估算,那么看到此就可以结束了。
如果你能接受估算,请看下文:
先说理论
首先,不同的编码存储的文件占用大小是不一样的,这里以常用的 utf8 存储为例说明,我查看了下思源数据库也是 utf8 存储的。
在 utf8 中,通常字节占用如下
- 对于 ASCII 字符(包括英文字母、数字和大多数标点符号),每个字符占用 1 字节。
- 对于非 ASCII 字符(如大部分欧洲语言字符),每个字符占用 2 字节。
- 对于中文、日文和韩文字符,每个字符通常占用 3 字节。
- 对于一些特殊字符或表情符号,每个字符可能占用 4 字节。
这里不考虑其他情况,就假设以英文和中文为主,那么英文和中文的字节占比基本上就是 1:3
那么,如果假设英文字符占比为 𝑥%,中文字符占比为 𝑦%,总字符数为 𝑛,那么可以使用以下公式来计算文件的大小(以字节为单位):
计算公式
文件大小 (字节)=(𝑥%×𝑛×1)+(𝑦%×𝑛×3)
这里:
- 𝑥%×𝑛 表示英文字符的数量,每个英文字符占用 1 字节。
- 𝑦%×𝑛 表示中文字符的数量,每个中文字符占用 3 字节。
示例
假设总字符数 𝑛=1000,其中 20% 为英文字符,80% 为中文字符,那么:
- 英文字符数量:0.2×1000=200
- 中文字符数量:0.8×1000=800
代入公式计算文件大小: 文件大小 (字节)=(0.2×1000×1)+(0.8×1000×3)=200+2400=2600
再说 SQL
有了以上公式就可以通过 SQL 计算了
首先这里按照你说的文件是指文档块来理解,那么文档块下面通常分很多容器或叶子块,但它们的 root_id 都是同一个,即文档块的 id
根据这个特点,我们通过嵌套查询就可以汇总出文档的所有块的 Markdown 文本占用大小了,不过超级复杂,仅当参考吧,下面这个 SQL 是 AI 生成的,就当作伪代码参考吧。
WITH markdown_lengths AS ( SELECT root_id, -- 计算英文字符数量 LENGTH(REPLACE(markdown, ' ', '')) FILTER (WHERE markdown ~ '[a-zA-Z0-9 ]') / LENGTH(markdown) * 100 AS x_percent, -- 计算中文字符数量 LENGTH(markdown) - LENGTH(REPLACE(markdown, ' ', '')) FILTER (WHERE markdown ~ '[a-zA-Z0-9 ]') / LENGTH(markdown) * 100 AS y_percent, -- 计算总字符数 LENGTH(markdown) AS n, -- 计算总字节数 (LENGTH(REPLACE(markdown, ' ', '')) FILTER (WHERE markdown ~ '[a-zA-Z0-9 ]') / LENGTH(markdown) * 100 * LENGTH(markdown) * 1 + (LENGTH(markdown) - LENGTH(REPLACE(markdown, ' ', '')) FILTER (WHERE markdown ~ '[a-zA-Z0-9 ]') / LENGTH(markdown) * 100 * LENGTH(markdown) * 3) / 100) AS markdown_bytes FROM blocks WHERE root_id IS NOT NULL ), subquery AS ( SELECT root_id, SUM(markdown_bytes) AS total_markdown_bytes FROM markdown_lengths GROUP BY root_id ) SELECT p.id AS parent_id, p.content AS title, p.hpath, p.markdown AS parent_markdown, COALESCE(s.total_markdown_bytes, 0) AS total_markdown_bytes FROM ( SELECT id, content, hpath, markdown FROM blocks WHERE root_id IS NULL ) p LEFT JOIN subquery s ON p.id = s.root_id WHERE COALESCE(s.total_markdown_bytes, 0) > 500000
哈哈哈,看了后,我建议你还是用 js 来实现吧。
- 其他回帖
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于