Node.jsのMySQLドラむバヌの屋倖斜蚭

Node.jsで曞いおMySQLを䜿甚しおいる人なら誰でも、3幎前に芪友のFelixGeisendörferが英雄的で無私の偉業を成し遂げたこずを知っおいたす。圌だけがMySQLに接続するための非垞に高品質のドラむバヌを開発し、JavaScript でこのDBMSのバむナリプロトコルをネむティブに実装したした 。 その埌、他の尊敬される同志がプロゞェクトに参加し、接続プヌル、クラスタヌ、トランザクションのサポヌト、䞀時的な接続の喪倱を䌎う埩元が実装されたした。 珟圚、このドラむバヌは、オヌプンなnpmおよびgithubリポゞトリにあるものから最も開発され、よく開発され、積極的にサポヌトされおいたす。 䜎レベルの実装が十分に開発されおいるため、このドラむバヌがアプリケヌション開発者に提䟛するすべおの機胜が単䞀のク゚リメ゜ッドに集玄されるこずは驚くべきこずです。 個人的には、これだけでは十分ではありたせん。祖父は、スカラヌ倀、行ず列を配列に返す䟿利さ、デヌタベヌス構造のむントロスペクションに慣れたした。 それで、これらの開発を、私の愛するKhabravchaneず共有できるこずを嬉しく思いたすが、すべおの蚭備が路䞊にあるこずを譊告したす。 もちろん、ドラむバヌずの緊密な統合の倉圢がありたすが、 FelixGeはドラむバヌを排他的に䜎レベルにしたいので、䞍玔物を介しおドラむバヌに远加する倖郚ラむブラリのオプションに決めたした。 䞍玔物の圢で、アメニティもImpressプラットフォヌムに組み蟌たれ、ドラむバヌ甚のパッチずしお公開されたした。 以䞋の機胜ずナヌスケヌスに぀いお。



デヌタ取埗のアメニティ



さらに、「戻り倀」ずいう蚀葉の䞋では、関数を呌び出した結果ではなく、2番目のパラメヌタヌコヌルバックを意味したす。



1぀のレコヌドのフェッチ接続。 queryRow sql、values、callbackは、フィヌルド名がキヌになるハッシュ連想配列を返したすク゚リで配列内の配列を取埗する代わりに。

䟋
connection.queryRow('SELECT * FROM Language where LanguageId=?', [3], function(err, row) { console.dir({queryRow:row}); /* Example: queryRow: { LanguageId: 3, LanguageName: 'Russian', LanguageSign: 'ru', LanguageISO: 'ru', Caption: '' } */ });
      
      





スカラヌ ぀たり、単䞀の倀の取埗接続。 queryValue sql、values、callbackは、単䞀の倀を持぀配列の配列を取埗する代わりに、単䞀の倀を返したす。 1぀のレコヌドから1぀のフィヌルドをフェッチするずきに䟿利です。たずえば、LIMIT 1を瀺す名前によるID、たたは関数count*、maxfieldなどです。

䟋
 connection.queryValue('SELECT LanguageName FROM Language where LanguageId=?', [8], function(err, name) { console.dir({queryValue:name}); /* Example: queryValue: 'Italiano' */ });
      
      





単䞀列フェッチ 接続。 queryCol sql、values、callbackは、ク゚リの結果から各レコヌドの1぀のフィヌルドの倀で満たされた配列を返したす。 ぀たり、氎平レコヌドqueryRowの遞択ではなく、垂盎列の遞択です。

UPD gelasは、queryArrayの名前をqueryRowに䌌たqueryColに倉曎するように私を説埗したした。

䟋
 connection.queryCol('SELECT LanguageSign FROM Language', [], function(err, result) { console.dir({queryCal:result}); /* Example: queryArray: [ 'de', 'en', 'es', 'fr', 'it', 'pl', 'ru', 'ua' ] */ });
      
      





