让数据访问层执行2次DB操作vs可能让DB操作失败

问题描述 投票:0回答:1

我正在使用 路由器 -> 控制器 -> 服务 -> 数据访问 架构构建 REST API。

大多数教程/示例项目都会像这样进行创建和更新(在 DAO 中):

  1. 从数据库检索现有数据
  2. 在数据库中创建/更新记录

例如 freecodecamp.com Node.js REST API 教程中的代码:

const createNewWorkout = (newWorkout) => {
  try {
    const isAlreadyAdded =
      DB.workouts.findIndex((workout) => workout.name === newWorkout.name) > -1;
    if (isAlreadyAdded) {
      throw {
        status: 400,
        message: `Workout with the name '${newWorkout.name}' already exists`,
      };
    }
    DB.workouts.push(newWorkout);
    saveToDatabase(DB);
    return newWorkout;
  } catch (error) {
    throw { status: error?.status || 500, message: error?.message || error };
  }
};

const updateOneWorkout = (workoutId, changes) => {
  try {
    const isAlreadyAdded =
      DB.workouts.findIndex((workout) => workout.name === changes.name) > -1;
    if (isAlreadyAdded) {
      throw {
        status: 400,
        message: `Workout with the name '${changes.name}' already exists`,
      };
    }
    const indexForUpdate = DB.workouts.findIndex(
      (workout) => workout.id === workoutId
    );
    if (indexForUpdate === -1) {
      throw {
        status: 400,
        message: `Can't find workout with the id '${workoutId}'`,
      };
    }
    const updatedWorkout = {
      ...DB.workouts[indexForUpdate],
      ...changes,
      updatedAt: new Date().toLocaleString("en-US", { timeZone: "UTC" }),
    };
    DB.workouts[indexForUpdate] = updatedWorkout;
    saveToDatabase(DB);
    return updatedWorkout;
  } catch (error) {
    throw { status: error?.status || 500, message: error?.message || error };
  }
};

然而,数据库操作在服务器资源方面是昂贵的。尝试创建/更新,如果需要的话让操作失败(主键已存在的记录,更新缺少必填字段等),然后捕获错误不是更好吗?也许将所有内容封装在存储过程中,这确实可能仍然首先检索数据以进行一些检查,但可以由数据库进行优化?

node.js postgresql rest database-design
1个回答
0
投票

您可以使用外键将您想要执行的所有验证移至数据库中,检查约束和触发器,如果验证失败,则会引发异常,然后在应用程序代码中处理失败/成功。

如果 INSERT/UPDATE 的验证依赖于大量数据,特别是如果您使用多个查询来获取该数据,那么效率可能会更高。将验证移至数据库中将为您节省网络往返次数。数据库可能会优化查询验证所需的数据和验证操作本身,但最有可能节省网络往返将是最大的时间节省。

© www.soinside.com 2019 - 2024. All rights reserved.