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

laravelのmigrationに関して

DBのカラムの保守などをする場合のmigrationに関して。 ポツポツ使っていたのですが、しっかりまとめてなかったのでここでまとめて見ようかと思います。 Contents1 カラム定義2 実際の実行 …

no image

EXISTSと集合

前回に引き続きEXISTSの問題です。 下記のようなテーブル(projects)があり、 project_id | step_nbr | status ———&#8 …

no image

MySQLのユーザー変更+information_schema.columns

MySQLで行うユーザーの作成について

これですが、一つのデータベースに対して行うとhost内のユーザーすべてが切り替わってしまいます …

no image

MySQL.sockファイルに関して

朝出社してテストサーバーを見るといきなりサーバーが動いていないという事態が発生。 MySQLを起動しようとすると

なるメッセージがでて …

no image

リレーションを含んだテーブルでの副問い合わせ

本日はSQLネタです。 下記のようなテーブル構成があったときとします。 注文ヘッダと注文詳細は(1:N)とします。 ここで、product_id=5を含んだ注文ヘッダーレコードを取り出したいとします。 …

アーカイブ