Kōhei Yamamoto (山本 浩平)

My web site

View My GitHub Profile

『リレーショナルデータベース入門[新訂版]−データモデル・SQL・管理システム−』読書メモ

第1章 データベースとは何か

演習問題 解答

問題1

概念モデル
論理モデル

問題2

ネットワークモデル
ハイアラキカルモデル
リレーショナルモデル
オブジェクト指向

問題3

店舗 (shops)、顧客 (customer)、商品 (products)、注文 (orders) を例として考える。

(問1)

3項関連型を用いた実体−関連図。* 付きの属性が主キーである。

                                  (payment)
                                    |
(*email, address)-[customers] -L- <orders> -M- [products]-(*sku, price)
                                    |
                                    N
                                    |
                                  [shops]-(*shop_name, address)
(問2)
(問3)

リレーショナルデータベーススキーマ

(問4)

次の理由から第6正規形になっている。

問題4

ID関連型をリレーショナルデータベーススキーマへ変換する方法
ISA関連をリレーショナルデータベーススキーマへ変換する方法

問題5

ファイル管理
データベース管理

問題6

店舗の運営で生じるデータ(原価、売上、データの生成日時など)を例として考える。

データは仕入や販売を通じて生まれた数値の羅列である。そこから、どの時間にいくら利益が生じているかを見出すことで、どの時間にどの商品が売れやすい、という知識を増やすことができる情報を得られる。

第2章 リレーショナルデータモデル

演習問題 解答

問題1

候補キーはタップルを一意に識別できる属性の極小な組であり、あるリレーションに少なくとも1個以上存在する。一方、主キーは候補キーの中からもっとも意味があると設計者が考えて選んだキーであり、キー制約(一意性制約、非NULL制約)を課す。

キー制約はある主キーの値集合が必ず存在し(非NULL制約)、一意に識別できること(一意性制約)を保証する制約。外部キー制約はあるリレーションのある属性と同じ値の属性を持つタップルが別リレーションの主キーに必ず存在することを保証する制約。

問題2

まず、リレーションとは「ドメインの直積の部分集合」であることから、各タップルは必ず異なる属性値の組となる。このとき、全属性のうち一部からなる組が候補キーにならない場合でも、全属性からなる組は必ずそのタップルを一意に特定できる候補キーとなるので、リレーションスキーマに候補キーが存在しないことはない。

問題3

「配送」を表す次のリレーションスキーマは全属性の組が候補キー、すなわち主キーとなる:

配送 (配送業者, 配送先, 受取人名, 日時, 商品)

理由はほぼ自明だが、配送先だけでは複数人がその配送先に居住している可能性があるので、受取人名もキーとする必要がある点に注意。

問題4

空集合への SUM, AVG の適用時に現れるNULLは値が0であることを意味している。

問題5

第1章演習問題3(問3)の解答から少し変えている。

CREATE SCHEMA 店舗販売;
CREATE DOMAIN SKU型 NCHAR(10);
CREATE TABLE 店舗 (
  店舗名 NCHAR VARYING (50) NOT NULL,
  住所 NCHAR VARYING (100) NOT NULL,
  PRIMARY KEY (店舗名)
)
CREATE TABLE 商品 (
  SKU SKU型 NOT NULL,
  値段 INTEGER NOT NULL,
  在庫 INTEGER NOT NULL,
  PRIMARY KEY (SKU)
)
CREATE TABLE 顧客 (
  メールアドレス NCHAR(256) NOT NULL,
  住所 NCHAR(256) NOT NULL,
  PRIMARY KEY (メールアドレス)
)
CREATE TABLE 注文 (
  店舗名 NCHAR VARYING (50) NOT NULL,
  SKU SKU型 NOT NULL,
  メールアドレス NCHAR(256) NOT NULL,
  決済方法 NCHAR(50) NOT NULL,
  総額 INTEGER NOT NULL,
  購入日時 DATETIME NOT NULL,
  PRIMARY KEY (店舗名, SKU, メールアドレス, 購入日時),
  FOREIGN KEY (店舗名) REFERENCES 店舗(店舗名),
  FOREIGN KEY (SKU) REFERENCES 商品(SKU),
  FOREIGN KEY (メールアドレス) REFERENCES 顧客(メールアドレス)
)

問題6

(問1)

問題5のスキーマにおいて、次の一貫性制約は検査制約によって定義できる。

SQL-92を使った定義を次に示す。

