skillup

技術ブログ

Database

データベースアンチパターン・グレーパターンまとめ

投稿日:

本で勉強したものと自分で個人的に経験したことのまとめ

値渡しと参照渡しの混同

マスタ値が変更された場合、通常のテーブルの変更の影響をどの程度受けるかを考える。

型の制約が弱い

文字列数が異常に多かったり、not nullがあまりなかったりなど。緩すぎるといろいろと問題が起こる。特にnot null、一意制、外部キー制約、桁数には神経を配る

変更していいデータ、していけないデータ

参照されている側でどのように使われるか、変更した場合の影響度を考える。特にマスタ値の変更を気軽にできないようにする。過去のデータに影響を与える場合、履歴などを取る必要性もある。

参照系と履歴系のデータを区別する

伝票とマスタがあり、伝票に表示するデータに関して参照系(マスタが変わるとその値も変える必要があるか)か履歴系(その時の値をそのまま使い、マスタの変更があっても変化しない)をしっかり区別する

リレーションでid(サロゲートキー)にするか否か

通常のマスタのようなものはほぼサロゲートキーでOKだが状態に関するキー(例えば在庫など)は同一の意味を持つデータができる可能性があるものは状態を持ったキーでリレーションを考えるべき

状態カラム

ステータス系のカラムは注意しないと別々のものが混じることがあり。例えばステータスと削除を一緒にいれるなど。情報が同カテゴリーかを要注意する。またステータスの値に0をとらないようにする

似たようなデータの点在

簡単にテーブル同士の同期を考えない。その場しのぎのデータを作るのをやめる。意味があって似たようなデータが複数あるのはもちろん問題ない。

1テーブルのカラムを増やしすぎない

正規化されていれば原則として、1テーブルにするが、あまりにも量が多いときは別テーブルに分け、1:1型のテーブルにするのもあり。

インデックスの貼り方が不適切(なさ過ぎて検索が遅い or 多すぎて更新が遅い)

性能テストとからむが増えたデータでのパフォーマンスを想定すること。複雑なSQLはexplainで見ておくこと。プログラムではループの中でsqlを発行していないかを確認すること。一般にはリレーション系のキーではインデックスを貼ったほうが良い。

物理削除なしなためサービス稼働後しばらくたってからのデータ爆発

世の中のサービスを見ても永久にデータが保存できるサービスはない。量を考え、適切なところで削除する必要がある。

性能テスト不備

データが増えたときの実用的なパフォーマンスを考えているか。

型の不統一(特に日付と、数値)

日付がバラバラ。また数値の場合、小数点をどこまで許可するか、どのように表示するか。

トランザクションが小さすぎて落ちたときにデータ不整合がおこる

その処理が中途半端に終わった時に、不整合が起きていないか、再開できるのかを考える。

トランザクションが大きすぎて時間がかかりすぎる(一部落ちると最初から全部やり直し)

ワントランザクションが大きすぎると失敗した時に、時間的代償が大きすぎる。あまりにも大きすぎる処理は適度に分割させる。

バッチ落ちたときの対処(落ちた場所からの再開が可能か、記録が正確にされているか)

リトライする場合に、リトライができるようになっているか。記録(ログ)がわかりやすく吐かれているか。エラーを正常に返しているか。以前DBのコンバートのさいこれが甘かったため大変だった・・・

全体的に異常時の設計に甘い

例外処理全般の設計に関して。プログラムの部分であることが多いが・・・。特にレスポンスが悪いときのエラー画面など適切に出せないと実務でトラブルが起きやすい。

集計テーブルがないためにSQLが複雑になる

適切な集計テーブルがないためにSQLが巨大化していないか。

非正規化テーブルをアドホックに作ってしまう

主に集計情報を格納するためだが、リスクなどはわかって使っているか。主に参照だけのために使い、データをここに入れないほうがいい。

関連テーブルを使わずに多列構造を取ってしまう

これも完全にアウトではないが、関連テーブルを使わずにカラムに直で値を入れてしまう。簡便な分、変更がききにくい。増える上限が必ず限られているかの確証はあるのか

SQLが巨大すぎる(他の人が読めず、保守性が落ちる)

JOINなどが巨大すぎないか。4つ以上になった場合は別途わける工夫ができないか。

ループの中でSQLを発行させているため、遅い

集計できるものはいわゆるガツン系で取れないか

nullと0,空白に対する意識の弱さ

数字の場合、これらの区分けが適切か。特に日付(0000-00-00などと記録されることあり)、数字で影響度が大きく出てくる。この3つは厳密に分けること

安易なサロゲートキー(autoincrement型のid)

大体において、有益だがメリットとデメリットをわかっているか。関連テーブルでは不要なことが多い。

安易な削除フラグ

安易に論理削除をしていないか。論理削除はもちろんいいこともあるが、マイナス点もいろいろある。

データを見れるというメリットがある半面、データ量が増える(後々の検索できいてくる)、システムが複雑になる、where句で削除フラグ=0をいれないといけない、ステータスとの区別ができていないこともあるなどのデメリットもある

-Database
-,

執筆者:


comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

関連記事

no image

NOT EXISTSの利用

引き続きNOT EXISTSの利用です。 思った以上に使えますね・・・がムズイ。 今回は下記のようなテーブル(seats)があるとします。 ケースとしては新幹線の座席番号で空は席が空いている状態、占は …

no image

SQLServerについて

今までDB環境といえば、95%以上がMySQLで、残り5%がPostgreSQLでしたが、SQLServerに触ることに・・・ 名前しか聞いたことなかったのですが、ここ1か月ぐらいで少し調べたことなど …

no image

日付がらみの処理に関して(MySQL&Java)

MySQL触りだして3年ぐらいたつんですがいまだに整理できないことが多いです。(特に日付がらみ) ちょっとJavaのネタと合わせて整理しておこうかなーと思います。 Contents1 MySQLの日付 …

no image

集合としてのSQL

今まで何度かSQLが集合ということを扱ってきました。 今回はそれがよくわかる例を。 実務ではあまりないと思うのですが、集合をイメージしやすい例題として、2つのテーブルが全く同じケースを考えます。 下記 …

no image

mavenのリモートリポジトリについて

JPAでO/Rマッパーに慣れてからというもの通常のSQLをごりごり書くのが億劫になってきました。 億劫というかいろいろとリスクがありますね。 問題点としてはコンパイルするときにエラーが検知できなかった …