You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL中获取食材表ID插入关联表的实现问题求助

解决方案

1. 先给食材表添加唯一约束

要实现「已存在则不插入」的核心逻辑,必须先给ingredients表的ingredient字段添加唯一索引,否则无法判断食材是否重复:

ALTER TABLE ingredients ADD UNIQUE INDEX idx_ingredient (ingredient);

2. 重构SQL逻辑

你原来的SQL结构过于复杂,我们可以简化为:对每个食材,先确保它存在于ingredients表(不存在则插入),再获取其ID插入到recipeIngredients表。

高效的单食材处理SQL

利用INSERT ... ON DUPLICATE KEY UPDATE结合824220,可以在一次SQL序列中完成「确保食材存在+获取ID+插入关联表」的操作:

-- 确保食材存在,若已存在则将其ID赋值给824220
INSERT INTO ingredients (ingredient) VALUES (LOWER(?))
ON DUPLICATE KEY UPDATE id = LAST_INSERT_ID(id);

-- 插入到关联表,直接使用刚才获取的食材ID
INSERT INTO recipeIngredients (recipe_id, amount, unit_id, ingredient_id)
VALUES (?, ?, ?, 824220);

3. 修正JS代码逻辑

你的createRecipeIngredient函数存在参数不匹配、逻辑混乱的问题,以下是重构后的完整代码:

recipes.js 重构后的createRecipeIngredient

async function createRecipeIngredient(newRecipeId, ingredients) {
  // 批量处理所有食材,用Promise.all提升效率
  const processIngredient = async (item) => {
    const { ingredient, unitId, amount } = item;
    const lowerIngredient = ingredient.toLowerCase();

    // 第一步:确保食材存在并获取ID
    await db.promise().query(`
      INSERT INTO ingredients (ingredient) VALUES (?)
      ON DUPLICATE KEY UPDATE id = LAST_INSERT_ID(id);
    `, [lowerIngredient]);

    // 第二步:插入到recipeIngredients表
    await db.promise().query(`
      INSERT INTO recipeIngredients (recipe_id, amount, unit_id, ingredient_id)
      VALUES (?, ?, ?, 824220);
    `, [newRecipeId, amount, unitId]);
  };

  await Promise.all(ingredients.map(processIngredient));
}

module.exports = { getRecipe, getRecipeComments, getRecipePhotos, getUserRecipeCommentLikes, createRecipe, insertRecipePhoto, createRecipeIngredient };

routerRecipes.js 修正调用逻辑

你之前调用createRecipeIngredient时仅传入newRecipeId,需要补充传入食材数组:

router.post('/recipes/new', cloudinary.upload.single('photo'), async (req, res, _next) => {
  // 假设createRecipe返回新生成的recipe_id,需根据实际逻辑调整
  const newRecipeId = await recipeQueries.createRecipe();
  await recipeQueries.insertRecipePhoto(newRecipeId, req.user, req.file.path);
  // 传入从请求体获取的食材数组
  await recipeQueries.createRecipeIngredient(newRecipeId, req.body.ingredients);

  res.redirect('/recipes');
});

关键说明

  • 唯一索引是核心:没有ingredients.ingredient的唯一约束,ON DUPLICATE KEY逻辑无法生效,会导致重复插入食材。
  • 统一小写存储:将食材名称转为小写后存储,避免大小写差异导致的重复(比如"Sugar"和"sugar"视为同一食材)。
  • 批量处理:用Promise.all并行处理多个食材,比逐个串行处理效率更高。

内容的提问来源于stack exchange,提问作者Bryce Richey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 08:57:24