※ パクレゼルヴではWeb開発エンジニアを大募集中!詳細はこちら

Archive

Archive for 2008/8

いつのまにストリートビュー  

2008/8/12 火曜日 15:02:53

流行に敏感なボクです。

ちょっと時代遅れ気味なのですが、Googleマップにストリートビュー機能が追加されました。
地図に表示されているその場所の風景が写真で上下左右見えちゃうわけです。
以下がサンプル。
GLatLngのところに、前前々回あたりのGoogleMap記事でのMap座標を記述すれば、その場所のストリートビューが表示されます。

<html>
<head>
<script src="http://maps.google.com/maps?file=api&v=2.x&key=*****" type="text/javascript"></script>
<script type="text/javascript">

var myPano;

function map() {
	var point = new GLatLng(**.******,**.******);
	panoramaOptions = { latlng:point };
	myPano = new GStreetviewPanorama(document.getElementById("pano"), panoramaOptions);
	GEvent.addListener(myPano,"error",NoFlash);
}

function NoFlash(errorCode) {
	if (errorCode == FLASH_UNAVAILABLE) {
		alert("FLASHに対応しておりません。");
		return;
	}
}
</script>
</head>
<body onload="map()" onunload="GUnload()">
	<div name="pano" id="pano" style="width: 500px; height: 300px"></div>
</body>
</html>

動的に、座標部分が変更できるとおもしろそうです。
・・・そんなふうに考えてた時期がボクにもありました。

下音タヌキ 未分類

アルゴリズムのちょいメモ  

2008/8/4 月曜日 17:56:30

またまた登場。かーつんです。

今回はちょっとしたメモをば。
基本中の基本なので、学生さんは覚えておくと良いかも。

例えば、
a==bとなる確率1/6
b==cとなる確率1/3
c==dとなる確率1/2
のような条件がある場合、

if(a==b && b==c && C==d){
	処理;
}

と書くのと、

if(a==b){
		if(b==c){
			if(c==d){
			処理;
		}
	}
}

と書くのは同じです。

このとき、後者の書き方をしていると、
確率の小さいものから比較した方が良いというのが直ぐわかりますが、
前者のような書き方をしていると、
ついつい確率を無視して例えば

if(b==c && a==b && c==d){
	処理;
}

なんて風に書きがちです。

やってること同じじゃん。なんて思わないでください。
このif分が100回とか10000回繰り返す処理だと、
if分で比較される回数が比較にならないほど違ってきます。

些細な書き方の違いですが、
2個目の比較、3個目の比較をするかしないか、比較する必要があるかないか、
大量データを処理するとき等は気をつけて、
自分の書いている処理を見直してみてください。

以上、か-∇-つんがお送りしました。

かーつん PHP, その他

DB設計時の注意点1  

2008/8/1 金曜日 19:52:39

本日2度目の投稿。かーつんです。

先にSQLのチューニング基礎書いたので、
今回はDB設計時の注意点など書いてみようかと思います。

みなさんDB設計するとき何を元に設計されてますか?
基本的に私に限らず画面設計を元にされることが多いのではないでしょうか。

画面にどんな項目があって、その項目にはどんな値が入って。などですね。
よく(私はそうだった)ですが、学校などでDBを教えてくれる所は、
正規化をきちんとするように。と言われるはずです。

まぁ、得られる情報・データを整理して無駄を省き、
整理整頓した形でDBに保存できるように、テーブルを作成しましょう。
という事なのですが、正直、実際の現場で一般的に教わる第三正規形を
キッチリ作り上げているDBは少ないです。

こんな事を書くと、「正規化なんてしなくて良い」と誤解されそうですが、
そういうわけでもないんですね。
現場で行われているのは、

「正規化したデータに冗長性を持たせる」

というものです。
最初からやらないというは、
「散らかるから部屋の掃除をしない」
というのと同じで、ゴミと一緒に必要なものが隠れていてわからなくなることがあります。
やっているのは、
「片付けた後に、必要なものだけを引き出す」
です。

よくあるのは、
正規化した段階でマスタっぽくなっているテーブルに
冗長性を持たせることで、集計時のSQL負荷を軽減させる。とかでしょうか。

つまり。
DB設計時には、テーブル同士の関連性を見極めて、
1テーブル更新することによる他テーブルへの影響を把握しておき、
影響による弊害を極限まで減らすことが重要です。

これがキッチリ行われていると、
テーブルを変更する際も、何も考えられていないときとは比較にならないくらい
作業量に差が出ます。
(テーブル追加なんかは無問題なんですけど、変更・削除はしんどいのです。)

では、今回はここまで。
か-д-つんがお送りしました。