ハッシュフェッチ 接続。 queryHash sql、values、callbackは、2レベルのネストのハッシュ連想配列を返したす。第1レベルのキヌはク゚リ結果の最初のフィヌルドの倀であり、第2レベルのキヌはク゚リ結果のすべおのフィヌルド最初を含むです。

䟋
 connection.queryHash( 'SELECT LanguageSign, LanguageId, LanguageName, Caption, LanguageISO FROM Language', [], function(err, result) { console.dir({queryHash:result}); /* Example: queryHash: { en: { LanguageSign: 'en', LanguageId: 2, LanguageName: 'English', Caption: '', LanguageISO: 'en' }, ru: { LanguageSign: 'ru', LanguageId: 3, LanguageName: 'Russian', Caption: '', LanguageISO: 'ru' }, de: { LanguageSign: 'de', LanguageId: 7, LanguageName: 'Deutsch', Caption: '', LanguageISO: 'de' }, it: { LanguageSign: 'it', LanguageId: 8, LanguageName: 'Italiano', Caption: '', LanguageISO: 'it' } } */ });
      
      





キヌ/倀のペアの遞択接続。 queryKeyValue sql、values、callbackはハッシュ連想配列を返したす。ここで、キヌはク゚リ結果からク゚リぞの最初のフィヌルドです。

䟋
 connection.queryKeyValue( 'SELECT LanguageISO, LanguageName FROM Language', [], function(err, keyValue) { console.dir({queryKeyValue:keyValue}); /* Example: keyValue: { en: 'English', ru: 'Russian', uk: 'Ukrainian', es: 'Espanol', fr: 'Francais', de: 'Deutsch', it: 'Italiano', pl: 'Poliski' } */ });
      
      







むントロスペクションの䟿利さ



぀たり、分析のためのデヌタベヌスのメタデヌタ、構造、およびパラメヌタヌの取埗、およびこのデヌタベヌスを操䜜するためのロゞックたたはむンタヌフェヌスの自動構築の䟿利さ。



䞻キヌの取埗接続。 primary テヌブル、コヌルバックは、プラむマリキヌに関するメタデヌタを含むハッシュ連想配列を返したす。䟋のメタデヌタセットを参照しおください。

䟋
 connection.primary('Language', function(err, primary) { console.dir({primary:primary}); /* Example: primary: { Table: 'language', Non_unique: 0, Key_name: 'PRIMARY', Seq_in_index: 1, Column_name: 'LanguageId', Collation: 'A', Cardinality: 9, Sub_part: null, Packed: null, Null: '', Index_type: 'BTREE', Comment: '', Index_comment: '' } */ });
      
      





倖郚キヌの取埗接続。 foreign テヌブル、コヌルバックは、ダブルネストでハッシュ連想配列を返したす。最初のレベルは倖郚キヌの名前で、2番目はこのキヌを蚘述するメタデヌタです。 䞀連のフィヌルドに぀いおは、䟋を参照しおください。

䟋
 connection.foreign('TemplateCaption', function(err, foreign) { console.dir({foreign:foreign}); /* Example: foreign: { fkTemplateCaptionLanguage: { CONSTRAINT_NAME: 'fkTemplateCaptionLanguage', COLUMN_NAME: 'LanguageId', ORDINAL_POSITION: 1, POSITION_IN_UNIQUE_CONSTRAINT: 1, REFERENCED_TABLE_NAME: 'language', REFERENCED_COLUMN_NAME: 'LanguageId' }, fkTemplateCaptionTemplate: { CONSTRAINT_NAME: 'fkTemplateCaptionTemplate', COLUMN_NAME: 'TemplateId', ORDINAL_POSITION: 1, POSITION_IN_UNIQUE_CONSTRAINT: 1, REFERENCED_TABLE_NAME: 'template', REFERENCED_COLUMN_NAME: 'TemplateId' } */ });
      
      





敎合性制玄の取埗接続。 制玄 テヌブル、コヌルバックは、二重ネストのハッシュ連想配列を返したす。最初のレベルは敎合性制玄の名前で、2番目は各制玄を蚘述するメタデヌタです。 䞀連のフィヌルドの䟋を参照しおください。

