( 続き ) 理想は
CREATE TABLE t_分類マスタ
(
分類CD INT NOT NULL PRIMARY KEY
, 分類名 VARCHAR( 50 ) NOT NULL
);
分類CD | 分類名 |
---|---|
1 | AA |
2 | AB |
3 | AC |
4 | AD |
` sql | |
CREATE TABLE t_分類トラン | |
( |
入力ID COUNTER NOT NULL PRIMARY KEY
, 分類CD INT NOT NULL
, 分類別番号 INT
);
| 入力ID | 分類CD | 分類別番号 |
|-------:|-------:|-----------:|
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 2 | 2 |
| 4 | 1 | 2 |
| 5 | 1 | 3 |
| 6 | 3 | 1 |
| 7 | 2 | 3 |
| 8 | 1 | 4 |
| 9 | 2 | 4 |
| 10 | 2 | 5 |
SELECT y.入力ID
, y.分類CD
, y.分類別番号
, x.分類名 & Format$( y.分類別番号, '-00' ) As 分類
FROM t_分類マスタ x
INNER JOIN t_分類トラン y
ON x.分類CD = y.分類CD
ORDER BY 1 ;
| 入力ID | 分類CD | 分類別番号 | 分類 |
|--------|--------|------------|-------|
| 1 | 1 | 1 | AA-01 |
| 2 | 2 | 1 | AB-01 |
| 3 | 2 | 2 | AB-02 |
| 4 | 1 | 2 | AA-02 |
| 5 | 1 | 3 | AA-03 |
| 6 | 3 | 1 | AC-01 |
| 7 | 2 | 3 | AB-03 |
| 8 | 1 | 4 | AA-04 |
| 9 | 2 | 4 | AB-04 |
| 10 | 2 | 5 | AB-05 |
通報 ...
mayuさんに質問なんですが、なぜ
分類CD
がPRIMARY KEY
なんでしょう?文字に対して番号を割り当てるなら
分類名
側をPRIMARY KEY
としたほうがそれっぽいと思うのですがhirotonさん、ご質問ありがとうございます。
分類CDをPRIMARY KEYとする理由を3つほど述べますね。
[理由1.]
PRIMARY KEY はソートに利用することが多いから、です。
文字列ですと、全行パディングされていない限りソートが難しくなります。
また、列数が2つのテーブルに
PRIMARY KEY と INDEX 両方を付与するのは
DBの容量増加、UPSERTの遅延、INDEX破損率の上昇
といったリスクを抱えることになりますので
列数の少ないマスタテーブルでは、設計上の理由から回避したいです。
( 経験則上、テーブルの破損 = INDEXの破損 が圧倒的に多いです )
[理由2.]
( あくまで可能性として )分類の再編が発生して
サロゲートキーを利用する一因として
理由2.のように、主キーの体系が変化した場合などの影響が
ナチュラルキーに比べて( サロゲートキーのほうが )少なくなります。
んー、質問の内容に対応する場合と、新規で構築する場合とで話も変わってくるとは思うんですが>> 3の段階の話だと
こういう登録が許容されるテーブルを使うのはどうかと思うんですよね
改めて構築するということだと分類CDがどこまでサロゲートキーとして有効かというのもあって、可能性の話なら
もあり得るんじゃないでしょうか。質問上だと、「フラグ」というカラムにしたいということなので
この形でサロゲートキーな分類CDを使うならわかるんだけどという感じです
分類名の重複は、データの登録前後ともに、集計クエリ・DCountのような定義域集計関数で
誤りをチェックできるため、設計上問題ないという見解です。
私とhirotonさんで質問文の解釈に違いがありそうです。
mabeeさんは、( おそらく )便宜上「フラグ」と表現されましたけど
通常、フラグという言葉は、立つ・折るという
二者択一に近い条件分岐や選択で用いられます。
分類を文字列だけでなく、数値でも表現したい とご希望なのは
並び替えの基準となる「識別子」が必要とお考えになったのではないか
と推測しました。
したがって、私は{ フラグ = 識別子 }と解釈し、識別子を主キーとしています。
( 分類CD, 分類名, フラグ の3列構成にしない理由にもなっています )
また、余談にはなりますけど
分類をキーとした場合は、差別化を図るかどうかは別として
AA, Aa, aA, aa AA それぞれを異なる値として扱えません。
( バイナリ比較が必要になり、カラムも GUI では作成不可 )
( 差別化を図る場合は>> 3の回答自体が無効という盛大なブーメランですね )
数値型フィールドを識別子とすれば、全角半角大文字小文字を
同一の値で扱うことも差別化も容易で、高度なスキルも必要ありません。
常時バイナリ比較になり、経験の浅いDBAでも扱いが容易なことから
値の識別となる大小比較や結合・並び替えは、できる限り文字列より数値で実施するべき
というのが私のポリシーですので
>> 3でのSELECT文も、苦肉の策に近く、ベストプラクティスではない
というのが本音にはなりますね。