おれおれサブセット実装


サブセットを実装するとできなくなってしまうことに

  • unique制約
  • 外部キー制約

がある。

例えば、社員マスタを正社員とパート社員というサブセットに分割したとして、

正社員(R) = { 社員ID, 社員コード, 名前, ... }
パート社員(R) = { 社員ID, 社員コード, 名前, ... }

社員コードは全社員を通じてユニークである必要があったら、それをチェックするのが面倒になる。
サブセットの社員コードにそれぞれ unique 制約をつけても、「社員全体で一意」かどうかのチェックにならないから。

また、社員の扶養家族マスタというのがあったとして、

社員の扶養家族(MO) = { 社員ID, 続柄コード, 扶養家族名 }

このテーブルの社員IDには外部キー制約をつけることができない。

認知番号しかない「サブセット」を作ったらどうか

上記の問題を回避するために、スーパーセットはそのまま置いておいて、認知番号の列しかない「サブセット」をくっつけたらどうかと思ったのです。

社員マスタ(R) = { 社員ID, 社員コード, 名前, ... }
正社員 = { 社員ID }
パート社員 = { 社員ID }

で、正社員の情報一覧がほしいときはこうする:

select 社員マスタ.*
from 正社員
inner join 社員マスタ using 社員ID

つかいみち

この構造は何に使えるだろう。
特定のサブセットのデータ件数が、全体から見てきわめて少数のときに、スーパーセットを全件なめなくてよくなるので、検索がすごい速くなる、ということはないか。


データ数50万件の受注ヘッダに、1日平均100件のデータが追加されているとする。

受注ヘッダ(E) = { 受注番号, 顧客ID, 金額, 出荷日, 受注ステータス }

注文が入った時点で「受注ステータス」は「未出荷」であり、出荷完了したら「出荷済み」ステータスに変えられる。
ほとんどの業務は、未出荷のデータについて行われるので、受注ヘッダへのクエリの7割は "受注ステータス=未出荷" で絞り込みをしている。

select 受注ヘッダ.*
from 受注ヘッダ
where 受注ステータス=未出荷 
and ...

受注ステータスにはインデックスがついているが、その他の複合条件によっては受注ステータスのインデックスが使用されなくなることがある。
... こんな状況だったら、受注ステータスを廃止して、サブセット「未処理受注」を追加してみる。

受注ヘッダ(E) = { 受注番号, 顧客ID, 金額, 出荷日 }
未処理受注 = { 受注番号 }

で、未処理の受注データに対するクエリはこうする:

select 受注ヘッダ.*
from 未処理受注
inner join 受注ヘッダ using 受注番号
where ...


相手にするレコード数が、50万件から未処理受注件数に2桁ぐらい減るので、劇的に速くなったりしないだろうか。
ヒマなときに検証してみる。