Files
Aq-Accounting-Spring/.codebuddy/memory/2026-09-28.md
T
Aqroid 0129cb1290 水印相机后端+建表语句
食物营养成分表数据
2026-09-28 09:58:38 +08:00

2.8 KiB
Raw Blame History

2026-09-28

食物营养成分表建表(中国食物成分表)

  • 新增 src/main/resources/db/migration_add_food_nutrition.sql(表 food_nutrition),并按项目惯例同步追加到 db/schema.sql。
  • 数据来源:https://nlc.chinanutri.cn/fq/(中国疾控中心营养与健康所)。
    • 列表接口:POST /fq/FoodInfoQueryAction!queryFoodInfoList.do
      • 参数:categoryOne / categoryTwo / foodName / pageNum / field / flag
      • 返回:{currentPage, totalPages, list: [[...36 元素...]]}
    • 列定义来源:/fq/foodlist_0_0_0_0_0_1.htm 里 th.ysq_code_* 的 class 名(页面为 UTF-8)。
    • 数组下标 = 表头序号 + 2([0]=食物ID、[1]=图片、[2]=食物名称,之后 34 个营养素)。
    • 关键字段名:huifen=灰分、tshhw=碳水化合物、qianwei=总膳食纤维、afte=α-TE(维生素E)、 las=硫胺素、hhs=核黄素、yanSuan=烟酸、wssC=维生素C;末尾 4 个是 SFA/MUFA/PUFA 百分比与合计。
    • 接口空值:""=无数据、"—"=未检出,入库统一 NULL;值自带单位后缀(12.7g/5.40μg/1478kJ/100%)。
    • 分类为两级:categoryOne 1..28(大类,如 1=谷类及制品),categoryTwo 30..128(子类,如 30=小麦)。
  • 校验方法:碳水 = 100 - 水分 - 蛋白质 - 脂肪 - 灰分(小麦粉各行完全吻合),据此确认了 huifen=灰分为第 11 位。
  • 修正(同上):数组共 36 元素,[0]ID [1]图片 [2]名称 [3]别名 [4]英文名 → [5]~[35] 共 31 个营养素,不是 34 个。

抓取全量数据 + 生成 INSERT(同日完成)

  • 新增 tools/fetch_food_nutrition.py(抓取 + 生成 SQL,带磁盘缓存、可断点续跑、支持 --offline 重生成)、 tools/verify_sql.py(结构/列序/逐值一致性校验)。tools/_cache/ 为 557 个原始 JSON 响应的缓存,已加入 .gitignore。
  • 产物 src/main/resources/db/data_food_nutrition.sql:1356 条食物,0.68MB,7 条批量 INSERT(200 行/批,41 列)。
  • 抓取策略:先用 categoryOne=0&categoryTwo=0 拿全量(即全集,170 页 × 8 条/页), 再遍历 20 个大类 + 91 个子类补分类标签;首页共 111 个分类链接,已全部覆盖。
  • 数据结论:Tr(微量)513 处,是唯一无法转数字的 token;只有 枸杞子(1571)、菊花(1613) 在源站没有分类归属(留 NULL)。
  • 校验结果:1356 条 × 41 字段全部正常;DDL 列序 == INSERT 列序;31 个营养素逐值与接口原始数组完全一致;raw_values JSON 合法。
  • 脚本关键点:to_num() 剥离单位后缀并统一 ""/—/Tr → NULL;sql_str() 转义 \ 与 '; verify_sql.py 里按「单引号字符串 + 括号嵌套」扫描切分元组,切分前必须先剥掉最外层圆括号。