---
# System prepended metadata

title: 2021/04/18 メンター相談
tags: [4月, メンター相談]

---

# 2021/04/18 メンター相談

###### tags: `メンター相談`,`4月`


## 124. 多対多の関連を作るときの中間テーブルには命名規則を決めていたりしますか？

課題「データベースにおけるNULLの扱い」より、issueとassigneeの中間テーブルを作った際、ペアで以下の2パターンの回答が出たので、実務ではどうされているのか聞きたいです。

- issue_assignee (そのまま二つのテーブル名を合わせる)
- assignee_issue_assignment (関連の意味を表すようにする)

### 回答
「関連の意味を表す」を使用するケースが多い。
- 類似したテーブルが複数存在した時、重複が起きない

### 余談
- ORM なら自動的に作成されるため、それにテーブル名を合わせる
- テーブルのデータが、リソース・イベントなのかを意識する事
（多対多テーブルは、高確率でイベント）

## 125. 課題「ビューを使いこなす」について質問です。

ビューのメリットについて調べた際、セキュリティの向上ということが書いてあったのですが、実務でセキュリティ対策などの目的でビューを使われることはあるのでしょうか？？

また、ビューとマテリアライズドビューをそれぞれ使用した実例がありましたら、教えて頂きたいです。

参考：https://mochipc.com/what-is-merit-of-view/#i

### 回答
- セキュリティ対策などの目的でビューを使ったことはない。松原さんは「テーブルを分けたら十分ということしか出会わなかった。」とのこと。ただ、想定される利用ケースは一つのテーブルに対して、権限を分けたい時など。管理者は全部のカラムが見れるけど、分析チームはこのカラムとこのカラムだけ見れるなど。ただ、分析・解析用にviewを使うことは通常ない。本番に対して分析・解析をすると負荷がかかるため、通常は本番環境以外のテーブルに分析・解析を行う。

- ビューとマテリアライズドビューをそれぞれ使用した実例

```
マテリアライズドビュー
横断して検索したい、性能があがる。

使用例）QAサイト上で、質問文、回答、タグをまとめて横断検索したい場合。

使って我慢できない時はalgoliaかelasticsearchを使おう
Q&Aサイトは読み取りより書き込みが多いだろうと思って待てマテリアライズドビューを採用した。
全文検索、algoliaの方が高いけど使いやすい。
データ更新頻度は、即時更新で設定した。
```


```
ビュー
クエリを使いまわしたい時は、アプリ側で制御しているため、ビューの使用経験はない。
```


## 126. テーブルの設計について質問です。
https://www.slideshare.net/SoudaiSone/postgre-sql-54919575

上記のスライドより、usersテーブルに削除フラグなどの状態を持たせるべきではなく、deleted_usersテーブルを作ることでテーブルには事実のみを持たせるべきだと書いてありました。

もし仮に、「会員ユーザー」「有料会員ユーザー」など、ユーザーのステータスが複数増えた場合、テーブルを増やすことで処理が複雑になる(例えば、退会ユーザー以外のユーザーを取得したい時にそれぞれのテーブルにリクエストを送る必要があるなどが考えられる)ので、INT型を保存するステータスカラムを作って、1 =「無料ユーザー」, 2 =「会員ユーザー」, 3 =「有料会員ユーザー」, 4 = 「大会ユーザー」のように、あえてテーブルに状態を持たせた設計を行った方がシンプルではないかと考えました。

実務で、状態を持つデータを扱う際のテーブル設計のルールや判断基準などがありましたら、教えて頂きたいです。


### 回答
各問題点を記載
- カラム内でステータスを分けた時
    - 各ステータスに関連した、下記のようなカラムが増える
        - 有料会員：有料会員登録日
        - 退会会員：退会日
    - 複数ステータスを保持できない
        - 有料会員かつ退会会員など
            退会したら、無料だったのか有料だったのかわからなくなる。
    - ステータスの意味が理解しにくい
        - 新しく入ってきた開発メンバーなどが理解しにくい
            （しかし、マスターで値を設定すれば解消される）
- テーブル毎にわけた時
    - 横断検索時、不便
    もし、テーブル毎に分ける際は、起こりうるユースケースなのかを考える。
    あらゆるステータスのユーザが欲しい時はあるのかなど。
    必要な場合は、union 句を使用した。
    
### 余談
テーブル毎にわけた時の設計手法として、テーブル継承の考え方が存在する。
Userテーブルを継承する形でDeleteUserやPaidUserテーブルを用意する(クラステーブル継承or具象テーブル継承)
全てのユーザーに共通の情報はUserテーブルに定義する。emailなど

欠点
- 更新時の複数テーブルに、またがるトランザクション管理が必要
userからデータを消して、deleteUserに動かすなど。
- そもそも全てのユーザーに共通の情報が何かは論点になる

参考：https://qiita.com/bmf_san/items/a03820b14a72db618d15

## 127. 多対多の関係を解決するために中間テーブルを導入しました。
作成した中間テーブルの主キーを単独主キーにするか複合主キーにするか議論にあがりました。
どのような条件のときに、単独主キー/複合主キー を採用するのでしょうか？

(複合主キーの場合、JOINする際に複数カラムを指定する必要があるため、複雑になってしまう？

単独主キー
TABLE issue_assignee {
    id: varchar PK
    issue_id: varchar NOT NULL FK
    assignee_id: varchar NOT NULL FK
}

複合主キー
TABLE issue_assignee {
    issue_id: varchar FK
    assignee_id: varchar FK
    PRIMARY KEY (issue_id, assignee_id)
}

### 回答
- 単独主キー/複合主キー を採用条件について
    中間テーブル内で、別物として区別したい時に使用する
    - 区別できる、必要　：複合主キー
    - 区別できない、不要：サロゲートキー（主キー）
    
### 余談
- 意味をもたないカラムを外部キーに指定する方が保守性が高まる。よくないのは、商品名などは外部キーに指定すること。経営方針の変更などで商品を商品コードで管理しようといった変更があるとデータベース側で対応できなくなってしまう。


