リレーショナルデータベース入門/リレーション・候補キー・主キーの定義

## 初めに
この記事は「[リレーショナルデータベース入門 第３版](https://www.amazon.co.jp/%E3%83%AA%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%AB%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E5%85%A5%E9%96%80%E2%80%95%E3%83%87%E3%83%BC%E3%82%BF%E3%83%A2%E3%83%87%E3%83%AB%E3%83%BBSQL%E3%83%BB%E7%AE%A1%E7%90%86%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%83%BBNoSQL-Information-Computing-%E5%A2%97%E6%B0%B8-%E8%89%AF%E6%96%87/dp/4781913903)」の第２章の一部をまとめたものです。
リレーションの例などは[徹底攻略 データベーススペシャリスト教科書 令和4年度](https://www.amazon.co.jp/dp/4295013587/ref=sspa_dk_detail_0?psc=1p13NParams&spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUEyQVFINlBBRFVCSEVCJmVuY3J5cHRlZElkPUEwNzc1NTI4NkpLSkJFVUM0SktWJmVuY3J5cHRlZEFkSWQ9QTNLOVBEMEEwOE5UREYmd2lkZ2V0TmFtZT1zcF9kZXRhaWwyJmFjdGlvbj1jbGlja1JlZGlyZWN0JmRvTm90TG9nQ2xpY2s9dHJ1ZQ==)で用いられている具体例を参考にしています。


## ドメインとリレーション
**ドメイン**とは集合（＝異なる元の集まり）である。
例えば人名の集合、年齢の集合、整数の集合といったものもドメインである。
ドメインは一般にDで表すことにする。例えば以下のようなものがドメインである。
```math 
D_{1} = \{x | xは人名\}, D_{2} = \{1,2,3,4,5\}, 
```
n個のドメインD1,...,Dnの直積は次のようなものである
```math 
D_{1}×\ldots　×D_{n}　＝　\{(x_{1} \ldots x_{n}) | x_i \in D_{i} (i=1...n)\}
```
つまり各ドメインの全ての組み合わせを直積と言う
この直積集合の各要素を**タプル**という。


### 定義（リレーション）
```math
D_{1}\ldots　D_{n}をドメインとする。\\
D_{1}\ldots　D_{n}の上のリレーションRとは、\\
直積D_{1}×\ldots　×D_{n}の任意の部分集合のことを言う
```
ここでRのタプルの総数のことを**濃度**と言う。また、Rを構成するドメインの数のことを**次数**という。次数rのリレーションのことを**r項リレーション**という。
リレーションは表として表現することができる。例えばD1={a,b,c},D2={10,20}としてR＝{(a,10),(b,20),(c,10)}とすれば、以下のように表現できる。

| a |  10 | 
| -------- | -------- | 
| b     | 20     | 
| c |10  |

表の横の並びを**行**、縦の並びを**列**という。
この表のままでは、初めて参照した人が何の表なのか理解することができない。
そこで列の名前である**属性名**と表の名前である**リレーション名**を与えると、以下のようにわかりやすくなる

兄弟
| 名前 |  年齢 | 
| -------- | -------- | 
|a     | 10     | 
| b |20  |
| c |10  |

属性名を用いて新たにリレーションを定義する。
ドメインD1...Dnの上のリレーションRの属性名をA1...Anとし、
ドメイン関数dom: {A1,..,An} → {D1,..,Dn}をdom(Ai)=Diと定義すると、
リレーションRはdom(A1)×...×dom(An)の任意の部分集合であると定義できる。

リレーションには新しいタプルが挿入・更新されたり削除されたりする。
つまり、タプルの値は変化していくものである。一方で属性やリレーション名は不変のものである。
そこで時間的に不変なリレーションの枠組みのことを**リレーションスキーマ**として規定する。リレーション名R、属性名A1...Anを用いてリレーションスキーマのことをR (A1...An)で表す。この時、dom(A1)×...×dom(An)の部分集合のことをリレーションスキーマRの**インスタンス**、単に**リレーション**といったりする。（リレーションスキーマは時間tに対して変化するリレーションRtの集合みたいなイメージ）

## 候補キーと主キー
リレーションRに対し、Ωで全属性集合{A1....An}を表す。
また、t={a1...an}をリレーションRのタプルとするとき、aiを「tのAi値」といい、t[Ai] とかく。
より一般に、複数の属性X = {Ai_1....Ai_k}の場合は{ai_1...ai_k}を「tのX値」といい、t[X]とかく。

この書き方を理解するために以下の具体例であるリレーションRを用いる。

#### 具体例：リレーション R「伝票」

| 伝票番号| 顧客名　　  | 顧客番号 | 商品番号 | 商品名　　 |　数量  |
| -------- | -------- | -------- |-------- | -------- | -------- |
| 1001   | ねこ商事   | 11      | 2001    | チョコ    |  5    |
| 1001   | ねこ商事   | 11      | 2002    | キャラメル |  10   |
| 1002   | うさぎ開発  | 13      | 2001    | チョコ    |  7    |
| 1002   | うさぎ開発  | 13      | 2003    | ドーナツ  |  20    |
| 1002   | うさぎ開発  | 13      | 2004    | アメ   　 |  8    |
| 1003   | くま工業   | 29      | 2005    | ちんすこう |  30    |
| 1004   | くま工業   | 29      | 2005    | ちんすこう |  100   |

この場合、
A1,A2,A3,A4,A5,A6はそれぞれ伝票番号,顧客名,顧客番号,商品番号,商品名,数量であり、
全属性集合Ωは{伝票番号,顧客名,顧客番号,商品番号,商品名,数量}である。
タプルtを{1002,うさぎ開発,13,2001,チョコ,7}とすると、t[A2]=うさぎ開発である。
また、X＝{商品番号,商品名,数量}という全属性集合Ωの部分集合とすると、t[X]={2001,チョコ,7}である。

さてこの表記をもとに、各種キーの定義をする。

### 定義（候補キー）
```math
リレーションスキーマ\textit Rの属性集合Kが候補キーであるとは、　\\
\textit Rの任意のインスタンスRに対して、以下が成り立つことである\\
1.\quad \forall t,s \in R \quad t[K]=s[K] \Rightarrow　t=s \\
2.\quad Kの全ての真部分集合Hに対して1.が成立しない。
```
つまり、候補キーに当たる属性の値が一致すれば、行の値全てが一致する（一意に決まる）ということである。さらにその属性の組み合わせが極小になっている（それ以上分解しても行を一意に決定するキーになり得ないと言うこと）。
なお、１の条件のみを満たす属性集合KはRの**スーパキー**という。

先の具体例で言うと、候補キーKは{伝票番号,商品番号}、{伝票番号, 商品名}が該当する。
実際、任意のタプルt,sに対して、それらの値t[K],s[K]が一致すれば、タプルt,sは必ず同じ行にしかなり得ない（例えばK＝{伝票番号,商品番号}とした時、Kの値を(1001,2002)にしても(1004,2005)にしても何にしても、行が必ず一意に定まる）。


さて、**主キー**を候補キーから一つ選ぶ（意味的に最も大事なものを選ぶ）。主キーは次のキー制約を満たす必要がある（逆に言えば、主キーは次のキー制約を満たす候補キーである必要があると言える）
### 定義（キー制約）
```math
キー制約とは、リレーションスキーマ\textit Rの属性集合Kを候補キーとしたときに　\\
\textit Rの任意のインスタンスRに対して、以下が成り立つことである\\
1.\quad \forall t,s \in R \quad t[K]=s[K] \Rightarrow　t=s \\
2.\quad　\forall t\in R　　\forall A\in K \quad t[A]は-でない
```
すなわち、一意識別能力を持ち、かつNULLにならない条件のことをキー制約という。
（候補キーである時点で1.は満たしてるので、わざわざ書く必要がないと思うが、一応書いた。）

これらを定義を用いて、リレーショナル代数や正規化についてまとめていく。

## 参考
・[リレーショナルデータベース入門 第３版](https://www.amazon.co.jp/%E3%83%AA%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%AB%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E5%85%A5%E9%96%80%E2%80%95%E3%83%87%E3%83%BC%E3%82%BF%E3%83%A2%E3%83%87%E3%83%AB%E3%83%BBSQL%E3%83%BB%E7%AE%A1%E7%90%86%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%83%BBNoSQL-Information-Computing-%E5%A2%97%E6%B0%B8-%E8%89%AF%E6%96%87/dp/4781913903)
・[徹底攻略 データベーススペシャリスト教科書 令和4年度](https://www.amazon.co.jp/dp/4295013587/ref=sspa_dk_detail_0?psc=1p13NParams&spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUEyQVFINlBBRFVCSEVCJmVuY3J5cHRlZElkPUEwNzc1NTI4NkpLSkJFVUM0SktWJmVuY3J5cHRlZEFkSWQ9QTNLOVBEMEEwOE5UREYmd2lkZ2V0TmFtZT1zcF9kZXRhaWwyJmFjdGlvbj1jbGlja1JlZGlyZWN0JmRvTm90TG9nQ2xpY2s9dHJ1ZQ==)