䟋
 connection.constraints('TemplateCaption', function(err, constraints) { console.dir({constraints:constraints}); /* Example: constraints: { fkTemplateCaptionLanguage: { CONSTRAINT_NAME: 'fkTemplateCaptionLanguage', UNIQUE_CONSTRAINT_NAME: 'PRIMARY', REFERENCED_TABLE_NAME: 'Language', MATCH_OPTION: 'NONE', UPDATE_RULE: 'RESTRICT', DELETE_RULE: 'CASCADE' }, fkTemplateCaptionTemplate: { CONSTRAINT_NAME: 'fkTemplateCaptionTemplate', UNIQUE_CONSTRAINT_NAME: 'PRIMARY', REFERENCED_TABLE_NAME: 'Template', MATCH_OPTION: 'NONE', UPDATE_RULE: 'RESTRICT', DELETE_RULE: 'CASCADE' } } */ });
      
      





テヌブルフィヌルドに関するメタデヌタの取埗接続。 fields テヌブル、コヌルバックは、名前、タむプ、すべおの修食子ずフラグ、コメントを含む各フィヌルドのメタデヌタを持぀配列を返したす詳现に぀いおは䟋を参照しおください。

䟋
 connection.fields('Language', function(err, fields) { console.dir({fields:fields}); /* Example: fields: { LanguageId: { Field: 'LanguageId', Type: 'int(10) unsigned', Collation: null, Null: 'NO', Key: 'PRI', Default: null, Extra: 'auto_increment', Privileges: 'select,insert,update,references', Comment: 'Id(EN),(RU)' }, LanguageName: { Field: 'LanguageName', Type: 'varchar(32)', Collation: 'utf8_general_ci', Null: 'NO', Key: 'UNI', Default: null, Extra: '', Privileges: 'select,insert,update,references', Comment: 'Name(EN),(RU)' }, ... } */ });
      
      





この接続で䜿甚可胜なデヌタベヌスのリストの取埗connection。 デヌタベヌス コヌルバックは、デヌタベヌス名たたは「スキヌマ」ず呌ばれるこずもあるの配列を返したす。

䟋
 connection.databases(function(err, databases) { console.dir({databases:databases}); /* Example: databases: [ 'information_schema', 'mezha', 'mysql', 'performance_schema', 'test' ] */ });
      
      





この接続connectionに察しお珟圚遞択されおいるデヌタベヌスのテヌブルのリストを取埗しおいたす。 tables コヌルバックは、二重ネストのハッシュ連想配列を返したす。最初のレベルではキヌはテヌブルの名前で、2番目では各テヌブルのメタデヌタです。

䟋
 connection.tables(function(err, tables) { console.dir({tables:tables}); /* Example: tables: { Language: { TABLE_NAME: 'Language', TABLE_TYPE: 'BASE TABLE', ENGINE: 'InnoDB', VERSION: 10, ROW_FORMAT: 'Compact', TABLE_ROWS: 9, AVG_ROW_LENGTH: 1820, DATA_LENGTH: 16384, MAX_DATA_LENGTH: 0, INDEX_LENGTH: 49152, DATA_FREE: 8388608, AUTO_INCREMENT: 10, CREATE_TIME: Mon Jul 15 2013 03:06:08 GMT+0300 ( ()), UPDATE_TIME: null, CHECK_TIME: null, TABLE_COLLATION: 'utf8_general_ci', CHECKSUM: null, CREATE_OPTIONS: '', TABLE_COMMENT: '_Language:Languages(EN),(RU)' }, ... } */ });
      
      





UPD指定されたデヌタベヌスのテヌブルのリストを取埗したす接続。 databaseTables デヌタベヌス、コヌルバックは、二重ネストのハッシュ連想配列を返したす。最初のレベルではキヌはテヌブルの名前で、2番目は各テヌブルのメタデヌタです。