かーつん データベース

【DB】ちょっとした気遣い  

2008/8/1 金曜日 18:37:15

おなかのお肉が(ry
のびーにょです
こんばんは

前回のエントリーからもつながりますが、またもや保守に関することです

DBを使う場合、いろいろなフラグが出てくると思います。
男性なのか、女性なのか。
会員なのか、非会員なのか。
新規受け付け、入金待ち、キャンセル、取り寄せ中、発送済み、入金済み
等など・・・

その場合、フラグをint型で持たせる人も多いかと思います。
かまわないと思います。
コメント残すのであれば ですけど。
ドキュメントに残してるからいいや とか、ちょっと勘弁してほしいです。
そのドキュメント、いつのドキュメントですか?ってなるんですよ。正直コメントも一緒ですけど。

DBにもコメント残す機能ありますしね。

SHOW FULL COLUMNS FROM テーブル名

で確認できますね、MySQLなら。

追加するなら

ALTER TABLE m_user CHANGE gender gender TINYINT
NOT NULL DEFAULT "1" COMMENT '1:male 2:female';

って感じですね。

つか、フラグで分けるなと。
ENUM使ってくださいと。

男女なら
ENUM(’MALE’,'FEMALE’)
会員非会員なら
ENUM(’YES’,'NO’)
新規受け付け、入金待ち、キャンセル、取り寄せ中、発送済み、入金済みなら
ENUM(’SHINKI’,'MACHI’,'CANCEL’,'TORIYOSE’,'END’,'NYUKINN’)

とかとか(最後のはあんまり良くないけど・・・数字よりは断然ましかと)

正直保守する時にソースすべて追いつつフラグの内容判断とか萎えるだけなので辞めてほしいです。

のびーにょ MySQL, データベース

SQLチューニング基礎1  

2008/8/1 金曜日 18:10:26

久々投稿かーつんです。
まだいました。はい。

今回はSQLの書き方の基本をば。
SQLって書き方一つで折角作ったインデックスを生かせるかどうかが変わったり、
同じ結果を取得する為のコストの増減が発生するんですよね。

例えば。

id   first_name   last_name    val
------------------------------------
1          taro      yamada    0.9
2          jiro       saito   0.79
3        hanako      sasaki    0.5
4         itiro      yamada    1.0
5        saburo      nomura    0.8
------------------------------------

なんていうmemberテーブルがあって、
idにプライマリ,last_nameにインデックスが指定してあるとき、

id=1を取得したければ、

SELECT * FROM member WHERE id = 1;

とまぁシンプルなSQLを書きます。
でも、こんな簡単なSQLでも、書き方一つでパフォーマンスを落とすことが可能です。
idの型ですね。
int型やsmallint型ならば WHERE id = 1 この書き方は正解ですが、
char型やvarchar型ならば WHERE id = ‘1′ と書かなければパフォーマンスが落ちます。
仮に、char型やvarchar型のものに WHERE id = 1 と書いてもエラーにはなりません。
しかし、インデックスが効かなくなるため、全レコードを捜査してしまいます。

また、last name に「yama」が入っている人を探す場合、

SELECT * FROM member WHERE last_name LIKE 'yama%';
SELECT * FROM member WHERE last_name LIKE '%yama';
SELECT * FROM member WHERE last_name LIKE '%yama%';

などと書くことが出来ますね。
各、前方一致・後方一致・部分一致の書き方ですが、
この中でインデックスが効くものがどれかわかりますか?
そう。WHERE last_name LIKE ‘yama%’の前方一致のみです。
SQLの細かい仕組みまでは述べませんが、
曖昧検索を行う場合、前方一致以外はインデックスを使用できないということを覚えておきましょう。

valが90%以上のものを取得したいとき

SELECT * FROM member WHERE (val*100) >= 90;
SELECT * FROM member WHERE val >= 0.9;

今はべた書きで書いているので、どちらで書けば良いかなんてのは一目瞭然ですが、
例えば比較対象の数値がプログラムの変数だった場合、
変数の値が90であったならば、プログラム側で0.9に変換し、
DBに格納されている値と同じようにする必要があります。
なぜならこれも、先に書いた書き方だとインデックスが効かなくなってパフォーマンスが落ちます。

今回挙げた3パターンは基礎中の基礎ですが、
意外にも忘れ去られている事があります。
もし自分の書いたSQLが悪い書き方をしているようなら、
有無を言わさず修正してしまいましょう。
こんな事でインデックス作ったのに検索結果が早くならない。
なんて、上司に相談したらきっと怒られちゃいますよ。

いじょ。かーつんがおおくりしました。

かーつん データベース