複合キーの実装または代替方法について

3,096 views
Skip to first unread message

Morimoto Tetsuya

unread,
Jun 19, 2009, 3:22:36 AM6/19/09
to djan...@googlegroups.com
初めて投稿します。森本と申します。
Django で Web アプリケーションの開発方法を学び始めた初心者です。

Django では、複合キーをサポートしていないとあります。
「一つのオブジェクトには一つしか主キーを指定できません。」
http://djangoproject.jp/doc/ja/1.0/ref/models/fields.html#primary-key

複合キーについて以下の疑問があります。
私は Web アプリケーションの開発経験がないので、
概念的なことも含めてご教示頂ければ嬉しいです。

1. 複合キーを用いた既存スキーマからの移行
Django では、どのようなモデルを構築すべきなのでしょうか?

2. どうしても複合キーを使いたいとき
以下のようなやり方が正しいのでしょうか?
「djangoのモデルのフィールドを組み合わせで一意にする 」
http://snippets.hachinos.net/lang/python/user/piro_suke/1/

3. 複合キーのメリット・デメリット
少し古いですが Rails や CakePHP でも
複合キーをサポートしないという議論があることを知りました。
http://cakephp.seesaa.net/article/46624086.html

複合キーをサポートしない根拠が私にはよく分かりません。
仕様であれば、それはそれで良いのですが、
複合キーをサポートするデメリットの有無が分かりません。

例えば、以下のようなスキーマの場合、id の代理キーを使うよりも、
複合キーを使った方が構造的にシンプルで、
パフォーマンス的にもメリットがあるように私は思います。
※ 私が RDB を中心に考えているので疑問に思うのですが、、、

グループマスタ
- グループID Pkey
- グループ名

個別マスタ
- 個別 ID Pkey
- グループ ID Pkey
- 名前

以上、宜しくお願いします。

Makoto Uemura

unread,
Jun 19, 2009, 3:49:51 AM6/19/09
to djan...@googlegroups.com
uemuraです。

Djangoに限らず一般的なWebフレームワークではprimarykeyはid (auto increment)
きめうちだと思います。

複数primarykeyを採用するとモデル側が複雑になりすぎるのが理由だと思われます。

SQLAlchemyなら複数PrimaryKeyでも扱えるので、
DjangoのO/Rマッパーを使わず
管理画面が使えないなどの
デメリットを承知でSQLAlchemyを採用するか
SQLAlchemyを使ってフレームワークを自作するしかないのが現状だと思います。


2009/6/19 Morimoto Tetsuya <tetsuya....@gmail.com>:

tsuyuki makoto

unread,
Jun 19, 2009, 1:46:17 PM6/19/09
to djan...@googlegroups.com
露木です。

2009/06/19 16:22 に Morimoto Tetsuya<tetsuya....@gmail.com> さんは書きました:
>
> 初めて投稿します。森本と申します。


>
> 1. 複合キーを用いた既存スキーマからの移行
> Django では、どのようなモデルを構築すべきなのでしょうか?

複合PK前提で構築されている既存スキーマのまま、は現実的に
は厳しいと思います。
#そんなことないって突っ込み大歓迎

> 2. どうしても複合キーを使いたいとき
> 以下のようなやり方が正しいのでしょうか?
> 「djangoのモデルのフィールドを組み合わせで一意にする 」
> http://snippets.hachinos.net/lang/python/user/piro_suke/1/

この方法をとるのが通常とされているはずです。
複合Indexなんかは出力されなかったと思います。

> 3. 複合キーのメリット・デメリット
> 少し古いですが Rails や CakePHP でも
> 複合キーをサポートしないという議論があることを知りました。
> http://cakephp.seesaa.net/article/46624086.html
>
> 複合キーをサポートしない根拠が私にはよく分かりません。
> 仕様であれば、それはそれで良いのですが、
> 複合キーをサポートするデメリットの有無が分かりません。
>
> 例えば、以下のようなスキーマの場合、id の代理キーを使うよりも、
> 複合キーを使った方が構造的にシンプルで、
> パフォーマンス的にもメリットがあるように私は思います。
> ※ 私が RDB を中心に考えているので疑問に思うのですが、、、

単純に、次のような理由でサポートしないのではないかと推測しています。
・1行を指し示すために複数の値を指定したくない
・PKにユニーク+インデックスという二つの意味があるのが気に食わない

RDB側からの設計でも余程の理由がなければ複合PKは使われなくなっ
てきていると思い込んでいたのですが、そうでもないようですね。

> グループマスタ
> - グループID Pkey
> - グループ名
>
> 個別マスタ
> - 個別 ID Pkey
> - グループ ID Pkey
> - 名前

これって個別 IDは個別マスタの代理キーです?
代理キー+外部キーの複合PKってあまり見かけないので、
複合PKにするメリットを後学のために教えていただける
とうれしいです。
グループIDでクラスタ化されて速い!とか!?

Morimoto Tetsuya

unread,
Jun 20, 2009, 7:52:35 PM6/20/09
to djan...@googlegroups.com
uemura さん

