【DB設計】スキーマを分けるシチュエーション

## 執筆動機
[昨日のアドベントカレンダーの記事](https://qiita.com/hayami04/items/b17b1d056128a5c67355)を読んだ人から、「スキーマって何？」と聞かれました。
口頭で説明したのですが、Qiitaでググった範囲では同じような記事にヒットしなかったので、備忘も兼ねて書きます。

## スキーマとは

### スキーマとは

> データベースにおけるスキーマとは、「データベースの構造を表現する設計図」となり、三層スキーマアーキテクチャと呼ばれる構造で定義されます。
>
>＊データベース設計全体における抽象的な概念であるため、通常のユーザーや管理者が意識することはありません。
>
> 🔗[データベースのスキーマを理解する(株式会社システムインテグレータ)](https://products.sint.co.jp/siob/blog/db-schema) より

### 三層スキーマ構造

みなさまおなじみ三層スキーマ構造。
三層スキーマアーキテクチャには主に2つの方式があります。

#### 1. 「外部スキーマ - 概念スキーマ - 内部スキーマ」方式

現代でいわゆる「三層スキーマ構造」と言った時に指すのはこちらの方式です。

>ANSI/SPARC 3層スキーマとも呼ばれ、データの論理的および物理的な独立性の確保を主眼としています。
>
>この方式は、現代の多くの商用データベースシステムで採用されており、アプリケーション開発者がデータの物理的な格納方法を考えずに、データの論理的な構造とアプリケーションのデータビューに集中できるというメリットがあります。
>
>🔗[3層スキーマアーキテクチャとは？初心者向けにデータベースの仕組みを解説](https://analytics-okinawa.jp/database/1997/) より

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2632896/f8815adc-5af6-e7bc-6650-623115d6a244.png)
引用：[データベースのスキーマを理解する(株式会社システムインテグレータ)](https://products.sint.co.jp/siob/blog/db-schema)

<br>

#### 2. 「概念スキーマ - 論理スキーマ - 物理スキーマ」方式

>概念スキーマで扱おうとする概念とその関係性を定義し、論理スキーマでこれらを具体的なデータモデルに表現し、最後に物理スキーマでデータの具体的な格納・管理方式を定義します。
>
>この方式は、特にデータウェアハウスや大規模なデータ分析プロジェクトで使用されます。ここでは、概念スキーマがビジネスモデルやビジネスプロセスを反映し、論理スキーマが特定のデータモデル（例えば、星形スキーマ）を用いてこれを表現し、物理スキーマがデータの格納とパフォーマンスの最適化に重点を置きます。
>
>🔗[3層スキーマアーキテクチャとは？初心者向けにデータベースの仕組みを解説](https://analytics-okinawa.jp/database/1997/) より

<br>

#### 3. 本記事で扱うスキーマ
本記事では、現代の主流な方式 **「外部スキーマ - 概念スキーマ - 内部スキーマ」方式** を前提として話を展開します。
その中でも、開発者やDB管理者がどのようにデータ構造を設計するか、といった点に着目するため、**本記事でいう「スキーマ」とは、実質的に「外部スキーマ - 概念スキーマ - 内部スキーマ」方式の「概念スキーマ」のことを指します。**

<br>

## スキーマを分けるシチュエーション
私の認識するスキーマを分けるシチュエーションと例は、以下のとおりです。


- 機密性の高いデータやデータの閲覧・編集等ができる人員を制限したい時
    - アクセス権限の分離
        - 特定スキーマを作成してそこにテーブルを突っ込む＋アクセス権限を付与することでアクセス権限を分離することができる

<br>

- 特定のテーブルをグループ化して周期的に他DBからバッチによって更新をかけたい時
    - 定期更新対象をひとまとめにしておくため
        - ひとまとめにしておくことで、スキーマ名称で人間側が特定のテーブルがどういう扱いをされているか認識しやすくなる
        - とはいえ、更新対象をひとまとめにしておくというよりは、ビジネスの構造上そのようにスキーマを定義するのが有用であるということが前提

<br>

- 開発者がアクセスするテーブルとDB管理者のみがアクセスするテーブルを分離して管理したい時
    - アクセス権限の分離、とも通じるが、組織における担当による責任範囲の分離という側面もある
    - もっと詳細にいうと、DB管理者のメンテ頻度によってわけるということもある認識（どうだろう）

<br>

## ほか、調べてみたメリット等

ふむ。概念といったかんじです。
> リレーショナルデータベースシステムは、強固なスキーマがあることに大きく依存しています。優れたスキーマ設計における目標には、次のようなものがあります。
> - データの冗長性を低減または排除。
> - データの矛盾や不正確さを防止。
> - データの正確性と整合性を確保。
> - データの検索、取得、分析を迅速に実施。
> - 機密性の高いデータを安全に保ちつつ必要な人がアクセス可能。
>
> 🔗[データベーススキーマ設計の完全ガイド](https://www.integrate.io/jp/blog/complete-guide-to-database-schema-design-guide-ja/) より

<br>

たしかに、より具体性のある例として個人情報をより厳密に管理するための分離、というのは実例としてわかりやすいですね。

> - アクセス権とセキュリティー
>：データベース・スキーマの設計は、データを個別のエンティティーに編成する際に役立ち、別のデータベース内での単一スキーマの共有をより簡単にします。管理者はまた、データベース許可を通じてアクセスを制御し、さらに多くの専有データのセキュリティーを強化できます。例えば、ある1つのスキーマに、プライバシーとセキュリティーのために暗号化したいと思う個人情報（PII）が含まれている場合などです。
>
> 🔗[データベース・スキーマとは(IBM)](https://www.ibm.com/jp-ja/topics/database-schema) より

<br>

ここではスキーマを文書化することが取り上げられていますが、たしかにスキーマの分離によって関係者（開発者）が自分はどのデータまでアクセスしていいのか認識しやすくなるというメリットはありそう。

> - 組織化とコミュニケーション
>： データベース・スキーマを文書化することで、内部の利害関係者間の組織化が強化され、コミュニケーションが向上します。共通の信頼できる情報源が提供されるため、ユーザーはテーブル間の論理的制約と集約手法を把握できるようになります。
>
> 🔗[データベース・スキーマとは(IBM)](https://www.ibm.com/jp-ja/topics/database-schema) より

<br>

これはもう少し運用よりの観点かも（開発時から運用を考えるのは当然だろうという話は置いておいて） 外部参照制約はテーブルごとにかけるイメージが強いけれど、それをスキーマ単位でかけるみたいなこと？

ChatGPTに聞いたら「学生スキーマ、授業コーススキーマ、授業登録スキーマがあった時に、履修登録スキーマのテーブルは学生スキーマのテーブルのStudentIDと授業コーススキーマのテーブルのCourseIDを参照しなければならないようにするみたいなことだよ」と言っていた。

つまり、この例をもう少しかみ砕くならば、「学生スキーマ」には入学年ごとの「学生テーブル」があり、「授業コーススキーマ」には年度ごとの「授業予定テーブル」があり、それらの登録結果を持っておく「履修登録スキーマ」にある「Ｎ年度春学期履修登録テーブル」に登録されるデータは、学生スキーマにある学生テーブルのキーと、授業コーススキーマにある授業予定テーブルのキーと結合できなければデータが存在できないようにする、という仕様にすることという理解。

> - 整合性
>：こうした組織化とコミュニケーションは、データの妥当性の確保にも役立ちます。例えば、管理者が正規化プロセスを管理してデータの重複を回避するのに役立ちます。また、スキーマのデータベース設計における制約の準拠性の監視にも役立ち、ACID特性（原子性、一貫性、独立性、耐久性）への準拠を可能にします。
>
> 🔗[データベース・スキーマとは(IBM)](https://www.ibm.com/jp-ja/topics/database-schema) より

<br>

たしかに。物理的にDBを複数構築するほどでもない… でもデータは分離したい… というニーズに適している気がする。Excelで例えるならばシートみたいなもののような。

> 一つのデータベースサーバーで複数のアプリケーション向けのDBを持つ場合、一つのスキーマだとどのテーブルがどちらのアプリケーションのものか混乱しますし、例えば顧客テーブルが両方に有った時に名前をどちらかが変更しなければなりません。
>
> スキーマを分ければ簡単に言えばDBサーバーがもう一つあるようなものなので、独立して設計・開発が行えます。
>
> 🔗[Yahoo!知恵袋 ベストアンサー](https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q12231322852) より

## まとめ
DBのスキーマ構造は、結局のところ所属組織でデータをどのように扱うか、ビジネスがどういう方向に向かっていく予定であるのかという点に依拠する気がします。

個人開発・小規模システムだと大規模データの扱いをあまり考慮せずともシステムが成り立つのかもしれませんが、先々のシステムの展望とデータの展開を見据えてスキーマ構造を作成しておくと、より構造化されてわかりやすいデータベースを管理することができるように思います。

データベースはシステムで使用するデータを保持しておく媒体にすぎませんが、その媒体を使用したり覗いたりするのは私たち人間であり、人間にとってもわかりやすい構造をしている、というのは、ストレスの少ない開発に一役買ってくれるのではないでしょうか。

<br>

**余談**
アドカレを書きながら、実は自分は結構DBってやつのことが人より好きなんじゃないかと気が付きました。つくづくたのしいという発見。


## 🔗参考Link

https://qiita.com/kenogi/items/31e027eeaddd0002f6e8

https://iret.media/1112

<br>

「データベースの講義ノート」というサイトがあった。やけにしっかりしているので何かと思ったら、大学の教授が講義用に作成されたサイトでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2632896/3e5baa2d-39ce-b274-79f4-3d8da1f2e63b.png)

https://dbnote.hontolab.org/index.html

<br>