データベーススペシャリスト掲示板


[0284] H29午前2問11

 nashさん(No.1) 
はじめまして。長文失礼します。
表題の問題の解答がウになるのは分かるのですが、問題文のSQLで、メモリカードidにnot nullが入っているのが気になります。
1.メモリカードidにnot nul制約をつける問題上の必然性、あるいは実装上のメリットがあるのでしょうか…?

2.もしかすると取り付けテーブルとメモリカードテーブルのリレーションがよく分かっていないかもしれません。リレーションが0…1 vs 1であることと、取り付けテーブルのメモリカードidにnot nullがあることは互いに矛盾しないと思っていますが正しいでしょうか?

3.not nullがあると、取り付けテーブルにレコードのある{PCID, スロット番号}の組には必ずメモリーカードが刺さっている必要があると思います。
つまりメモリーカードが抜かれたときは、その{PCID, スロット番号}のレコードを消すことになると思います。
それだと空のスロットを探すのに苦労しませんか?
2022.07.05 06:23
にゃんちゃんさん(No.2) 
問題文から分かる範囲の憶測ですが・・・

■取付けテーブルのテーブル定義
目的:各PCの使用スロットのみを管理
※空のスロットは管理していない。
※スロットが2つのPCのみを管理している。

PCID:PCを特定するキー
スロット番号:使用スロットを特定する番号(1or2)
メモリカードID:スロットにささっているメモリID
※使用しているスロットだけ管理するので非NULL

■回答
1.メモリカードidにnot nul制約をつける問題上の必然性、あるいは実装上のメリットがあるのでしょうか…?
使用スロットのみを管理するテーブルの仕様については是非があるかもしれません。
ただ、このテーブルを是とするなら、非NULL制約をつけるのは自然かと思います。
A. 使用スロットのみを管理するテーブルだから、例外が入り込まないようにするためです。

2.もしかすると取り付けテーブルとメモリカードテーブルのリレーションがよく分かっていないかもしれません。リレーションが0…1 vs 1であることと、取り付けテーブルのメモリカードidにnot nullがあることは互いに矛盾しないと思っていますが正しいでしょうか?
A. ご認識の通り、矛盾は生じません。
メモリカードIDがNULLのレコード(空のスロット)さえ入らなければ違反になりません。

3.not nullがあると、取り付けテーブルにレコードのある{PCID, スロット番号}の組には必ずメモリーカードが刺さっている必要があると思います。
つまりメモリーカードが抜かれたときは、その{PCID, スロット番号}のレコードを消すことになると思います。
それだと空のスロットを探すのに苦労しませんか?
A. PCテーブルに登録している全PCの空のスロットを探す場合
以下のような方針でSQL文を書けばいいかと思います(ベストプラクティスかどうかは別)。
@PCテーブル×値(1,2)で直積(全PCのスロットリスト)
A上記@に対して、取付けテーブルを左外部結合
B上記Aに対して、メモリカードIDがNULLを選択

もし別のテーブル設計をするなら
全PCの全スロットリストの使用状況を管理するテーブルを作ることになると思いますが
空きスロットをすぐ探せる(第3正規形にしていないため結合が不要)というメリットもあり
レコード数が多く冗長になる、テーブルの更新に時間がかかるというデメリットもあります。
管理するPC台数であったり、どういう用途なのかだったりで設計は変わるかと思います。
2022.07.06 01:03
 nashさん(No.3) 
こんな本質的でない質問に回答頂きありがとうございました。
1, 2については得心しました。
「自分ならこうする」という自身の設計思想を回答に持ち込んでしまいがちで、それが出題側と異なるとなぜそうなっているのかが気になって先に進めなくなってしまうんですよね。
3については、私も似たようなことを考えたのですが、各PCのもつスロット数がいくつか分からない(1 vs 0…2)ため、単純に直積をしてもだめかと思いました(スロットを持たないPCでも空のスロットが見つかる。)その点、にゃんちゃんさんの但し書き(※スロットが2つのPCのみを管理している。)は読み違いでしょうか…?
PCテーブルに各PCのスロット数を保持することを考えたのですが、上手く全PCのスロットリストを得られなさそうだったので質問した次第です。
2022.07.06 06:15
 nashさん(No.4) 
この投稿は投稿者により削除されました。(2022.07.06 06:19)
2022.07.06 06:19
 nashさん(No.5) 
…書いている間に思いついたのですが、
1.PCテーブルに各PCのスロット数を持たせる
2.PCテーブルと値1, 2を直積
3.直積の結果とPCテーブルで以下のような相関副問合せをし、各PCの保有スロット数以下のスロットidだけを抽出する
(PC.PCID = 直積結果.PCID AND PC.スロット数 >= 直積結果.スロットID)でWHERE EXISTS。 SQLっぽい内容が含まれていると投稿できないようなのでこのように書き換えています)
このようにすれば全PCのスロット一覧が得られ、その後回答頂いたようにAとBの操作をすれば空のスロットが見つかりそうですね(?)
なんだか自分のメモのように使ってしまい申し訳ないです…
2022.07.06 06:21
にゃんちゃんさん(No.6) 
問題文に
「1台のPCは、スロット番号で識別されるメモリカードスロットを二つ備える」
とあります。

よって、直積により以下の一時テーブルを作った次第です。

PCID スロット番号
A1001 1
A1001 2
A1002 1
A1002 2
A1003 1
A1003 2


ここに取付けテーブルを左外部結合すれば

PCID スロット番号 メモリカードID
A1001 1 M1001
A1001 2 M1002
A1002 1 M1003
A1002 2 null
A1003 1 null
A1003 2 null


このようになります。
上記の例だと
A1001はスロットいっぱい
A1002は空きスロットがひとつ
A1003は空きスロットがふたつ(修理中?)
となります。

各PCがスロットを1つしか持たない、3つ持っているなどが混在する場合はご記載のクエリを使うことになると思います。
今回は問題文から全PCのスロットがピッタリ2つと分かるので、1,2の直積でベースを作りました。
2022.07.06 08:13

【返信投稿用フォーム】

お名前(10文字以内)

顔アイコン


本文(2,000文字以内)

投稿削除用のパスワード(20文字以内)

プレビュー
※宣伝や迷惑行為を防止するため、当サイトとIPAサイト以外のURLを含む文章の投稿は禁止されています。

投稿記事削除用フォーム

投稿No. パスワード 
© 2016-2022 データベーススペシャリストドットコム All Rights Reserved.

Pagetop