全ての結果を一つのクエリで出そうとしてはいけない 電話で幹部と話している上司が、いきなりあなたの机に来てこう言いました。 「SQLを使って次の4つの値を調べて欲しい。開発者一人当たりの平均バグ修正数、修正したバグの中で顧客から報告された数、バグを修正した開発者の数、うちの課が取り扱っているバグの数」 あなたは怒りを抑えて、全ての答えを一気に取り出したいので、次のような複雑なクエリを書くことにしました。(これが間違い) SELECT COUNT(bp.product_id) AS how_many_products, COUNT(dev.account_id) AS how_many_devel…
副題 問題にぶつかると「正規表現を使えばいい」という人がいる。 そして問題を二つ抱えることになる。 事例:検索エンジンの必要性 webサイトで記事の数が膨大になるにつれて、検索機能の必要性が明らかになる。 分類して設置しておくことも一つの解決策だが、分類が難しい記事もあるし、結局は検索機能が必要になる。 検索には次のような用件が求められる crashで検索すると、crashed,crashes,chrashingなどが出てくる 記事が増加しても処理が重くならない 確かに、オンラインでのテキスト検索は一般的になった。 しかしSQLでテキスト検索を高速かつ正確に行うのは、簡単そうに見えて難しい。 …
ケース(ランダムセレクション) あなたはweb広告を表示するアプリケーションの担当者だ。 広告は適当なテーブルからランダムに選ばれる仕組みだ。 ある日webサイトが日に日に重くなるインシデントが起票され、その原因があなたが担当するアプリケーションにあることがわかった サンプル行をフェッチする目的をどのように達成すれば良いか... アンチパターン:データをランダムにソートする 次の方法はランダムにソートを行い、最初の行を選択する方法。 SELECT * FROM Bugs ORDER BY RAND() LIMIT 1; これはわかりやすく実装も簡単だが、データが増えるとともに弱点が出てくる。 …
概要(良いクエリ) ある程度SQLを学んだプログラマーは、クエリでGroup Byと集約関数(MIN,MAX,SUM,COUNTなど)を巧みに用いて集計することを覚える。 少量のコードで複雑なレポートを作成できる強力な機能である。 例えば「product_idごとにレポート日付の最大値を取得したい」という要件を考えると、次のようなコードになる。 SELECT product_id, MAX(data_report) FROM Bugs Group By product_id このクエリはうまく動いた。 概要(悪いクエリ) ところで、上のクエリでbug_idは幾つになるかも同時に表示したいと考え…
インデックスについて インデックスとは、データの値と格納場所を結びつけるデータベースオブジェクト。 正しく使うとデータベースの検索の高速化が可能になる。 作成例 create table staff( id int , name varchar(10), description varchar(400), PRIMARY KEY(id), index (id), index (description) ); しかしながら、インデックスを正しく理解/使用できている開発者は意外と少ないという。 また、インデックス機能について、いつ、どのタイミングで、どのカラムに対して適応するべきかを書いているマニ…
データベースで画像を保存するべき理由と方法 この記事では外部リソースに画像を保存する方法ではなく、データベースに画像を保存する方法のメリットとやり方を紹介する。 まず簡単に結論を述べると、データベースは外部リソースを管理することはできない。 であるため、バックアップなどのSQLで恩恵を受けれるはずの機能が受けれなくなってしまう。 サーバーラックが倒れたら...? 事例1:あなたはwebサイトの管理人で、webサイトでは画像を表示する機能がありその画像はデータベースには格納していません。 データベースには画像のパスだけを格納し、そのパスに画像を保存しています。 ある時事件が起きます。 データベー…
マルチカラムアトリビュート 複数列属性を持つようなアンチデザインパターンのこと。 SQLテーブルに対して列に対して年度や携帯電話番号など、これから増える可能性のあるものをカラムとして設定すると厄介な事象が発生します; 複数の値を持つ属性を格納する 例) 連絡先情報を格納するテーブルを作成するときに、電話番号は厄介なトラブルの元となる なぜなら大抵の人は電話番号を一つではなく二つ以上持っているからだ。 場合によっては三つの電話番号を持っている人もいる そんな時に次のようなテーブルを作成することも考えられるが、結論から言えばこれは悪手である。 CREATE TABLE ContactAdress …
ポリモーフィックなテーブルを作成したい。 あなたはバグレポートを管理するシステムを作成しようとしています。 そしてこのバグレポート管理システムに新たなる要件が届きました。 その要件とは「バグについてのコメントを書き込めるような機能が欲しい」というものです。 つまり、バグについての情報があるテーブルと新たに作成されたCommentsというテーブルには一対多の関連が存在する。 ところが問題は -- バグについての情報があるテーブルは一つとは限らないこと -- 例えば、issueというテーブルを継承した二つのテーブル Bugs FeatureRequests があるかもしれない。 この状態で(複数の…
この記事は? SQLアンチパターンの備忘録です。 特に今回は5章の「エンティティ アトリビュート バリュー」 と呼ばれる手法の悪い点と改善策をまとめました。 エンティティ アトリビュート バリュー とは あなたはバグレポートを管理するシステムを作成しようとしています。 UI,UX,使用する言語が決まりましたが、SQLのデータベースの方式がなかなか決められません。(データベース設計のこと) 特に、バグのデータといっても、イシュー(要望)として扱われるのか、プロブレム(問題)として扱われるのかの二種類のデータがあることに苦悩しています。これら二つをサポートしたデータベースを仮に作成した場合、どちら…