2011年12月アーカイブ

PostgreSQL Advent Calendar 25日目です。

/* ~ */ で複数行にわたるコメント

SQLでコメントを書くとき、"--"を使うのはよく知られています。

-- ここはコメントです。
-- ここもコメントです。

知らない人が結構いるのですが、/* ~ */ でブロックコメントを書くことができます。

こちらのスタイルの方が、C/Java/Javascript/PHP と同じなのでプログラマに優しいと思います。
これは標準SQL準拠です。

/*
 ここはコメント
 ここもコメント
 ここまでコメント 
*/

MongoDBのベストプラクティス10箇条

| カテゴリ:
MongoDB Best Practicesという面白い記事があったので意訳してみます。
書いた人はEngine Yardという会社のひとです。
(Amazon EC2でMongoDBを運用する場合を主に想定しているようです。)

1.必ずレプリカセット(replica sets)を使いましょう

MapReduceの処理は、はじめのうちはインタラクティブシェルで試行錯誤することになると思います。

しかしシェル上でコードを書く場合、繰り返し実行するのが不便だったり、コードをバージョン管理(Git/Subversion)システムにコミットできないとういデメリットがあります。
いろいろ試してみて手法が固まってきたら、JSコードをファイルとして保存した方がよいでしょう。

例えば、アクセスログの時間帯別集計をするMapRedcue処理を、下記のようにJSファイルとして保存します。
MapReduceでは、scopeオプションというのがあります。
これを使うと、あらかじめ作った自作関数をmap,reduce内から使うことができます。

利点は、
  • map関数本体がすっきりする
  • 単体テストがやりやすくなる

以前紹介した「MongoDB : サルでもわかるMapReduceその2:ログの時間別集計を行う」のアクセスログ集計を、scopeを使って実行してみます。

MongoDBにはJavaScriptで動くインタラクティブシェルがあります。

このシェルには、組み込みの変数やオブジェクトやメソッドがいろいろあるのですが、ヘルプやマニュアルにも書いてない便利なメソッドがたくさんあります。

例えば、Array.sumというメソッドがあって、配列の合計を求めたりできます。

Mongo shellでは、ログアウト時に変数が破棄される

MongoDBのshell上でグローバル関数を定義しても、いちどshellから抜けてしまうと関数は破棄されます。

$ ~/bin/mongo
> var wa = function (a,b){return a+b ;} 
> wa(2,3)
5
> exit
bye
(この時点で関数waは消滅する)

$ ~/bin/mongo

> wa(2,3)
Fri Dec 23 18:41:59 ReferenceError: wa is not defined (shell):1
(関数waはもう存在しない)

サーバ側に関数を保存する方法

前回の記事「MongoDB : サルでもわかるMapReduce」では、MapReduceを使った簡単な集計を行いました。
今回はもう少し実用的なことをしてみましょう。

アクセスログを時間帯別に集計する

accesslogというコレクションに、下記のようにユーザのアクセスログがたまっているとします。
> db.accesslog.find();
{ "_id" : ObjectId("4eed6c60ee5b36a552000000"), "user_id" : 141637, "timestamp" : ISODate("2011-11-01T15:00:00.223Z") }
{ "_id" : ObjectId("4eed6c60ee5b36a552000001"), "user_id" : 141637, "timestamp" : ISODate("2011-11-01T15:00:00.432Z") }
{ "_id" : ObjectId("4eed6c60ee5b36a552000002"), "user_id" : 115383, "timestamp" : ISODate("2011-11-01T15:00:02.994Z") }
{ "_id" : ObjectId("4eed6c60ee5b36a552000003"), "user_id" : 190968, "timestamp" : ISODate("2011-11-01T15:00:03.871Z") }
{ "_id" : ObjectId("4eed6c60ee5b36a552000004"), "user_id" : 160751, "timestamp" : ISODate("2011-11-01T15:00:05.071Z") }
{ "_id" : ObjectId("4eed6c60ee5b36a552000005"), "user_id" : 121768, "timestamp" : ISODate("2011-11-01T15:00:05.163Z") }
 

