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

集合としてのSQL

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

no image

cakeでのトランザクション、コミット、ロールバック

cakePHP(2.X系)でのトランザクション、コミット、ロールバックについて。 cakePHPでトランザクションを書ける場合、Model内に [crayon-64745b942cfe51451284 …

no image

SQLで数列を扱う

今回はSQLで数列を扱ってみましょう。 例えば下記のような0から9までの数字が書かれている数列があったとして、 これにより連番を作成してみましょう。 digit ——- 0 1 …

no image

JSON型の検索

複数のタグなどを入れる場合、JSON型のカラムやデータなどを入れることがあるかと思いますが、ここから検索できるということが昨日わかりましたので、メモしておきます。 SQLServerで発見しましたが、 …

no image

SQL基礎 case式について

case式に関して。 集約系の関数では複雑な処理を一気に行うことができる。 case式は1列のみ有効。複数の列に対して行うことはできない。 case ~ when ・・・thenではwhenが評価され …

アーカイブ