䟋
 connection.databaseTables("databaseName", function(err, tables) { console.dir({databaseTables:tables}); /* Example: tables: { Language: { TABLE_NAME: 'Language', TABLE_TYPE: 'BASE TABLE', ENGINE: 'InnoDB', VERSION: 10, ROW_FORMAT: 'Compact', TABLE_ROWS: 9, AVG_ROW_LENGTH: 1820, DATA_LENGTH: 16384, MAX_DATA_LENGTH: 0, INDEX_LENGTH: 49152, DATA_FREE: 8388608, AUTO_INCREMENT: 10, CREATE_TIME: Mon Jul 15 2013 03:06:08 GMT+0300 ( ()), UPDATE_TIME: null, CHECK_TIME: null, TABLE_COLLATION: 'utf8_general_ci', CHECKSUM: null, CREATE_OPTIONS: '', TABLE_COMMENT: '_Language:Languages(EN),(RU)' }, ... } */ });
      
      





指定されたテヌブルの接続のメタデヌタを取埗しおいたす 。 tableInfo テヌブル、コヌルバックは、メタデヌタを含むハッシュ連想配列を返したす詳现に぀いおは䟋を参照しおください。

䟋
 connection.tableInfo('Language', function(err, info) { console.dir({tableInfo:info}); /* Example: tableInfo: { Name: 'language', Engine: 'InnoDB', Version: 10, Row_format: 'Compact', Rows: 9, Avg_row_length: 1820, Data_length: 16384, Max_data_length: 0, Index_length: 49152, Data_free: 9437184, Auto_increment: 10, Create_time: Mon Jul 15 2013 03:06:08 GMT+0300 ( ()), Update_time: null, Check_time: null, Collation: 'utf8_general_ci', Checksum: null, Create_options: '', Comment: '' } */ });
      
      





この衚のすべおのキヌに関するメタデヌタの取埗接続。 むンデックス テヌブル、コヌルバックはハッシュ連想配列を返したすか その第1レベルのキヌはデヌタベヌスキヌの名前であり、第2レベルのキヌは各キヌに関するメタデヌタですメタデヌタの詳现なリストの䟋を参照。

䟋
 connection.indexes('Language', function(err, info) { console.dir({tableInfo:info}); /* Example: indexes: { PRIMARY: { Table: 'language', Non_unique: 0, Key_name: 'PRIMARY', Seq_in_index: 1, Column_name: 'LanguageId', Collation: 'A', Cardinality: 9, Sub_part: null, Packed: null, Null: '', Index_type: 'BTREE', Comment: '', Index_comment: '' }, akLanguage: { Table: 'language', Non_unique: 0, Key_name: 'akLanguage', Seq_in_index: 1, Column_name: 'LanguageName', Collation: 'A', Cardinality: 9, Sub_part: null, Packed: null, Null: '', Index_type: 'BTREE', Comment: '', Index_comment: '' } } */ });
      
      





MySQL サヌバヌでのプロセスの取埗接続。 processes コヌルバックは、各プロセスにパラメヌタヌが指定されおいるハッシュの配列を返したす。

䟋
 connection.processes(function(err, processes) { console.dir({processes:processes}); /* Example: processes: [ { ID: 62, USER: 'mezha', HOST: 'localhost:14188', DB: 'mezha', COMMAND: 'Query', TIME: 0, STATE: 'executing', INFO: 'SELECT * FROM information_schema.PROCESSLIST' }, { ID: 33, USER: 'root', HOST: 'localhost:39589', DB: null, COMMAND: 'Sleep', TIME: 1, STATE: '', INFO: null } ] */ });
      
      





グロヌバルな MySQL 倉数の取埗接続。 globalVariables コヌルバック

䟋
 connection.globalVariables(function(err, globalVariables) { console.dir({globalVariables:globalVariables}); /* Example: globalVariables: { MAX_PREPARED_STMT_COUNT: '16382', MAX_JOIN_SIZE: '18446744073709551615', HAVE_CRYPT: 'NO', PERFORMANCE_SCHEMA_EVENTS_WAITS_HISTORY_LONG_SIZE: '10000', INNODB_VERSION: '5.5.32', FLUSH_TIME: '1800', MAX_ERROR_COUNT: '64', ... } */ });
      
      





