2019年に「データベース:: 論理の使い所は」という記事を書きました。タイトルに「データベース::」という接頭辞を付けたのは、一連の記事を検索しやすくするためです。一連の記事とは、次の意図で書かれる“はずだった”記事です。
ちゃんと書こうと思うと億劫になるので、ふと思い立ったときに、データベースと論理に関するラフなメモ書きを残すことにします。
ところが、接頭辞「データベース::」が付いた記事は2019年の記事一本だけ。続きはありませんでした。
最近(2023年6月)、「カーディナリティ〈多重度〉の“カラスの足”記法が分からない」という記事を書きました。この記事を書いた後で、「データベースに関連する記事になんか接頭辞を付ける気でいたような?」と思い出しました。“カラスの足”記事のタイトルを変える気はありませんが、この記事には接頭辞「データベース::」を付けました。4年ぶりの2本目の記事となります。
この記事の話題は、よく知られた“テーブルのキー”についてです。「よく知られた」と書きましたが、それほどよく知られてないんじゃないのかなぁ、という思いが記事を書いた動機です。$`\require{color}
\newcommand{\Keyword}[1]{ \textcolor{green}{\text{#1}} }
\newcommand{\For}{\Keyword{For }}
\newcommand{\Define}{\Keyword{Define }}
\newcommand{\Imp}{ \Rightarrow }
\newcommand{\mrm}[1]{\mathrm{#1}}
\newcommand{\hyp}{\text{-}}
\newcommand{\Iff}{\Leftrightarrow}
\newcommand{\Doms}{\mathscr{D}}
`$
内容:
シリーズ記事:
- データベース:: 論理の使い所は
- データベース:: テーブルのキーって何なのよ? (この記事)
- データベース:: テーブル構造とデータベース構造
- データベース:: 具体例の記述方法
- データベース:: テーブル間の参照
- データベース:: 記法と用語のまとめ
関連記事
- データベース・テーブルの変更を圏論的に見るならば
- 関係(非決定性写像)に関する用語
- (続き) 関係(非決定性写像)に関する記法
- テンソル計算(の準備)と型推論・エラボレーション
- カーディナリティ〈多重度〉の“カラスの足”記法が分からない
- 続報・カーディナリティ(多項関係、関係の属性も)
カラム、ドメイン、テーブルスキーマ
「データベース:: 論理の使い所は」にて:
数学における(標準的な)関係概念はきわめてクリアです。が、RDBの世界の「関係〈リレーション〉」はそれとは別の意味で使われています。ここでは、「関係」は数学の標準的な意味で使い、RDBジャーゴン(RDBコミュニティ特有の隠語)としての「関係」は「テーブル」と呼びます。
というわけで、「関係」「属性」は後で使うために温存しておき、「テーブル」「カラム」を使います。例えば、通常「関係スキーマ〈リレーションスキーマ〉」と呼ばれるものを「テーブルスキーマ」と呼びます。
カラムに関して、カラム名とカラム関数(後述)を区別します。カラム名とは何かというと、カラム名の集合の要素です。カラム名の集合は単なる有限集合です。
- カラム名の集合〈set of column names〉とは、(任意の)有限集合のこと。空集合も認めます。
- カラム名〈column name〉とは、カラム名の集合の要素のこと。
「これでは何も定義してないではないか」と思うでしょう、そのとおりです! カラム名が実体として何であるかは一切定義しません。「とある有限集合の要素」以上の意味はありません。
同様に、ドメインも実体として何であるかは定義しないで、呼び名だけ決めます。
- ドメインの集合〈set of domains〉とは、集合を要素とする有限集合のこと。
- ドメイン〈domain〉とは、ドメインの集合の要素のこと。
“ドメインの集合”が“集合の集合”なので、ドメインは集合です。ドメインの集合に属するドメイン(と呼ばれる集合)は、基本データ型〈primitive data-type〉だと思ってください。整数型、文字列型、真偽値型のような汎用・共通な基本データ型だけでなくて、特定の応用状況で使う基本データ型、例えば、身長型、年齢型、性別型、製品番号型、都道府県コード型とかでもいいです。
「ドメイン」という言葉は、他の意味でも使われていてコンフリクトするので、混乱を招きそうなときは「ドメイン〈ASPDT〉」と書くことにします。ASPDT は、Application Specific Primitive Data-Type のことです。Application Specific も Domain Specific としたかったのですが、さっそくに Domain がコンフリクトしました(苦笑)。
ドメイン〈ASPDT〉の集合(有限個の基本データ型の集まり)は前もって決められているとして、それを $`\Doms`$ とします。
テーブルスキーマ〈table schema〉とは、カラム名の集合 $`C`$ から、ドメイン〈ASPDT〉の集合 $`\Doms`$ への写像〈関数〉です。つまり、
$`\quad S : C \to \Doms`$ (写像)
$`C`$ は有限集合なので、$`C = \{c_1, \cdots, c_n \}`$ と書けます。$`S(c_i) = D_i`$ として、次のように書くことにします。
$`\quad S = (c_1 : D_1, \cdots, c_n: D_n )`$
特に、$`C`$ が番号の集合 $`C = \{1, \cdots, n \}`$ のときは、次のように略記します。
$`\quad S = (D_1, \cdots, D_n)`$
この場合、テーブルスキーマは単にドメイン〈APSTD〉のリストになります。同じドメインが何度も出現してもかまいません。
カラム名の集合が空集合のときも、テーブルスキーマはひとつ存在します。それは次のように書けます。
$`\quad S = ()`$ (ドメインの空リスト)
カラム名の集合が空集合である(唯一の)テーブルスキーマを空テーブルスキーマ〈empty table schema〉と呼びます。空テーブルスキーマは無意味なわけではなく、必要なものです。
個々のカラム名が何であるかは、今の文脈では重要ではないので、主に $`C = \{1, \cdots, n \}`$ のケースを考えます。具体例のときは、カラム名で現実的意味を示唆することが多いので、自然言語由来のカラム名を用います。例えば:
$`\quad S = (\text{姓}: {\bf String}, \text{名}: {\bf String}, \text{生年月日}: {\bf Date})`$
タプルとテーブルインスタンス
$`S:C \to \Doms`$ をテーブルスキーマとします。$`S`$ のタプルは、カラム名に値を割り当てる関数 $`t`$ のことです。ただし、次の条件を満たす必要があります。
- $`c\in C`$ に対して、$`t(c) \in S(c)`$ である。
習慣により、$`t(c)`$ は $`t_c`$ とも書かれます。$`C = \{1, \cdots, n\}`$ のときなら、$`t(i) = t_i`$ であり、$`t = (t_1, \cdots, t_n)`$ とお馴染みの形で書けます。
テーブルスキーマ $`S`$ のタプル全体からなる集合を $`\mrm{Tuple}(S)`$ とします。$`C = \{1, \cdots, n\}`$ で $`S = (D_1, \cdots, D_n)`$ のときは、次のように書けます。
$`\quad \mrm{Tuple}(S) \cong D_1 \times \cdots\times D_n`$
記号 '$`\cong`$' は集合の同型の意味ですが、左右を同一視してイコールだと思ってもかまいません。
シグマ型とパイ型を知っているなら、$`\mrm{Tuple}(S)`$ は次のように記述できます。
$`\quad \mrm{Tuple}(S) := \prod_{c\in C} S(c)\\
= \mrm{Sect}(\pi : \sum_{c\in C} S(c) \to C)
`$
ここで、$`\pi`$ はシグマ型にともなう射影で、$`\mrm{Sect}(\hyp)`$ は射影のセクションの集合を表します。次のように書けます。
$`\quad t \in \mrm{Tuple}(S)\\
\Iff t \in \mrm{Map}(C, \sum_{c\in C} S(c)) \land \pi\circ t = \mrm{id}_C`$
[/補足]
テーブルスキーマ $`S`$ のタプルを関数とみなした場合の余域〈codomain〉は $`\bigcup S`$ と書くことにします。$`S = (D_1, \cdots, D_n)`$ のときなら、次のように書けます。
$`\quad \bigcup S \\
= \bigcup (D_1, \cdots, D_n)\\
= D_1\cup \cdots\cup D_n
`$
シグマ型を知っているなら、$`\bigcup S`$ の代わりにシグマ型 $`\sum S = \sum_{c\in C} S(c)`$ で考えてもいいです。
タプルの集合 $`\mrm{Tuple}(S)`$ の部分集合を、テーブルスキーマ $`S`$ のテーブルインスタンス〈table instance〉と呼びます。つまり、
$`\quad T \text{ は } S \text{ のテーブルインスタンス}\\
\Iff T \subseteq \mrm{Tuple}(S)
`$
テーブルスキーマ $`S`$ のすべてのテーブルインスタンスからなる集合は $`\mrm{Pow}(\mrm{Tuple}(S))`$ と書けます。ここで、$`\mrm{Pow}(\hyp)`$ はベキ集合〈powerset〉です。
カラム名の集合と射影関数
関係データベースにおいて、「キー」は重要な概念だと思いますが、その「キー」に関してハッキリとした定義はされてないことが多いようです。とあるデータベース教材から超キー〈superkey〉の定義を引用します。
与えられたテーブルスキーマ $`S`$ のいかなるテーブルインスタンスにおいても、二つ以上のタプルが同一とならないようなカラム名の集合
「二つ以上のタプルが同一とならない」の意味がちょっと分かりにくいので、ハッキリさせましょう。
カラム名の集合 $`C`$ の部分集合を $`X, Y`$ などで表します。$`X\subseteq C`$ があると、テーブルスキーマ $`S:C \to \Doms`$ を $`X`$ に制限できます。例えば、$`C = \{a, b, c\}, X = \{a, c\}`$ ならば、$`X`$ に制限された $`S`$ は次のように書けます。
$`\quad (a: S(a), c:S(c))`$
$`X`$ に制限された $`S`$ は $`S|_X`$ と書きます。
$`\quad S = (a:S(a), b:S(b), c:S(c))\\
\quad S|_X = (a: S(a), c:S(c))`$
$`S|_X`$ もテーブルスキーマなので、タプルの集合 $`\mrm{Tuple}(S|_X)`$ を考えることができます。$`\mrm{Tuple}(S)`$ の要素($`S`$ のタプル)から、$`\mrm{Tuple}(S|_X)`$ の要素($`S|_X`$ のタプル)を自然に作ることができます。それは、次のような写像〈関数〉があるということです。
$`\quad \pi_X : \mrm{Tuple}(S) \to \mrm{Tuple}(S|_X)`$
タプル $`t \in \mrm{Tuple}(S)`$ は、$`t:C \to \bigcup S`$ という関数でした。関数としての $`t`$ を $`X`$ に制限することができます。域が $`X`$ に制限された $`t`$ を $`\pi_X(t)`$ と書くのです。例えば、先の例で、$`t = (t_a, t_b, t_c)`$ が $`S`$ のタプルのとき $`\pi_X(t)`$ は $`(t_a, t_c)`$ です。この $`\pi_X`$ を、部分集合 $`X \subseteq C`$ が決める射影関数〈projection function〉と呼びます。
特に、$`c\in C`$ として、単元集合 $`\{c\}`$ が決める射影関数は次の形です。
$`\quad \pi_{ \{c\}} : \mrm{Tuple}(S) \to \mrm{Tuple}(S|_{\{c\}})`$
$`\mrm{Tuple}(S|_{\{c\}})`$ と $`S(c)`$ は標準的に〈canonically〉同型なので、次の図式を可換にする写像 $`\pi_c`$ が決まります。
$`\require{AMScd}
\begin{CD}
\mrm{Tuple}(S) @>{\pi_{ \{c\}}}>> \mrm{Tuple}(S|_{\{c\}}) \\
@| @VV{\cong}V\\
\mrm{Tuple}(S) @>{\pi_c }>> S(c)
\end{CD}
`$
こうして決まる写像 $`\pi_c : \mrm{Tuple}(S) \to S(c)`$ をカラム関数〈column function〉と呼ぶことにします。カラム関数は、タプルの特定成分の値(関数とみなしたタプルの、特定引数に対する戻り値)を取り出す関数です*1
$`\mrm{Tuple}(S|_X)`$ は頻繁に使うので、$`X`$ を(小さな下付きではなくて)大きくして $`\mrm{Tuple}(S, X)`$ とも書きます。$`\mrm{Tuple}(S) = \mrm{Tuple}(S, C)`$ です。
さて、先の「二つ以上のタプルが同一とならない」ですが、カラム名の集合の部分集合を $`X \subseteq C`$ として、
- 二つ以上のタプルの、射影関数 $`\pi_X`$ による値が同一とならない
の意味です。ここで、「二つ以上のタプル」は、テーブルインスタンス $`T`$ の要素だとします。つまり、
- テーブルインスタンス $`T`$ の要素である二つ以上のタプルの、射影関数 $`\pi_X`$ による値が同一とならない
これを論理式で表現すれば、次のようです。
$`\quad \lnot \exists t, t' \in T.\, t \ne t' \land \pi_X(t) = \pi_X(t')`$
日本語に逐語翻訳するなら:
$`t`$ と $`t'`$ は異なっていて ($`t \ne t'`$)
かつ ($`\land`$)
射影関数による値は同一 ($`\pi_X(t) = \pi_X(t')`$)
であるようなテーブルインスタンス $`T`$ の要素 $`t, t'`$ が存在する ($`\exists t, t' \in T.`$)
ことはない ($`\lnot`$)
これで、「二つ以上のタプルが同一とならない」の意味がハッキリしました。
$`S:C \to \Doms`$ がテーブルスキーマで、$`t\in \mrm{Tuple}(S)`$ が $`S`$ のタプルのとき、$`X \subseteq C`$ に対する射影 $`\pi_X`$ による値 $`\pi_X(t)`$ を $`t[X]`$ と書く習慣があるようです。値だけでなくて、テーブルインスタンス $`T\subseteq \mrm{Tuple}(S)`$ に対する像集合 $`\pi_X(T)`$ にも $`T[X]`$ という記法を使います。ブラケットを、次の2つの意味でオーバーロードしているわけです。
$`\quad (\hyp)[X] : \mrm{Tuple}(S, C) \to \mrm{Tuple}(S, X) \\
\quad (\hyp)[X] : \mrm{Pow}(\mrm{Tuple}(S, C)) \to \mrm{Pow}(\mrm{Tuple}(S, X))
`$
この記事内ではブラケット記法を使いませんが、データベース理論ではブラケット記法をよく見かけます。
[/補足]
自明なキー以外のキーは存在しない
超キーの定義を再掲します。
与えられたテーブルスキーマ $`S`$ のいかなるテーブルインスタンスにおいても、二つ以上のタプルが同一とならないようなカラム名の集合
$`S:C \to \Doms`$ が与えられたテーブルスキーマだとして、カラム名の集合 $`X \subseteq C`$ が超キーである条件は次のようです。
$`\quad \forall T \in \mrm{Pow}(\mrm{Tuple}(S)).\\
\qquad \lnot \exists t, t' \in T.\, t \ne t' \land \pi_X(t) = \pi_X(t')
`$
$`\forall T \in \mrm{Pow}(\mrm{Tuple}(S)).`$ が「いかなるテーブルインスタンスにおいても」に相当します。$`\forall T \in \mrm{Pow}(\mrm{Tuple}(S)).`$ を逐語翻訳するならば:
テーブルスキーマ $`S`$ のタプルの集合 ($`\mrm{Tuple}(S)`$)
の任意の ($`\forall`$) 部分集合 $`T`$ ($`T \in \mrm{Pow}(\mrm{Tuple}(S))`$)
に対して
$`X = C`$ ならばこの条件は満たされます。つまり、カラム名の集合 $`C`$ はテーブルスキーマ $`S`$ の超キーです。この場合は当たり前なので、$`C`$ を自明な超キー〈trivial superkey〉と呼びます。
では、自明でない超キーは存在するでしょうか? 超キーの定義を文字通りに受け取ると、自明でない超キーは存在しません。
テーブルスキーマ $`S:C \to \Doms`$ に次の仮定を設けます。この仮定が特殊な条件だと思う人はいないでしょう。
- カラム名の集合 $`C`$ は空集合ではない。
- 任意のカラム名 $`c\in C`$ に対して、ドメイン〈ASPDT〉$`S(c)`$ は2個以上の要素を持つ。
この仮定のもとで、部分集合 $`X\subseteq C`$ が $`X \ne C`$ ならば、超キーになれないことを示しましょう。
$`C \ne \emptyset \land X \ne C`$ なので、$`a\in C \land a \not\in X`$ であるカラム名 $`a`$ を取れます。仮定より $`S(a)`$ は2個以上の要素を持つので、異なる2つの要素〈値〉を $`v, v' \in S(a)`$ とします。
タプル $`s\in \mrm{Tuple}(S)`$ をひとつ選びます(何でもいいです)。$`s`$ から2つのタプル $`t, t'\in \mrm{Tuple}(S)`$ を次のように作ります。
- $`t_a = v`$ 、 $`a`$ 以外の $`c\in C`$ に対しては $`t_c = s_c`$
- $`t'_a = v'`$ 、 $`a`$ 以外の $`c\in C`$ に対しては $`t'_c = s_c`$
こうして作った $`t, t'`$ は次の条件を満たします。
- $`t \ne t'`$ (カラム名 $`a`$ での値 $`v, v'`$ が違うから)
- $`\pi_X(t) = \pi_X(t')`$ ($`a`$ 以外のカラム名での値は同じだから)
テーブルインスタンス $`T \subseteq \mrm{Tuple}(S)`$ を次のように定義します。
$`\quad T := \{t, t'\}`$
この $`T`$ については、次の命題が成立します*2。
$`\quad \exists t, t' \in T.\, t \ne t' \land \pi_X(t) = \pi_X(t')`$
よって、$`X`$ は超キーの条件を満たしません。$`X \ne C`$ であるかぎり、超キーにはなれないのです。
非自明な超キーが存在しないと、非自明な候補キー〈candidate key〉も存在しないし、非自明な主キー〈primary key〉も存在しません。
「そんなバカな」と思うでしょ。そう、なんかオカシイのです。超キーの定義がオカシイのですよ。
テーブルクラス
超キーの定義の「いかなるテーブルインスタンスにおいても」の「いかなる」が問題なのです。前節で、「いかなる」を $`\forall T \in \mrm{Pow}(\mrm{Tuple}(S)).`$ と解釈したのですが、そうではないのです。テーブルインスタンスの集合 $`\Gamma`$ が事前に決まっていて、$`\Gamma`$ に相対的に超キーが定義されるのです。
$`S:C \to \Doms`$ はテーブルスキーマとして、$`\Gamma \subseteq \mrm{Pow}(\mrm{Tuple}(S))`$ も与えられているとします。そのとき、$`X \subseteq C`$ が、$`\Gamma`$ に対して超キー〈superkey〉であるとは次のことです。
$`\quad \forall T \in \Gamma.\\
\qquad \lnot \exists t, t' \in T.\, t \ne t' \land \pi_X(t) = \pi_X(t')
`$
$`\Gamma \subseteq \mrm{Pow}(\mrm{Tuple}(S))`$ を、$`S`$ のテーブルクラス〈table class〉と呼ぶことにします。「クラス」という言葉も多用され過ぎてワケワカラナイのですが、「インスタンスの集まり」というなら「クラス」しかない気もします。
もう一度確認すると、超キーという概念は、テーブルスキーマに対して決まるのではなくて、テーブルスキーマのテーブルクラスを指定して初めて決まる概念です。テーブルクラスが不明だと、超キーかどうかの判断が出来ません。すべてのテーブルインスタンスからなるテーブルクラス(最大のテーブルクラス)に対しては、自明な超キーしか存在しません(前節の話)。
通常、テーブルクラス(に相当する概念)に言及されないのは、テーブルスキーマに付けられた自然言語由来の名前、例えば「社員」「製品」「学生」などから、対応するテーブルクラスを暗黙に連想させる方法が採られているからでしょう*3。しかし、暗黙の連想に頼ったコミュニケーションって碌なことにならないんだよね。
あらためてキーの定義
仕切り直しをしましょう。キー概念、つまり超キー、候補キー、主キーをちゃんと定義しましょう。
まず、ドメインの集合 $`\Doms`$ は決まっているとします。ドメイン設計は済んでいる、とも言えます。固定された $`\Doms`$ のもとでさらに $`C, S`$ を決めます。
- $`C`$ は、カラム名の集合である。有限集合なら何でもいい。
- $`S`$ は、$`S:C \to \Doms`$ という写像である。
- $`S`$ が決まれば、$`C`$ は“写像 $`S`$ の域〈domain〉” と位置づけられる。(「ドメイン〈domain〉」がまたコンフリクト。)
$`S`$ が決まると、$`S`$ のテーブルインスタンスという概念を定義できます。
- $`T`$ が $`S`$ のテーブルインスタンス ⇔ $`T\subseteq \mrm{Tuple}(S)`$
- 同じことだが、$`T\in \mrm{Pow}(\mrm{Tuple}(S))`$
そして、前節で述べたテーブルクラス $`\Gamma`$ を、暗黙でなくて明示的に決めます。
- $`\Gamma`$ はテーブルインスタンスの集合である。
- 同じことだが、$`\Gamma \subseteq \mrm{Pow}(\mrm{Tuple}(S))`$
- 同じことだが、$`\Gamma \in \mrm{Pow}( \mrm{Pow}(\mrm{Tuple}(S)) )`$
ここまでに出てきたすべての構成素〈constituent〉達を並べてまとめると:
$`\quad (\Doms, C, S, \Gamma)`$
これらで決まる構造をテーブル構造〈table structure〉と呼ぶことにしましょう。特定のテーブルクラス $`\Gamma`$ も含めるところがミソです。
$`\Doms`$ は文脈内に固定されているとして省略し、以下のような表現を使うことにします。
- カラム名の集合 $`C`$
- $`C`$ 上のテーブルスキーマ $`S`$
- テーブルスキーマ $`(C, S)`$
- テーブルスキーマ $`S`$ ($`C = \mrm{dom}(S)`$ として再現できるので、$`C`$ を省略している)
- $`(C, S)`$ 上のテーブルクラス $`\Gamma`$
- テーブル構造 $`(C, S, \Gamma)`$
キー概念はテーブル構造 $`(C, S, \Gamma)`$ に相対的に定義されます。「$`X`$ が、$`(C, S, \Gamma)`$ の超キーである」という意味の述語〈predicate〉を $`\text{isSuperkey}_{(C, S, \Gamma)}(X)`$ と書くことにします。この述語は次のように定義されます。
$`\For X \in \mrm{Pow}(C)\\
\Define \text{isSuperkey}_{(C, S, \Gamma)}(X) :\Iff \\
\quad \forall T \in \Gamma.\,
\lnot \exists t, t'\in T.\\
\qquad t \ne t' \land \pi_X(t) = \pi_X(t')
`$
定義のなかに否定($`\lnot`$)が出てくるのが嫌なら、次のように書き換えることができます*4。
$`\For X \in \mrm{Pow}(C)\\
\Define \text{isSuperkey}_{(C, S, \Gamma)}(X) :\Iff \\
\quad \forall T \in \Gamma.\,
\forall t, t'\in T.\\
\qquad \pi_X(t) = \pi_X(t') \Imp t = t'
`$
超キーが定義できれば、それを使って候補キー〈candidate key〉を定義できます。「$`X`$ が、$`(C, S, \Gamma)`$ の候補キーである」という意味の述語を $`\text{isCandidateKey}_{(C, S, \Gamma)}(X)`$ と書くことにして:
$`\For X \in \mrm{Pow}(C)\\
\Define \text{isCandidateKey}_{(C, S, \Gamma)}(X) :\Iff \\
\quad \text{isSuperkey}_{(C, S, \Gamma)}(X)\\
\quad \land\\
\quad \lnot \exists Y \in \mrm{Pow}(C).\,
Y \subseteq X \land Y \ne X \land \text{isSuperkey}_{(C, S, \Gamma)}(Y)
`$
主キー〈primary key〉は、候補キーの集合からひとつ選んだ特定の候補キー $`K \subseteq C`$ のことです。
主キーを特定したテーブル構造は $`(C, S, \Gamma, K)`$ と書けます。主キー $`K`$ は候補キーなので、次の条件を満たします。
$`\forall T \in \Gamma.\,
\forall t, t'\in T.\, \pi_K(t) = \pi_K(t') \Imp t = t'\\
\land\\
\lnot \exists Y \in \mrm{Pow}(C).\\
\quad Y \subseteq K \land Y \ne K \land\\
\quad \forall T \in \Gamma.\,\forall t, t'\in T.\, \pi_Y(t) = \pi_Y(t') \Imp t = t'
`$
「うひゃー、長い論理式だ」と思ったかも知れません。自然言語〈日本語〉で書くと、もっと長くなり、しかも曖昧です。上記の長めの論理式は、正確に短く書いた表現であり、きちんとした推論のベースとして頼りになります。
暗黙の連想を前提にしたり、曖昧で雰囲気的な自然言語でお茶を濁していては、それに基づく正確な議論は無理です。明示的に、述語論理に基づいた表現を使うのが得策だと思います。
この記事では、テーブル構造の「キー」という概念を定義しただけです。さらに続く話があれば、「データベース::」という接頭辞が付いたタイトルの記事になるでしょう(次の記事がいつになるか分からんけど)。
*1:カラム関数 $`\pi_a`$ は、評価関数 $`\mrm{eval}(\hyp, \hyp)`$ の第二引数を固定した $`\mrm{eval}(\hyp, a)`$ と同じです。特定成分の値を取り出すことは、特定引数を渡して評価することです。
*2:存在命題の束縛変数名が、構成した2つのタプル $`t, t'`$ と同じ名前になっています。これは普通のことですが、混乱したり違和感を感じるなら、束縛変数名をリネームすればいいでしょう。例えば、$`\exists x, x' \in T.\, x \ne x' \land \pi_X(x) = \pi_X(x')`$
*3:テーブルスキーマ〈関係スキーマ〉において、その名前が重要視されるのは、「テーブルクラスを連想しやすい名前にすべき」というモラルがあるからでしょう。
*4:ド・モルガンの法則(限量子に対する法則も含める)と、$`A \Imp B`$ が $`\lnot A \lor B`$ と同値であることを使います。