森本です。

早速のご返信ありがとうございます。

> SQLAlchemyなら複数PrimaryKeyでも扱えるので、
O/R マッパーを変更するという方法もあるのですね。とても参考になります。
管理画面を使えないデメリットは許容できるのでちょっと試してみたいと思います。

2009/06/19 16:49 Makoto Uemura <makoto...@gmail.com>:

Morimoto Tetsuya

unread,
Jun 20, 2009, 8:28:38 PM6/20/09
to djan...@googlegroups.com
露木さん

森本です。

丁寧にご返信ありがとうございます。

> RDB側からの設計でも余程の理由がなければ複合PKは使われなくなっ
> てきていると思い込んでいたのですが、そうでもないようですね。
私の携わったプロジェクトでそのように設計していたので、
そういうものかなと勝手に思い込んでいるだけになります。
一般的にどのように設計すれば良いというのは私は分かっていません。

ただ、パフォーマンス的なメリットを考慮すると、
意味のない数値 id キーをプライマリキーにするのは、
個人的にもったいない気がしてしまうのですね(^ ^;;
プライマリキー = ユニーク + インデックス + Not NULL が自動生成されます。
特にインデックスはたくさん張れば張るほど、
参照/更新処理のパフォーマンスに影響を与えるので、
無意味なインデックスを張りたくないと思ってしまいます。
※ 1度に数千万件データをインサートするようなバッチ系処理を作ってたからかな

> 代理キー+外部キーの複合PKってあまり見かけないので、
> 複合PKにするメリットを後学のために教えていただける
> とうれしいです。
> グループIDでクラスタ化されて速い!とか!?
私の意図があっているかどうか分からないので詳細に書きます。
個別マスタとグループマスタを持っておけば、
柔軟なスキーマ定義ができます。

例えば、商品マスタと地域別商品マスタを考えます。
ちゃんと正規化すると以下になるのかな。

商品マスタ
- 商品コード PKey
- 商品名
- メーカー

地域グループマスタ
- 地域コード PKey
- 地域名
- 原価

商品地域グループ関連テーブル
- 商品コード PKey
- 地域コード PKey

ある商品の原価という項目に着目すると、
原価は、北海道と東京と大阪で違ったりします。
商品情報は商品マスタに持つけれど、
原価情報は地域グループマスタに持ちたいとします。

1つの地域に対して1つの商品が1つの原価を持つので、
商品と地域の組合せをユニークにしたいのですね。
そういうときに上記のように複合キーを設けるのが
一般的なのかなと私は勝手に思い込んでいます。
複合キーを使えない場合、こういうときに
どのような設計をすれば良いのでしょうか?


2009/06/20 2:46 tsuyuki makoto <mtsu...@gmail.com>:

makoto tsuyuki

unread,
Jun 22, 2009, 11:39:01 AM6/22/09
to django-ja
露木です。

On 6月21日, 午前9:28, Morimoto Tetsuya <tetsuya.morim...@gmail.com> wrote:
> 森本です。
>
> > RDB側からの設計でも余程の理由がなければ複合PKは使われなくなっ
> > てきていると思い込んでいたのですが、そうでもないようですね。
>
> 私の携わったプロジェクトでそのように設計していたので、
> そういうものかなと勝手に思い込んでいるだけになります。
> 一般的にどのように設計すれば良いというのは私は分かっていません。
>
> ただ、パフォーマンス的なメリットを考慮すると、
> 意味のない数値 id キーをプライマリキーにするのは、
> 個人的にもったいない気がしてしまうのですね(^ ^;;
> プライマリキー = ユニーク + インデックス + Not NULL が自動生成されます。
> 特にインデックスはたくさん張れば張るほど、
> 参照/更新処理のパフォーマンスに影響を与えるので、
> 無意味なインデックスを張りたくないと思ってしまいます。
> ※ 1度に数千万件データをインサートするようなバッチ系処理を作ってたからかな

数千万件のバッチ処理とかになると、もうO/Rの出番ではないし、インデックスも
インサート時は再作成をされない状態にして、とか色々話は変わってきますね。

> > 代理キー+外部キーの複合PKってあまり見かけないので、
> > 複合PKにするメリットを後学のために教えていただける
> > とうれしいです。
> > グループIDでクラスタ化されて速い!とか!?
>
> 私の意図があっているかどうか分からないので詳細に書きます。
> 個別マスタとグループマスタを持っておけば、
> 柔軟なスキーマ定義ができます。
>
> 例えば、商品マスタと地域別商品マスタを考えます。
> ちゃんと正規化すると以下になるのかな。
>
> 商品マスタ
> - 商品コード PKey
> - 商品名
> - メーカー
>
> 地域グループマスタ
> - 地域コード PKey
> - 地域名
> - 原価
>
> 商品地域グループ関連テーブル
> - 商品コード PKey
> - 地域コード PKey

こういう形は見慣れています :)
Reply all
Reply to author
Forward
0 new messages