カテゴリー別アーカイブ: Database

MySQLで完全外部結合

説明のために, 2つのテーブルを定義しておきます.

table1
id title
1 パーフェクトJava
2 パーフェクトJavaScript
3 パーフェクトPHP

 

table2
id price
2 3456
3 3888
4 3200

 

完全外部結合した結果のテーブル

table1
id title id price
1 パーフェクトJava NULL NULL
2 パーフェクトJavaScript 2 3456
3 パーフェクトPHP 3 3888
NULL NULL 4 3200

 

FULL OUTER JOIN句が利用可能なデータベースであれば,

SELECT * FROM table1 FULL OUTER JOIN table2 ON table1.id = table2.id

これで片付くのですが, MySQLではFULL OUTER JOIN句をサポートしていないので, 左外部結合 (LEFT OUTER JOIN) と 右外部結合 (RIGHT OUTER JOIN) の結果の和集合 (UNION) をとることで, 完全外部結合を実現します.

SELECT * FROM table1 LEFT OUTER JOIN table2 ON table1.id = table2.id UNION SELECT * FROM table1 RIGHT OUTER JOIN table2 ON table1.id = table2.id

Mac OS X ローカルでMySQLを利用可能にする

備忘録的に…

1. まずは, MySQLをダウンロード. アカウント登録がめんどくさいけど, 費用はかからないのでご安心を

http://dev.mysql.com/downloads/mysql/

2. ダウンロードしたものをインストール (特に手動でやることはなし. ダウンロードしたファイルをダブルクリックするだけ)

3. MySQLを起動できる状態にはなっているけども, PDOインスタンスを生成しようとするとエラーが発生する. これは, PDOインスタンスに, UNIXドメインのソケットの指定がないので発生する

4. MySQLを起動して (システム環境設定のパネルにMySQLが入っているはず), コマンドプロンプトで以下のコマンドをたたく.

$ sudo mysqladmin -p version
....
Server version5.6.17
Protocol version10
ConnectionLocalhost via UNIX socket
UNIX socket/tmp/mysql.sock
....

この結果のUNIX socketのパスを覚えるなりメモしておく.

5. php.iniを編集する

設定ファイルをコピーしておきましょう

$ cp /private/etc/php.ini.default /private/etc/php.ini

php.iniの pdo_mysql.default_socket= に先ほどのUNIX socketのパスを指定する.

pdo_mysql.default_socket=/tmp/mysql.sock

念のため, ApacheとMySQLを再起動しておきます.

6. PDOインスタンス生成時にUNIXドメインのソケットを指定する.

$dsn = 'mysql'
           . ':dbname=sample'
           . ';unix_socket=/tmp/mysql.sock'
           . ';host=localhost';

$pdo = new PDO($dsn, 'root', 'password', []);

意外とやることが多いですが, これでローカル環境でもMySQLが利用できます.

Node.js + MongoDBでサウンドパッチシステム

Node.js + MongoDBでユーザ登録システムを作成したのをベースに, サウンドのセッティングをMongoDBに保存・ロードするところまで完成した. あとは, パッチの更新と削除処理と, セッション管理を実装すればとりあえず構想していたのは完成する.

ただ, セッション管理が結構問題で, Node.jsでは, PHPの$_SESSIONスーパーグローバル変数のように, セッション管理機能をもたない (らしい…). Node.jsでセッション管理するための正攻法としては, 最もメジャーなNode.jsのフレームワークであるexpressを使うこと.

…なんだけど, Node.js (+ MongoDB)を利用した (それなりに本格的な) Webアプリケーションの作成は初めてなので, フレームワークは使わないという方針で作ってきた.

となると, 自分でセッション管理を実装するか, 妥協してexpressを使うか…

 

Node.js + MongoDB クエリオブジェクト

Node.js + MongoDBでのドキュメントの検索や更新の際には, 対象のドキュメントを指定するためにクエリオブジェクトを定義してメソッドに渡す必要があります.

例えば, usernameというキーが’rilakkuma’のドキュメントのみを取得する場合,

// monogdbの読み込み
var mongodb  = require('mongodb');

// mongodb.Serverインスタンスの生成
// ポート番号はデフォルトでは27017です.
// 利用していないポート番号であれば変更可能です.
var server   = new mongodb.Server(host, mongodb.Connection.DEFAULT_PORT);

// データベースの作成 (mongodb.Dbインスタンスの生成)
// 第1引数のデータベース名は適宜変更してください
// 第2引数にはmongodb.Serverインスタンスを指定します.
// 第3引数はオプションですが, safeモードは有効にしておいたほうがいいでしょう.
var database = new mongodb.Db('database_name', server, {safe : true});

// データベースのオープン (コネクションの確立)
// 非同期APIなので, コールバック関数を指定して, オープンされたmongodb.Dbインスタンスを参照する.
// コールバック関数の第1引数は, Node.jsの非同期APIと同様にエラーオブジェクトが渡されます.
database.open(function(error, database) {
    if (error) {
        console.error(error);
        return;
    }

    // mongodb.Dbインスタンスのcollectionメソッドに
    // コレクション名を指定して,
    // mongodb.Collectionインスタンスを生成します.
    // このインスタンスからCRUDのためのメソッドを呼び出します.
    var collection = database.collection('samples');

    var query = {username : 'rilakkuma'};

    var cursor = collection.find(query);
});

また, クエリオブジェクトには, 単なる値の指定だけでなく, 表に記載しているようなキーワードを利用することで, より柔軟なクエリ力を発揮することができます.

Keyword Condition
$gt 指定した値より大きい
$lt 指定した値より小さい
$gte 指定した値以上
$lte 指定した値以下
$ne 指定した値でない
$exists trueであれば, キーが存在するドキュメント. falseであればキー存在しないドキュメント
$or クエリオブジェクトを論理和で連結
$nor クエリオブジェクトを否定論理和で連結
$and クエリオブジェクトを論理積で連結

…etc

例えば, usernameというキーが存在し, かつ, ageキーの値が20以上のドキュメントを取得するクエリオブジェクトは, こんな感じになります.

var query = {
    $and : [
        {username : {$exists : true}},
        {age           : {$gte      : 20  }}
    ]
};