【问题标题】:Multiple mysql queries with Express Node使用 Express 节点的多个 mysql 查询
【发布时间】:2018-11-22 16:33:15
【问题描述】:

我正在运行 Express 服务器并连接到 MySQL 数据库。我有两个通过user_id 引用的表。当用户提供电子邮件地址时,我需要查询 users 以找到 user_id 然后运行另一个查询以加入 tracking 表。实现这一目标的最佳方法是什么?也感谢任何对代码任何部分的最佳实践建议!

谢谢

MySQL

CREATE TABLE users (
  user_id INT NOT NULL AUTO_INCREMENT UNIQUE,
  first_name VARCHAR(100) NOT NULL,
  last_name VARCHAR(100) DEFAULT NULL,
  email VARCHAR(320) NOT NULL UNIQUE,
  date_created TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (user_id)
);

CREATE TABLE tracking (
  tracking_id INT NOT NULL AUTO_INCREMENT,
  user_id INT NOT NULL,
  metric VARCHAR(100) NOT NULL,
  unit VARCHAR(100) NOT NULL,
  amount DOUBLE DEFAULT NULL,
  date_tracked DATE,
  date_created TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (tracking_id),
  INDEX user_ind (user_id),
  FOREIGN KEY (user_id)
   REFERENCES users(user_id)
   ON DELETE CASCADE
);

Express (Nodejs)

const express = require("express");
const app = express();
const port = 3000;
var mysql = require("mysql");
var connection = mysql.createConnection({
  host: "",
  user: "",
  password: "",
  database: "tracker"
});

app.get("/data/:email/metric/:metric", (req, res) => {
  console.log(req.params);
  let user_id = "";

  connection.connect();

  connection.query(
    `SELECT user_id FROM users WHERE email = '${req.params.email}';`,
    function(error, results, fields) {
      if (error) throw error;
      user_id = results[0].user_id;
    }
  );

  connection.query(
    `SELECT users.first_name, users.last_name, users.email, tracking.metric, tracking.unit, tracking.amount, tracking.date_tracked FROM users JOIN tracking ON users.user_id = tracking.user_id WHERE users.user_id = '${user_id}' AND metric = '${
      req.params.metric
    }';`,
    function(error, results, fields) {
      if (error) throw error;
      res.send(results);
    }
  );

  connection.end();
});

app.listen(port, () => console.log(`Example app listening on port ${port}!`));

【问题讨论】:

    标签: mysql node.js express


    【解决方案1】:

    您可以通过单个查询完成此操作,只需 JOINuser_id 上的表

    SELECT 
      u.first_name, 
      u.last_name, 
      u.email, 
      t.metric, 
      t.unit, 
      t.amount, 
      t.date_tracked 
    FROM users u
    INNER JOIN tracking AS t ON t.user_id = u.user_id
    WHERE u.email = '<email>' AND t.metric = '<metric>'
    

    另外,FWIW 你应该使用参数化查询来保护自己免受 SQL 注入

    const values = [
      req.params.email, 
      req.params.metric
    ];
    connection.query(
      'SELECT ... WHERE u.email = ? AND t.metric = ?', 
      values, 
      (err, results, fields) => {
        if (err) return next(e); // propagate the error to Express, rather than throwing in the callback
    
        res.send(results);
      }
    );
    

    【讨论】:

      【解决方案2】:

      我需要查询用户以找到 user_id,然后运行另一个查询来加入跟踪表。实现这一目标的最佳方法是什么?

      只需 1 个查询即可实现:

          SELECT users.first_name, users.last_name, users.email, 
                  tracking.metric, tracking.unit, tracking.amount,
                  tracking.date_tracked 
          FROM users 
          JOIN tracking 
          ON users.user_id = tracking.user_id 
          WHERE users.email = '${req.params.email}' AND 
                metric = '${req.params.metric}
      

      对于代码的任何部分的任何最佳实践建议都表示赞赏!

      首先,你应该在服务器启动后连接到mySql。

      在每个请求上连接和断开连接都会影响性能(打开套接字并在外部连接是一项昂贵的任务)

      所以试试类似的东西:

          CONNECTION.connect().then(() => {
              // mysql is ready , let's start express server 
              // accepting connections
              app.listen(port, () => console.log(`ready on ${port}!`));
          }).catch(console.error)
      

      您应该知道的另一个好习惯是并行运行查询 与 Promise.all([])。当您需要运行多个不相关的查询时, 您可以一个接一个地执行它们,从而使所有结果的等待时间大大缩短。

      【讨论】:

        猜你喜欢
        • 2014-08-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-25
        • 1970-01-01
        • 2017-10-08
        • 2017-09-05
        相关资源
        最近更新 更多