コマンド道場
正規化難易度 ★★★☆☆

商品を別の表に切り出す

juchu_nama は主キーが (juchu_id, shohin_id) ですが、shohin_mei と tanka は shohin_id だけで決まってしまい、同じ値が何度も入っています。これを 2 つの表に分けてください。shohin は shohin_id が整数で主キー、shohin_mei が text で NULL を許さない、tanka が numeric(10,0) で NULL を許さない、の 3 列。juchu は juchu_id が整数、shohin_id が整数で shohin を参照する外部キー、suryo が整数で NULL を許さない、の 3 列で、(juchu_id, shohin_id) を主キーにします。どちらも列はこの順です。juchu_nama の中身を、重複なく両方の表へ移してください。

この書き方が使えない製品があります そのまま使える: PostgreSQL / MySQL / MariaDB / SQLite / SQL Server

  • Oracle Database では使えませんtext 型の列 / この問題のほかの構文は未確認です

未確認: IBM Db2

製品ごとの対応表(根拠つき)を見る

  • Oracle Database には text 型がありません。shohin_mei は VARCHAR2 や CLOB に読み替えてください(公式のデータ型の一覧で確認)。
● 起動中…

この問題で使えるテーブル(名前をタップすると入力できます)

8

NULL
🔑int不可
🔑int不可
text不可
numeric(10,0)不可
int不可
データを見る(先頭 5 行)
juchu_idshohin_idshohin_meitankasuryo
110pen1203
111note2002
210pen1205
212eraser801
311note2004

6

NULL
🔑int不可
text不可
int不可
text不可
データを見る(先頭 5 行)
kaiin_idkaiin_meipref_codepref_mei
1sato13tokyo
2suzuki27osaka
3takahashi13tokyo
4tanaka23aichi
5ito27osaka

解説

結論

主キーの一部だけで決まる列は、別の表に切り出します。

★何が問題だったのか

juchu_nama では 'pen' という商品名が 3 行に書かれていました。商品名を直すには 3 行とも直さなければならず、1 行でも直し忘れると食い違います。単価も同じです。切り出した後は、商品の表を 1 行直すだけで済みます。

★重複を落とす必要があるのはなぜか: 元の表には同じ商品が何度も出てきます。そのまま入れると商品の表に同じ商品が並び、主キーが重複してエラーになります。DISTINCT で 1 行にまとめてから入れます。

★外部キーまで付けて完成です: 表を分けただけでは、受注の側に存在しない商品番号を書けてしまいます。分ける前は「同じ行に書いてあるから必ず一致する」ことが保証されていたので、分けたぶんの保証を外部キーで取り戻します。

⚠️ この問題では分解後の表名と列名を指定しています。分け方そのものは何通りもあり得るので、指定が無いと採点できないためです。実際の設計では、この「どう分けるか」が判断のしどころになります。

正規化 の使い方をはじめから読む

根拠(一次情報)