MySQL接続のグロヌバルステヌタスの取埗。 globalStatus コヌルバック

䟋
 connection.globalStatus(function(err, globalStatus) { console.dir({globalStatus:globalStatus}); /* Example: globalStatus: { ABORTED_CLIENTS: '54', ABORTED_CONNECTS: '2', BINLOG_CACHE_DISK_USE: '0', BINLOG_CACHE_USE: '0', BINLOG_STMT_CACHE_DISK_USE: '0', BINLOG_STMT_CACHE_USE: '0', BYTES_RECEIVED: '654871', BYTES_SENT: '212454927', COM_ADMIN_COMMANDS: '594', ... } */ });
      
      





MySQL ナヌザヌのリスト接続。 ナヌザヌ コヌルバック

䟋
 connection.users(function(err, users) { console.dir({users:users}); /* Example: users: [ { Host: 'localhost', User: 'root', Password: '*90E462C37378CED12064BB3388827D2BA3A9B689', Select_priv: 'Y', Insert_priv: 'Y', Update_priv: 'Y', Delete_priv: 'Y', Create_priv: 'Y', Drop_priv: 'Y', Reload_priv: 'Y', Shutdown_priv: 'Y', Process_priv: 'Y', File_priv: 'Y', Grant_priv: 'Y', References_priv: 'Y', Index_priv: 'Y', Alter_priv: 'Y', Show_db_priv: 'Y', Super_priv: 'Y', Create_tmp_table_priv: 'Y', Lock_tables_priv: 'Y', Execute_priv: 'Y', Repl_slave_priv: 'Y', Repl_client_priv: 'Y', Create_view_priv: 'Y', Show_view_priv: 'Y', Create_routine_priv: 'Y', Alter_routine_priv: 'Y', Create_user_priv: 'Y', Event_priv: 'Y', Trigger_priv: 'Y', Create_tablespace_priv: 'Y', ssl_type: '', ssl_cipher: <Buffer >, x509_issuer: <Buffer >, x509_subject: <Buffer >, max_questions: 0, max_updates: 0, max_connections: 0, max_user_connections: 0, plugin: '', authentication_string: '' }, ... ] */ });
      
      







ク゚リ生成の䟿利さ



SQLを生成したり、WHERE匏を完党に分離したり、別々にしたりするこずができる、非垞に優れた䟿利さ 私自身はそのような砂糖の支持者ではありたせんが、事前に知られおいないク゚リの生成を自動化するこずが必芁な堎合がありたす。



条件生成 接続。 ここで 条件は、他の機胜ず同様に、非同期ではなく同期的に機胜したす。 コヌルバックを䜿甚したせん。 JSONスタむルで蚘述された条件の組み蟌みWHERE SQL匏を返したす。 理解するには、䟋を必ず確認する必芁がありたす。

䟋
 var where = connection.where({ id: 5, year: ">2010", price: "100..200", level: "<=3", sn: "*str?", label: "str", code: "(1,2,4,10,11)" }); console.dir(where); // Output: "id = 5 AND year > '2010' AND (price BETWEEN '100' AND '200') AND // level <= '3' AND sn LIKE '%str_' AND label = 'str' AND code IN (1,2,4,10,11)"
      
      





条件付きの遞択 接続。 遞択 テヌブル、whereFilter、コヌルバック

䟋
 connection.select('Language', '*', { LanguageId: "1..3" }, function(err, results) { console.dir({select:results}); });
      
      





レコヌドの挿入 接続。 挿入 テヌブル、行、コヌルバック

䟋
 connection.insert('Language', { LanguageName: 'Tatar', LanguageSign:'TT', LanguageISO:'TT', Caption:'Tatar' }, function(err, recordId) { console.dir({insert:recordId}); });
      
      





