LoginSignup
11
13

More than 5 years have passed since last update.

mysqlをrestでアクセスできてもいいじゃない

Posted at

RDB v.s KVS

KVS触っていて、「RESTAPIがあるのっていいなー」とは思う。複雑なクエリは出せないけど、curlコマンド一発でアクセスできる。だったら複雑ではないクエリなら、mysqlにそういうRESTのかぶせものがあってもいい。

mysql-to-restは nodeで使える、mysqlにREST をかぶせるライブラリ

以下、mysql-to-restを使ったサンプルソース。依存モジュールはmysql-to-restのREADMEにしたがって入れてください。手元にポケモンGOのポケモンの出現情報をためたテーブルがあるのでそれを取得してみた。

sample.js
var mysql      = require('mysql');
var connection = mysql.createConnection({
    host     : 'localhost',
    user     : 'root',
    password : '', 
    database : 'sample',
    timezone : 'Asia/Tokyo' //これいれないとUTCで出ちゃう
});

connection.connect();

var express = require('express');
var mysqltorest  = require('mysql-to-rest');
var app = express();

app.set('trust proxy', 'loopback'); // 同一セグメントからのみの接続を許可
// app.set('trust proxy', 'loopback,192.168.0.1'); // 同一セグメントプラス特定IPのみ許可 

var api = mysqltorest(app,connection);
app.listen(8000);
~                

実行

sh
> node sample.js

テスト

appearances というテーブルの、主キーが、11,12,13というレコードを取得

curl http://localhost:8000/api/appearances/11,12,13

レスポンス

json
{
  "result": "success",
  "json": [
    {
      "id": 11,
      "pokemon_id": 69,
      "pokemon_name": "マダツボミ",
      "lat": 35.64469,
      "lon": 139.687588,
      "distance": 588.94278,
      "expired": "2016-07-30 12:40:18",
      "query_lat": 35.644393,
      "query_lon": 139.681088,
      "landmark": "世田谷公園",
      "created_at": "2016-07-30 12:34:54",
      "updated_at": "2016-07-30 12:34:54"
    },
    {
      "id": 12,
      "pokemon_id": 74,
      "pokemon_name": "イシツブテ",
      "lat": 35.646162,
      "lon": 139.68679,
      "distance": 552.19259,
      "expired": "2016-07-30 12:37:13",
      "query_lat": 35.644393,
      "query_lon": 139.681088,
      "landmark": "世田谷公園",
      "created_at": "2016-07-30 12:34:54",
      "updated_at": "2016-07-30 12:34:54"
    },
    {
      "id": 13,
      "pokemon_id": 23,
      "pokemon_name": "アーボ",
      "lat": 35.649789,
      "lon": 139.68368,
      "distance": 644.8466,
      "expired": "2016-07-30 12:36:55",
      "query_lat": 35.644393,
      "query_lon": 139.681088,
      "landmark": "世田谷公園",
      "created_at": "2016-07-30 12:34:54",
      "updated_at": "2016-07-30 12:34:54"
    }
  ],
  "table": "appearances",
  "length": 3
}

他にもいろんなクエリのサンプル

実行パフォーマンス

先ほどのキーダイレクトで3件取得するというサンプルで負荷テスト。MBA 1.6 GHz Intel Core i5 のメモリ4G というなんてことのないマシン。

ab -n 1000 -c 10 http://localhost:8000/api/appearances/11,12,13
Requests per second:    473.91 [#/sec] (mean)
Time per request:       21.101 [ms] (mean)
Time per request:       2.110 [ms] (mean, across all concurrent requests)
Transfer rate:          606.28 [Kbytes/sec] received

同じクエリを流し続けているので、クエリキャッシュがきいてるはずだけど、十分早い。ちょっと重めのSQLになれば、ほとんどDB側の時間になるはず。

複雑なSQLは流せない

JOINをしたかったら?

  • 画面の一覧に出すレコードはどうせlimit 20とかそんなもん
  • 取得したあとに、20のレコードにある外部キーで、改めてキーダイレクトで取得
  • 取得したあとにプログラム側で結合 ドン臭いけど、JOINはある日突然パフォーマンスが落ちることがある。集十件のレコードを主キー取得するのはいつも一瞬。

もしくは参照頻度があまりに大きかったら、正規化崩してJOIN済みのデーブルを作っちゃっててもいい。

そこまでやるならとっととKSVを使えばいいじゃない

確かにそうなんだけど、phpmyadmin に相当するいいものがなかったり、SequelProに相当するいいツールがなかったり、オンプレミスとクラウドとローカル開発環境とを同じアーキテクチャでやろうとすると、ちょうどいいのがなかったりとか。そしてやっぱり「表」は楽ちんで、CSVに吐き出してエクセルで見るという導線はやっぱり便利。

そしていざって時に、遅くてもいいからフィールドをLIKE検索したり、groupやcountしたりする。そんなわけでまだまだmysql使っていそうな気がする。

11
13
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
13