MW211 EXIT

devlog
PHP/file関数の排他制御
2013年02月21日
「file()」や「file_get_contents()」では排他制御ができない。

排他制御には「flock()」が必要で、この引数の一つがファイルポインタで、
つまりは、ファイルポインタがないと排他制御ができないのだが、
「file()」や「file_get_contents()」はファイルポインタがない
(敢えて意識しないような作りの)関数だからだ。

ま、読み込む分には、リトライとか必要ないからそれでいいのかもしれないが、
書き込みとセットで「読み込み~書き込み」の間を独占したい場合には、
排他制御が必要となってくる。

ということで、実現方法としては、ダミーの排他用ファイルを用意して、
そちらで排他の真似事のようなこと(といっても思いっきり排他だけど)をする。

  (1) 排他用ファイルをロックする
  (2) 「file()」とかを使って読み込む
  (3) 「fopen()」「fwrite()」「fclose()」を組み合わせて書き込む
  (4) 排他用ファイルをアンロックする

これにより、(1)~(4)の区間が排他占有となり、(2)と(3)も排他占有となるという寸法。
┌──────────────────────────────────────┐
│$fp = fopen('lock.txt','w');                                                │
│flock($fp, LOCK_EX);                                                        │
├──────────────────────────────────────┤
│fclose($fp);                                                                │
└──────────────────────────────────────┘
「flock()」の対義語的な「funlock()」(そんなのないけど)は、
「fclose()」が内包してくれてる感じかな。

追記:と思ったら、PHP5.3.2以降ではアンロックを
      「fclose()」が内包してくれない仕様になってしまった
…というわけで続く。。。
分類:PHP
PostgreSQL/条件分岐UPDATE文
2013年02月20日
条件によりUPDATEしたい値を変えたい場合には、CASE文が使える。
┌──────────────────────────────────────┐
│UPDATE 表                                                                   │
│    SET 列 = (CASE                                                          │
│                WHEN 条件 THEN 値                                           │
│                ELSE           値                                           │
│              END);                                                         │
└──────────────────────────────────────┘
CASE文の前後を囲む括弧はなくてもよいみたい。
分類:PostgreSQL
PostgreSQL/ランダムな並び替え
2013年02月19日
「ORDER BY」句に「random()」を使う。

こんな感じ。
┌──────────────────────────────────────┐
│SELECT 列 FROM 表 ORDER BY random();                                        │
└──────────────────────────────────────┘
分類:PostgreSQL
PostgreSQL/乱数に重みをつける
2013年02月18日
ただランダムに値を取得するのではなく、頻度を分けたい場合がある。
「1」の目を多く出るようにしたい場合とかである(コンプガチャか!?)

こういう場合は、配列と組み合わせてこんな感じにできるであろう。
┌──────────────────────────────────────┐
│SELECT (ARRAY[1,1,2,3,4,5,6])[trunc(random() * 7) + 1];               →1~6│
└──────────────────────────────────────┘
これだと、「1」(はずれ?)の目の確率が他の二倍となる。
分類:PostgreSQL
PostgreSQL/乱数
2013年02月17日
乱数は「random()」で「0以上1未満」の値が取得できる。

「trunc()」(切り捨て)と組み合わせると、「0から指定した値未満まで」を取得できる。
┌──────────────────────────────────────┐
│SELECT trunc(random() * 10);                                          →0~9│
└──────────────────────────────────────┘
分類:PostgreSQL
PostgreSQL/剰余計算
2013年02月15日
「mod()」を使う。
「mod(割られる数,割る数)」の書式だ。

試しにいろいろな数を「3」で割ってみると。
┌──────────────────────────────────────┐
│SELECT mod(-4,3);                                                       →-1│
│SELECT mod(-3,3);                                                       → 0│
│SELECT mod(-2,3);                                                       →-2│
│SELECT mod(-1,3);                                                       →-1│
│SELECT mod( 0,3);                                                       → 0│
│SELECT mod( 1,3);                                                       → 1│
│SELECT mod( 2,3);                                                       → 2│
│SELECT mod( 3,3);                                                       → 0│
│SELECT mod( 4,3);                                                       → 1│
└──────────────────────────────────────┘
分類:PostgreSQL
PostgreSQL/ANALYZEとは(2)
2013年02月14日
で、実際の「ANALYZE」の実行について。

┌──────────────────────────────────────┐
│ANALYZE;                                                                    │
└──────────────────────────────────────┘
単なる「ANALYZE」は、全ての表を対象とする。

┌──────────────────────────────────────┐
│ANALYZE 表;                                                                 │
└──────────────────────────────────────┘
もちろん表を絞り込むことができる。

┌──────────────────────────────────────┐
│ANALYZE VERBOSE;                                                            │
└──────────────────────────────────────┘
「VERBOSE」を付けると進行状況を報告してくれる。
分類:PostgreSQL
PostgreSQL/ANALYZEとは(1)
2013年02月13日
「ANALYZE」は「統計情報」を最新に更新してくれる機能。