CREATE TABLE 商品 (
  SKU SKU型 NOT NULL,
  値段 INTEGER NOT NULL,
  在庫 INTEGER NOT NULL,
  PRIMARY KEY (SKU),
  CHECK (値段 ≧ 0);
);
CREATE TABLE 注文 (
  // ...
  決済方法 NCHAR(50) NOT NULL,
  // ...
  CHECK (決済方法 IN ('クレジットカード', '銀行振込', '代金引換'));
);
(問2)

問題5のスキーマにおいて、注文総額 が注文した個々の商品の金額の総和に一致している、という一貫性制約は表明によって定義できる。

(問3)

注文 にタップルが挿入されたときに対応する 商品 のタップルの 在庫 が減少する、という一貫性制約はトリガによって定義できる。SQL-92を使った定義を次に示す。

CREATE TRIGGER 在庫引当
  AFTER INSERT ON 注文
    UPDATE 商品
      SET 在庫 = 在庫 - 1
      WHERE 商品.SKU = 注文.SKU;

問題7

第3章 データ操作言語とリレーショナル代数

演習問題 解答

問題1

リレーショナル代数表現とリレーショナル論理表現の両方で表すことを指示されているが、面倒なのでリレーショナル代数表現のほうだけ書く。

以降では

とする。

(問1)
(問2)
(問3)
(問4)
(問5)
(問6)
(問7)
(問8)
(問9)
(問10)

問題2

(問1)
(問2)

ステレオを生産している工場を表すリレーションを \(R = (((\text{製品} \times \text{工場})[\text{製品}.\text{製品名} = \text{“ステレオ”}])\) とすると

(問3)

\(S = (\text{製品} \times \text{工場}) \times \text{在庫}\) とすると

問題3

(問1)

ある属性の値が不明であったり、適切な値が存在しない場合に、そのことを表すための値が必要だから。

(問2)

あるリレーションを \(R = (A_{1}, A_{2}, …, A_{n})\) とするとき、Rの属性 \(A_{i}\), \(A_{j}\) 上の \(\theta\)-選択 \(R[A_{i} \theta A_{j}]\) は次のリレーションである。

\(A_{i} \theta A_{j}\) は \(A_{i}\) と \(A_{j}\) が \(\theta\) という関係にあることを表し、このリレーションはその条件に当てはまるタップルだけをリレーション \(R\) から抽出したものとなっている。

ここで、リレーションの属性値が空値をとるとき、条件 \(A_{i} \theta A_{j}\) の真偽が定まらなくなる。この場合、その条件の値を不定とする3値論理を導入することで、空値を含むリレーションに対して推量 \(\theta\)-選択を上述した \(\theta\)-選択(こちらを真正 \(\theta\)-選択と呼ぶ)とは別に導入できるようになる。推量 \(\theta\)-選択は次のリレーションである。

ある条件の値が不定の場合、\( \text{UNKNOWN}\) であると見なされる。

第7章 ファイルのアクセス法と編成法

演習問題 解答

問題1, 2, 5は略

問題3

図7.13(f)のB+木にレコード \((6, \text{渡辺})\) と \((11, \text{小林})\) を挿入するときの変化の過程を説明する。初期状態のB+木は次のとおり。

初期状態のB+木

葉ノードにつながるレコードは省略している。

\((6, \text{渡辺})\) は左端葉ノードに入るべきレコードである。このノードは空きがないので、ノードを次の形に分割する。

分割したノード

元の葉ノードの最大値を親ノードに入れる。ここでは \(6\) である。

レコード (6, 渡辺) を挿入したB+木

これで \((6, \text{渡辺})\) の挿入が完了した。次に \((11, \text{小林})\) を挿入する。これは右から二番目の葉ノードに入るべきレコードであり、ノードに空きがあるのでそのまま入れる。

レコード (11, 小林) を挿入したB+木

問題4

次のような形のB+木となり、逆順にレコードを挿入することでB+木の構造は変わる。木の構造が変わる理由としては、分割処理は前半の \( \lceil p/2 \rceil \) 個(\(p\) はB+木のオーダー)を元の葉ノードとするので、同じレコード群でも挿入順によって元の葉ノードに残るレコードが変わることが挙げられる。

図7.13(f)と逆の順でレコードを挿入したときのB+木

問題6

ハッシュ関数 \(h(k) = k \bmod 2\) でレコードを格納すると次のようになる。

B0

B1

社員レコード取得時のブロックの平均探索回数は次のとおり。