2016-09-11 5 views
2

私はチームを作成する必要があるプロジェクトで作業していますが、その前にそのチーム名が既に同じユーザーによって占有されているかどうかを確認する必要があります。サンプルコードは複数の信頼できるmysqlクエリをnodejsで実行する

var mysql=require('../../config/mysql_connect.js'); 
var dateFormat = require('dateformat'); 

var functions={ 

    createTeam:function(data,cb){ 

     this.checkifExists(data,function(err,result){ 

      if(err) 
      { 
       cb(err); 
      } 
      else 
      { 
       if(result.length) 
       { 
        cb(null,0); // Team name exists 
       } 
       else 
       { 
        mysql.getConnectionFromPool(function(err,con){ 

         if(err) 
         { 
          cb(err); 
         } 
         else 
         { 

          var query=con.query("Insert into team SET ? ",data,function(err,result){ 

          if(err) 
          { 
           cb(err); 
          } 
          else 
          { 
           cb(null,result.insertId); 
          } 

           con.release(); 
          }); 

          } 
         }); 
       } 
      } 
     }); 


    }, 
    checkifExists:function(data,cb){ 

     mysql.getConnectionFromPool(function(err,con){ 

      if(err) 
      { 
       cb(err); 
      } 
      else 
      { 
       var sql="Select id from team where user_id = ? and team_name like "+ con.escape('%'+data.team_name+'%') ; 

       var query=con.query(sql,[data.user_id,data.team_name],function(err,result){ 

        if(err) 
        { 
         cb(err); 
        } 
        else 
        { 
         cb(null,result); 
        } 
        con.release(); 
       }); 

       console.log(query.sql); 
      } 

     }); 
    } 
}; 

module.exports=functions; 

すべてが正常に動作しますが、そこを超える3-4のクエリで、コードが複雑になると、非管理しやすい場合がありますので、より管理しやすい方法で、この信頼性のクエリを記述するための任意の簡単な方法があります。

私はそこにもっとして3-4のクエリがあると私は二つの問題がある見ることができるように、いくつかの場合にはインデックスが

+0

あなたの質問は困惑しています。明確にするためにそれを[編集]してください。あなたはあなたが*信頼できる*を書いた*依存*クエリを意味しますか?あなたがしようとしていることをあなたのコードから伝えるのは難しいです。ユニークなインデックスを使用してユニークなチーム名などを実施することを検討しましたか? –

+0

テーブルにインデックスを追加したくありません.Dependableは、あるクエリの結果が他のクエリなどで使用されることを意味します。例:ここでは、一意のチーム名が存在するかどうかをチェックし、他のクエリは実行されませんでしたが、場合によっては他のクエリを実行する必要があるかもしれません。 – Vibhas

+0

これに関する専門用語はほとんどのSQL開発者が目的に一意のインデックスを使用します。明らかに、あなたの要件はほとんどのSQL開発者の要件とは異なります。トランザクションの使用について学ぶ必要があります。 –

答えて

1

を私のニーズを満たしていますどのような場合には、まだ同じことは、MySQL固有のインデックスを介して達成することができる知っているが、 。

  1. 1つの接続に対して開始されたトランザクションを他に渡すことはできないため、管理対象プール接続でトランザクションを使用することはできません。
  2. 各機能の接続を取得および解放します。コードを複製する必要はありません。

これらの問題を解決するには、エンティティなどの別の接続を使用できます。 1つはteam、もう1つはuserなどです。コールバック地獄を避けるために、asyncモジュールまたは約束を使用してください。

これはドラフト

// db.js 
var mysql=require('../../config/mysql_connect.js'); 
var connections = {}; 

// No, that code don't solve problems, because transaction can't started inside other. 
// Block mechanism by transaction property `is_busy` seems a bulky. 
function DB(name) { 
    if (!name) 
     // unnamed connection. Must be released on query end. 
     return mysql.getConnectionFromPool(); 

    if (!connections[name]) 
     // create always open connection 
     connections[name] = mysql.getConnectionFromPool(); 

    return connections[name]; 
} 

module.exports = DB; 