SQLでデータを読み込む時に、いろいろな方法がある。
目的地にたどり着くのにいろいろな経路があるようなものだ。

意識しなくても、一番最適な(最速な)経路をみつけてくれる(実行計画という)のだが、
その判断根拠となるのが、「統計情報」になる。

インプット情報が正しくなければ正しい結果は導き出せないので、
「統計情報」ってのはかなり大事だといえよう。

たいていは、「VACUUM」同様、都度、統計情報は最新に更新されるモードがとられるが、
任意で実行したい場合には「ANALYZE」を使う。

┌──────────────────────────────────────┐
│EXPLAIN SQL文;                                                              │
└──────────────────────────────────────┘
SQL文の先頭に「EXPLAIN」を付けて実行すると、実行計画が提示される。
┌──────────────────────────────────────┐
│… (cost=… rows=1234 …)                                                   │
└──────────────────────────────────────┘

さらに「EXPLAIN ANALYZE」にすると、実行計画の提示とともに
実際に実行してその見積もり(実行計画)がどうだったか教えてくれる。
┌──────────────────────────────────────┐
│EXPLAIN ANALYZE SQL文;                                                      │
└──────────────────────────────────────┘
こんな感じの結果となる。
┌──────────────────────────────────────┐
│… (cost=… rows=1234 …) (actual … rows=123456 …)                        │
└──────────────────────────────────────┘
「actual」(実際に)の後が、実際の結果だ。
見積もりでは「1234」だったのに、実際にやってみたら「123456」だった…って
見積もり大間違いじゃんというオチである。

ま、そんな時に「ANALYZE」を実行して、「統計情報」を最新にってことだ。

ちなみに、「ANALYZE」は全件調査するわけではなく、無作為抽出調査だ。
そのサンプル数を増やせば改善される場合もある。
分類:PostgreSQL
PostgreSQL/VACUUMを復習
2013年02月12日
「VACUUM」というのは簡単にいえば「お掃除係」。

┌──────────────────────────────────────┐
│VACUUM;                                                                     │
└──────────────────────────────────────┘
単なる「VACUUM」は、ゴミ領域のお掃除をしてくれるだけ。(なので排他とか関係ない)

┌──────────────────────────────────────┐
│VACUUM FULL;                                                                │
└──────────────────────────────────────┘
「VACUUM FULL」は、お掃除に加えて整理整頓をしてくれる。よって排他がかかる。
つまり、効果は大きいが、遅い・場所をとる・占有するっていう弊害がある。
やるんなら、覚悟してやるってことだね。

┌──────────────────────────────────────┐
│VACUUM 表;                                                                  │
└──────────────────────────────────────┘
表を指定すればその表だけを対象にできる。

┌──────────────────────────────────────┐
│VACUUM VERBOSE;                                                             │
└──────────────────────────────────────┘
「VERBOSE」を付けると進行状況を報告してくれる。

┌──────────────────────────────────────┐
│VACUUM ANALYZE;
└──────────────────────────────────────┘
「ANALYZE」を付けると、「ANALYZE」もやってくれる。

ん?「ANALYZE」って何だ?

ということで、次回へ続く。
分類:PostgreSQL
PostgreSQL/COPY句を使ってファイル出力
2013年02月09日
「COPY」句は、結果をファイルとして出力してくれる便利な命令。
出力先ファイルは上書されるので注意。

テーブルをバイナリファイル形式で出力する。
┌──────────────────────────────────────┐
│COPY BINARY 表 TO 'C:\表.bin';                                              │
└──────────────────────────────────────┘

テーブルをTSVファイル形式で出力する。
┌──────────────────────────────────────┐
│COPY 表 TO 'C:\表.tsv';                                                     │
└──────────────────────────────────────┘

テーブルをCSVファイル形式で出力する。
┌──────────────────────────────────────┐
│COPY 表 TO 'C:\表.csv' WITH CSV;                                            │
└──────────────────────────────────────┘

任意の区切文字を指定して出力する。(以下の例では「|」を区切文字として指定)
┌──────────────────────────────────────┐
│COPY 表 TO 'C:\表.txt' USING DELIMITERS '|';                                │
└──────────────────────────────────────┘
区切文字は1バイト文字しかダメなようです。

NULL文字を置換する。(以下の例ではNULL文字を「??」に置換するよう指定)
┌──────────────────────────────────────┐
│COPY 表 TO 'C:\表.txt' WITH NULL AS '??';                                 │
└──────────────────────────────────────┘
こちらはなんでもOKのようです。

文字コードを指定して出力する。(以下の例では「Shift_JIS」を指定)
┌──────────────────────────────────────┐
│COPY 表 TO 'C:\表.txt' WITH encoding 'SJIS';                                │
└──────────────────────────────────────┘

SQLの結果も出力できます。(っていうか、こっちが本題っぽい)
┌──────────────────────────────────────┐
│COPY (SELECT NOW()) TO 'C:\表.txt';                                         │
└──────────────────────────────────────┘
分類:PostgreSQL
前へ 1 … 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 … 156 次へ