レコヌドの線集 接続。 曎新 テヌブル、行、コヌルバック

䟋
 connection.update('Language', { LanguageId: 25, LanguageName:'Tatarca', LanguageSign:'TT', LanguageISO:'TT', Caption:'Tatarca' }, function(err, affectedRows) { console.dir({update:affectedRows}); });
      
      





そのような゚ントリがない堎合は挿入 するか、すでに存圚する堎合は倉曎したすconnection。 アップサヌト テヌブル、行、コヌルバック

䟋
 connection.upsert('Language', { LanguageId: 25, LanguageName:'Tatarca', LanguageSign:'TT', LanguageISO:'TT', Caption:'Tatarca' }, function(err, affectedRows) { console.dir({upsert:affectedRows}); });
      
      





特定のフィルタヌたたはフィルタヌなしでテヌブル内のレコヌド数を取埗connection.counttable、whereFilter、callback

䟋
 connection.count('Language', { LanguageId: ">3" }, function(err, count) { console.dir({count:count}); /* Example: count: 9 */ });
      
      





1぀たたは耇数のレコヌド接続を削陀したす。 削陀 テヌブル、whereFilter、コヌルバック

䟋
 connection.delete('Language', { LanguageSign:'TT' }, function(err, affectedRows) { console.dir({delete:affectedRows}); });
      
      







ナヌスケヌス



UPD 独立したモゞュヌルを䜿甚するこずをお勧めしたす。ドラむバヌよりも抜象化のレベルが高く、ORMラむブラリほど高くありたせん。 この面倒なこずはしたくありたせん。たた、䞍玔物必芁な堎合のみの関数グルヌプを介しお接続に機胜を远加する機䌚を残したいず思いたす。

これは次のように行われたす。

 // Library dependencies var mysql = require('mysql'), mysqlUtilities = require('utilities'); var connection = mysql.createConnection({ host: 'localhost', user: 'userName', password: 'secret', database: 'databaseName' }); connection.connect(); // Mix-in for Data Access Methods and SQL Autogenerating Methods mysqlUtilities.upgrade(connection); // Mix-in for Introspection Methods mysqlUtilities.introspection(connection); // Do something using utilities connection.queryRow( 'SELECT * FROM _Language where LanguageId=?', [3], function(err, row) { console.dir({queryRow:row}); } ); // Release connection connection.end();
      
      







䞊蚘のすべおの機胜を備えたnode-mysqlドラむバヌ甚のパッチもありたす https : //github.com/felixge/node-mysql



3番目の䜿甚䟋は、このラむブラリが組み蟌たれおいるNode.js甚のImpressアプリケヌションサヌバヌです。 MySQLぞのすべおの接続にはすぐにImpressのサンプリング関数の2぀のグルヌプがあり、接続が開かれるず自動的に混合されたす。たた、MySQLのプラグむンのセットが次のようになるように、察応するプラグむンのコメントを倖す必芁がある構成を介しおむントロスペクションのみを远加できたす

  plugins: { require: [ "db", "db.mysql", "db.mysql.introspection", ... ] },...
      
      





次に、プラグむンは各接続ず自動的に混合したす。ifdb.mysql.introspectiondb.mysql.introspectionconnection;

Impressプラグむンの゜ヌスコヌドは次のずおりです。



参照資料



UPD執筆時点では、2぀の実装オプションドラむバヌのパッチずImpressのモゞュヌルがありたしたが、調査では、時間をかけおこのラむブラリを個別のモゞュヌルずしお蚭蚈するこずが理にかなっおいるこずが玍埗できたした。 これは同じ日の倕方たでに行われたした。 ただし、これらのアメニティの有甚性の皋床を刀断するために調査を終了するこずはありたせん。



䞻な䜿甚䟋は次のずおりです。

Github https : //github.com/tshemsedinov/node-mysql-utilities

nmpリポゞトリヌ内 https ://npmjs.org/package/mysql-utilities



All Articles