17641


> `意見やディスカッションを求める質問`に該当する場合は、クローズ票を入れていただければ、直ちにクローズ致します。

例えば、ユーザーの設定により通知のオン・オフを切り替えるシステムを考えます。

データベース設計として2通りを考えました。

  1. ステータス列を作成して、オン・オフ表現する
  2. レコードの有無で、オン・オフを表現する

具体例として、ユーザー1は通知が有効、ユーザー2は通知が無効、を考えます。

1の例

[code]

    | user_id | enabled |
    |:-------:|:-------:|
    | 1       | true    |
    | 2       | false   |
    
[/code]

2の例

[code]

    | user_id |
    |:-------:|
    | 1       |
    
[/code]

1の場合、メリットとして、下記が考えられます。

  * オフであるということが明確にわかります。
  * 通知をオフにした人は何人？などの集計も簡単です。

一方で、デメリットは、量が多いことです。

  * データ量が多い (ユーザー数 x 通知の種類)

2の場合、メリットとして、

  * データ量は少ないです。

デメリットは、下記を考えました。

  * INSERT / DELETE で更新する(DELETEは遅い)
  * オフに対する集計ができない (全てからオンを引く、という状態)
  * オフに対する状態が保持できない (x日にオフになった等)

とはいえ決定打となる要素がなく、現状は、ケースバイケースで対応してしまいます。

データベース設計に関するデファクトスタンダード、  
または、書籍、積極的に発信をしいるウォッチ推奨のエンジニア、など  
ご教授願えれば幸いです。

# 参考にしたもの

[データベース設計徹底指南](http://www.slideshare.net/nippondanji/db-engineerstudyanim)

> ある物事に対する事実の集合

「通知を受け取るユーザーの集合」だと考えれば、1?  
「ユーザーの通知設定」というデータの集合だと考えれば、2?

[第1回 データベース設計とは：初めてのデータベース設計｜gihyo.jp …
技術評論社](http://gihyo.jp/dev/feature/01/database/0001)

> 概念設計では，データベースによって管理の対象とするものを現実の世界から抽出して概念モデルを作成します。

管理の対象は、ユーザーごとの通知設定。  
レコードで管理するのか、行で管理するのかは、概念モデルの時点では判明しない？


CC BY-SA 3.0
2015-09-14T03:41:09.737
16580
2015-10-24T11:06:50.973
2015-09-14T05:14:45.040
10492
7471
question
database データベース設計
有効無効を表現するためのデータベース設計にデファクトスタンダードはありますか？


2.の場合のデメリットをもう少し追加しておきましょう。

  * ワーストケースでは1.とデータ量が変わらない
  * データ変更を繰り返した場合フラグメントを起こしやすい
  * user_idをキーにしてオフのデータを検索した場合は遅くなる

1.の実装は「データ量が多い」以外にデメリットがないという点で優れています。逆に2.の実装は欠点が多く、ワーストケースでは1.と変わらないデータ量で1.よりも遅くなるリスクをはらんでいます。私なら迷わず1.の実装にするところです。


CC BY-SA 3.0
2015-10-14T09:06:59.437
17641
2015-10-14T09:06:59.437
12774
16580
answer


私の場合は、  
ユーザー通知可否以外にもコードや名称などのユーザー情報があり、まだ設計段階であるのならば  
既存のユーザーマスタに通知可否フラグの列を追加して真偽値を登録します。  
カットオーバー後に気軽にＤＢの列を加えられない状態であれば、  
やむを得ずコンスタントマスタに  
フィールド："TUCHIOKFLG"(＝通知可フラグを意味するもの)、  
キー："(ユーザーＩＤ)"  
で登録してレコードの有無で判断します。  
ステータスが考え中であり既存のユーザーマスタがあるのであれば"1"かなぁと思います。


CC BY-SA 3.0
2015-10-14T10:17:40.043
17646
2015-10-14T10:17:40.043
12753
16580
answer


デフォクトスタンダードは無いでしょうね。

書かれているように概念モデルに合わせて設計するべきとは思いますが、それがスタンダードとして確立していれば、メリットやデメリットで指摘されている事は判断基準にならないはずですが、実際のシステムの実装を考えると、速いとか重いとかは重要で軽視出来ませんので、実装重視の設計も「あり」だと思います。

概念モデルでは判明しないかどうかですが「ユーザ一人ひとりが持つ属性」なのか「『ある特定のユーザ一覧』という属性」なのか等で判明するのではないでしょうか。

例えば、ニコニコ動画のNGユーザという機能は後者のような気がします。（憶測です）

例として書かれている、ユーザごとの設定項目の有効、無効の場合を考えますと、「設定項目が無効という状態」もシステムは保持するべきですので前者だと思います。

後者の場合は、設定が無効である状態を保持しませんので、概念モデルを表して無いと思います。

（回答になってるか自身がありませんが）


CC BY-SA 3.0
2015-10-14T14:58:54.267
17654
2015-10-14T14:58:54.267
5008
16580
answer


２の場合のデメリットとして、設定の種類が増えるたびに、  
このようなテーブルが増大してしまうことが考えられます。

対して、１の場合は新たな設定項目に対する列を追加するだけで済みます。  
増大するのがテーブルではなく列になるだけといってしまえばそれまでですが、  
この手の設定は一度に複数利用することも多いので、  
１ユーザの設定を１レコードの問い合わせで取得できるこちらの方が性能上有利になります。

また、細かいテーブルが大量に増えると、リバースツールでER図を生成した際  
ごちゃごちゃするなど、設計情報を共有する観点からもいいことはありません。  
とはいえ、USERテーブルに設定項目の列だらけになって名前や住所など、  
より重要度の高いはずの列が埋もれてしまうのも、個人的にはあまり好きではありません。  
私の場合は、USERテーブルと1:1対応するUSER_SETTINGSなどのテーブルを別途作ると思います。  
（また、焦点がぼやけないよう、USER_SETTINGSの詳細は概念モデリング時には省略しておきます）

データベース設計の際には、起こりうる変更の可能性にどれだけ耐えられるかという  
観点からも設計検討されるとよいかと思います。


CC BY-SA 3.0
2015-10-24T11:06:50.973
18019
2015-10-24T11:06:50.973
12943
16580
answer