// team.js 
var dateFormat = require('dateformat'); 
var async = require('async'); 
var db = require('db')('team'); // get always-open connection for team-entity from pool 

function create (data, cb) { 
    // Here async is not necessary but used as example 
    async.waterfall([ 
     function(cb) { 
      isExists(data.user_id, data.team_name, cb); 
     }, 

     function(isTeamExists, cb) { 
      if (!isTeamExists) 
       return cb(); // go to end of waterfall 
      // is a bad statement; use enum of fields 
      db.query('insert into team SET ?', data, cb); 
     }], 

     // end waterfall chain 
     function(err, team_id) { 
      if (err) 
       return cb(err); // pass error to original cb-func 

      ...do-smth and call cb without error... 
     } 
    ); 
} 

function isExists (user_id, team_name, cb) { 
    // You can use ?? to masked input 
    db.query('select 1 from team where user_id = ?? and team_name like "%??%"', 
     [user_id, team_name], 
     function(err, res) { 
      cb(err, !err && res.length > 0); 
     } 
    ); 
} 

module.exports = { 
    create, 
    isExists 
}; 
0

これは誰もがJavaScriptで持っている基本的な問題です。私は長年にわたりこれを解決するためのさまざまな方法を試みました。

多くのオプションを試した結果、async/awaitキーワードを使用してbabelを使用することをお勧めします。使用可能であることを確認する1つの方法であるes2017プリセットを使用する場合。

これで免責事項は、あなたはまだ約束を習得しなければならないということです。 async/awaitへの約束をスキップしようとすると、意味のない約束のコードがすぐに見つかるでしょう。また、async/awaitには約束が必要です。あなたはそれを自分で教える必要があります。それに慣れるまでには少し時間がかかります。

JavaScriptで一般的に役立つもう1つのことは、4つのタブまたはタブの代わりに2つのスペースを使用することです。それはあなたのコードをはるかに読みやすくします。また、中括弧を同じ行に置き、コードを読みやすくするために必要な部分だけ余分な空白行を追加しないでください。

だから、これは正確なコードが、私はそれを行うだろうかの概要ではない:MySQLの特定のケースでは

async function existsTeam(data) { 
    const id = await query('select id ..', data); 
    return id; 
} 

async function createTeam(data) { 
    const existingId = await existsTeam(data); 
    if (existingId) return existingId; 

    const result = await query('insert into team ..', data); 
    return result.insertId; 
} 

、私はMySQLがdoesnのことを考えるの制約を強制しようとしていますdbの外部キー制約をサポートしていませんが、もしそれができれば事を簡素化できるので、二重チェックするかもしれません。しかし、Sequelize or BookshelfのORMでは、これらのタイプのクエリ/更新が簡単になる場合があります。

+0

ありがとう男ただ一つのことこのタスクのために正しいと最適な方法を使用するasyncまたはqのような約束asyncは間接的に約束を使用するので、結局は約束を学ぶ方が良いです。 – Vibhas

+0

あなたがそれを使用したときに明確ではないので、キーワードasyncに注意する必要があります。これは一般に非同期コード(Nodeが常に動作する方法、非同期対同期)、または非同期モジュール、または 'async'と' await'キーワードを参照できます。 'async'と' await'コードは明らかに(私にとっては)クリーナーです。パフォーマンスは通常似ています。 'q'はネイティブの約束や' bluebird'を使うのはお勧めしません。私は約束を学ぶことをお勧めします。 –

+0

このコンテキストでは「最適化」されています。あなたが認識しなければならないことは、ネットワークがデータベースに到達する時間は、どの計算よりも100倍〜1000倍大きい可能性があるということです。 https://gist.github.com/jboner/2841832 - これを注意深く読んでください。しかし、これらのタイプの関数をネットワークオーバーヘッドなしでループで実行すると、正確な実装(最終出力)とNode/v8エンジンのバージョンによって、JITコンパイラの最適化の種類に大きな違いが生じる可能性があります。これはこの種のケースでは関係ありません。ネットワークを待っていて、CPUはごくわずかです。 –

関連する問題