skillup

技術ブログ

Database

アンチパターン 参照渡しと値渡し+キー情報の設定+同一値を複数テーブルに配置+正規化が不十分+集計表+不適切なステータス値

投稿日:

本日は自分がデータベースの設計をしていて気を付かないといけないなーと思った点などを。

注意点としては設計のミスは実装で取り返しにくいことが多いので極力気を付けましょう。あといろいろなテーブルのパターンをみておいたり、他人のミスのパターンを積極的に見ておくのは大事。

マスタ値の参照渡しと値渡し

適当な言い方がおもいつかなかったので、プログラムでよく使われる参照渡しと値渡しで区別してみました。なんのことかというとある値を別のテーブルに渡すときにidだけを渡すのか、それとも値を渡すのかの違いです。

あり得るケースとしては受注明細テーブルがあったとして、商品名を表示するときにproduct_idだけ渡して表示の時だけデータをとって表示するか、それともproduct_idはもとより商品名などの情報もテーブルに埋め込むか、の差です。

この2つは全く違い、もし受注明細テーブルにproduct_idだけを渡した場合(つまり参照渡し)、商品情報が変わると受注明細もかわってしまいます。受注明細っておそらくは受注が起きた時点での情報の保存の必要があるので、この場合は値渡しが適切ですよね・・・

また商品が変わった時に他の値も動的に変えたい場合は参照渡しをする必要があります。

ちなみにECCUBEで受注のパターメーターなんかをみたところproduct_idを渡すのと商品名などの情報を渡すのを両方やってました。配送系の情報などもすべてこのパターンでした。

基本的にはその時点での情報に意味があるのか(値渡し)、参照としての情報が必要なのかをしっかり意識することが大事かと思います。

ポイントとしてはマスタが変わるとその値もかわるか(参照)として扱うのか、その時に記録された値をそのまま使うのかをしっかり区別することです。

デメリット

マスタの値が変わった時に、値が反映されない or 意図せず値が反映されてしまうというエラーが起きる。かなりクリティカルなので設計段階でしっかり考慮しておくべき。

対策

  • 値を受け取る側がマスタ系のテーブルのデータ変更をうけるものかよく考える

キー情報の設定

主キーとなるようなコード系の情報(会社コード、社員コード)のようなものを変更可能にするかいなか

デメリット

  • 変更があった場合、参照しているデータを変えてしまう(リテラシーがないユーザーの場合、あるユーザーが退職した後などに別ユーザーをいれることがある)。
  • ただ変更できないようにするとユーザーが誤って変更した時に変更できない。
  • その他、マスタ値の値を変える場合、変更が与える影響などを常に検討すること(あるいは変わってほしいのに変わらないなど)

対策

  • 値のルールをプロジェクト内でしっかり定義しておくこと
  • マスタ値の値の変更の際のの影響度について慎重になること

同一値を複数テーブルに保持

どういうことかといいますと商品テーブルと商品規格テーブル(サイズだけが違うみたいなテーブル)があって両方で同じ意味をもっているカラムを持っているみたいなケースです。

デメリット

このようなケースは基本的にないと思うが、仕様変更があったときに別テーブルを作った時に仕方なく生成する必要がでてきて、このような状態に・・・

プログラムを書いているうちにこんがらがって両方の値を見たりすることになる。同期が大変でどこかしらでずれが生じる。

対策

  • 基本行わないこと
  • 同期をとるリスクを常に考えること
  • 本当に同期すべきものかを考えること(別々の状態として定義していいのではないか?といった疑問を持つべき)
  • 安易にこっちの値をこっちにコピーみたいなことを考えないこと

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

デメリット

  • 主にマスタのデータで紐づいているデータがある場合、変更するとそのマスタを参照しているデータも影響を受ける
  • 「キー情報」の設定に近いが、単なる値ではなく、特に関係性があるものは超要注意

対策

  • 非マスタ系のデータに値がある場合、マスタの変更でどのような影響を受けるかをしっかり考えておく

正規化が不十分

正規化が不十分でリレーションの関連がおかしくなること

デメリット

  • 1:Nの関係が崩れておかしいことになる

対策

  • ER図の簡単なものでもいいので常に情報を視覚化すること
  • サンプルデータをいれてイメージを持っておくこと

集計表

値の集計的なテーブルをつくること

デメリット

  • 元データが入っているテーブルと値がずれる可能性がある。テーブル分、データサイズが増える。

対策

  • 基本的にパフォーマンスを向上させるために考えられることがほとんど。時と場合により、必要なケースもあり
  • 当たり前だが参照だけにし、集計テーブルに値は入れないようにする
  • ビューでの代替を考える
  • テーブルを作らずSQLで切り抜けられないかを考える

不適切なステータス値

主に状態やフラグ系のカラムに不適切な値を入れてしまうこと。削除フラグでもないのに0をいれてしまうなど(0=未会員,1=仮会員,2=本会員など)。次元の違う値をいれしまう(1=出荷、2=入荷、3=出品中、4=キャンセル)など。(←1,2は処理方法、3,4は商品状態でくくるべき)。削除なのかステータスなのかが不明瞭なものが多い

デメリット

  • 不適切に設定すると、変更に弱く、実装段階で困ること多い。

対策

  • プログラム言語によって0はfalse,null,空白と同値となることがあり、phpだとemptyなどで値がない状態と同じになってしまうのでフラグ系でない限りは避ける
  • ステータス系の値は持っている値の次元性が正しいものかどうかを考える。ちなみに値は1,2,3・・よりは10,20・・などととると間に値をとることができ、変更に対応ができやすくなります。

 

-Database
-

執筆者:


comment

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

関連記事

no image

MySQLのセキュアな設定

以前SSHの設定についていろいろ書いたんで今回はMySQLに関して。 Contents1 基本的な処方箋(MySQLに限らないかも)2 ホストのアクセスを制限する3 LOCAL INFILEコマンドを …

no image

DBUtils活用 その2

以前DBUtilsの活用を書きましたが、他の使い方がわかったのでメモ 以前はSelectでList<エンティティ>を取得したのですが、List<Map>でも取得できます。 ソー …

no image

サロゲートキーに関して

テーブル設計に関してのメモ。 テーブルを作る時にid int not null auto_increment primary keyを自動的に作ることが多いと思いますが、サロゲートキーといい、グレーノ …

no image

SQL問題

今までやったSQL問題などのまとめ。定期的にやる予定です・・ 自分用なのでテーブルデータとかあったりなかったりいい加減です(汗) SQLドリル 問題1 nameとageで構成されたテーブルがあるとして …

no image

インデックスについて(SQLServer)

DBのインデックスについて、今までぼんやりと検索条件の効率化についてはしっていたのですが、もう少し掘り下げて理解する必要があるなと思い、メモります。 SQLServerのインデックスについてすごくまと …

アーカイブ