频道 400 条视频的元数据,我用 sqlite 存后查发布时间全错
我的频道有 400 多条视频,之前用 yt-dlp 拉过元数据,存成 JSON 放在硬盘里。想按发布时间排序时发现,直接读 JSON 再排序很慢,于是想导入 sqlite 建个索引。数据库版本是 sqlite 3.37,系统是 Ubuntu 22.04,数据量不大,但字段类型没想清楚。
第一步先把 JSON 转成 CSV,只留 video_id、title、upload_date、duration、view_count 五个字段。用 jq 转的:
jq -r '.[] | [.id, .title, .upload_date, .duration, .view_count] | @csv' videos.json > videos.csv
然后建表:
CREATE TABLE videos (
video_id TEXT PRIMARY KEY,
title TEXT,
upload_date TEXT,
duration REAL,
view_count INTEGER
);
用 .import --csv videos.csv videos 导入。之后想查 2023 年发布的视频:
SELECT * FROM videos WHERE upload_date LIKE '2023%';
结果返回 0 行。检查发现 upload_date 存的是 20230115 这种格式,没有分隔符,LIKE 匹配不上。改成 LIKE '2023%' 应该可以,但实际还是 0 行——因为 yt-dlp 的 upload_date 字段有时是 NA,CSV 导入时被当成文本了,混在数字里。
我的做法是先把 upload_date 统一成 ISO 格式,再把 NA 转成 NULL:
UPDATE videos SET upload_date = NULL WHERE upload_date = 'NA';
UPDATE videos SET upload_date = substr(upload_date,1,4) || '-' || substr(upload_date,5,2) || '-' || substr(upload_date,7,2) WHERE upload_date IS NOT NULL AND length(upload_date) = 8;
再查 2023 年:
SELECT * FROM videos WHERE upload_date LIKE '2023-%';
这次正常了。但还有另一个坑:duration 字段有小数,我定义成 REAL,导入时有些行是 NA,sqlite 会把它当 0 存进去,导致按时长排序时这些视频排在最前面。后来改成导入前用 jq 把 NA 转成 null,sqlite 才会存 NULL。
为什么用 TEXT 存日期而不是 DATE 类型?sqlite 没有真正的日期类型,用 TEXT 存 ISO 格式可以直接比较和排序,也方便导出。代价是每次查询要保证格式一致,否则索引失效。
这套方法在视频数超过 10 万时可能会慢,因为 UPDATE 全表扫描。另外如果 yt-dlp 未来改了字段格式(比如 upload_date 变成带时区的),这段 SQL 就失效了。我目前只处理了 400 条,没测过更大数据量。
你们存视频元数据时,日期字段是直接用 yt-dlp 的原格式,还是先转成标准格式再入库?
0 条评论
还没有评论,写下第一条。