これを時間帯別に件数カウントしてみましょう。
MongoDBで日付情報を保存するときは、MongoDB標準のISODateで保存することが多いと思います。

ISODateで日付期間指定して検索する方法を紹介します。

例:2011-11-01から2011-11-02の期間を指定して検索する

日本時間と世界標準時は9時間の時差があると言われても、実感できない人がほとんどではないでしょうか?

そんなときは、下記の図をイメージしてみてください。

イギリス人が「ハッピーニューイヤー」の花火を打ち上げている瞬間、日本人は元旦朝9時のお雑煮をたべているの図

new_year.jpg ozoni.jpg
0時9時


出典:office.microsoft.com
MongoDBのデフォルトの日時オブジェクトはISODateというものです。

これの実装がどうなっているか調べてみました。

ISODateとは、関数であります。
ということは、ISODate関数のコードを可視化できれば、実装がわかるはずです。

Mongo Shell で"ISODate"とタイプしてみたら、コードの中身を表示することができました。

ISODateの実装

(これは、PostgreSQL Advent Calenderの企画記事です。)

PostgreSQLで、巨大なテーブル(例えばレコード数百万件~数千万件)にカラム追加・削除するときには注意が必要です。

カラム追加時にDEFAULTを設定しない

ポップアップカレンダーによる日付入力インターフェースはいろいろありますが、やはりredmineのやつが一番使いやすいと思います。
そこで、誰でも簡単に設置できるように、jQueryプラグインとして移植してみました。

デモ

日付を入力: ← クリック


どうですか?直感的でしょ?

ダウンロード

下記のページで設置方法と使い方を紹介しています。
どうぞご利用ください。

シンプルなカレンダー日付入力プラグイン jquery.simplecalendarjp.js

利用レポートの日付がわかりづらい!

AWS(Amazon Web Services)では、利用レポートをCSVでダウンローできる機能があります。

1個難点があって、日付のフォーマットが非常にわかりづらいです。

Service, Operation, UsageType, Resource, StartTime, EndTime, UsageValue
AmazonS3,GetObject,DataTransfer-Out-Bytes,8122jp,11/08/11 00:00:00,11/09/11 00:00:00,70460
AmazonS3,GetObject,DataTransfer-Out-Bytes,8122jp,11/09/11 00:00:00,11/10/11 00:00:00,36570
AmazonS3,GetObject,DataTransfer-Out-Bytes,8122jp,11/10/11 00:00:00,11/11/11 00:00:00,138692
AmazonS3,HeadObject,DataTransfer-Out-Bytes,8122jp,11/10/11 00:00:00,11/11/11 00:00:00,8758
AmazonS3,ListAllMyBuckets,DataTransfer-Out-Bytes,,11/10/11 00:00:00,11/11/11 00:00:00,933

'11/10/11'という文字列を見ただけでは、もはやどれが年で月で日なのか、判別は不可能です(泣笑)

日付はMDYです。

カスタマーサポートに問い合わせたら回答いただきました。
日付のフォーマットは、"MM/DD/YY"になっているそうです。

したがって、'11/10/11'は"11月10日2011年"を意味します。


PHP/Perlをちょろっと書く程度しかできなかったウェブエンジニアの端くれの私が、経験したトラブルとそこで4ヵ月もかかって身に着けたことを紹介します。

PostgreSQLが重い!

とにかくWebサイトが重い。

.htmlのページはすぐ表示されるんだけど、.phpのページがやたらと重い。
夜のアクセスピーク時にはめっちゃ重い。

こんなことを経験する日が来るかもしれません。
そんなときに、おそるおそるLinuxサーバにログインしてなんとかやるしかないのが、ウェブエンジニアの端くれというものです。

(対応開始)

まずは負荷を調べる

人気記事

このアーカイブについて

このページには、2011年12月に書かれたブログ記事が新しい順に公開されています。

前のアーカイブは2011年11月です。

次のアーカイブは2012年1月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

最近の人気記事