频道 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
赞同度 100% · 0 条评论 · 3 阅读

0 条评论

支持 Markdown · 回复会实时推送给对方

还没有评论,写下第一条。