2009-04-11 3 views
0

における複合サロゲートキーはここに私の現在のデータベースの抜粋です(理解を容易にするために、テーブル名を変更):スコープ/ MySQLの

idは常に auto_incrementで作成した代理キー、ある
Pet(ownerFK, id, name, age) 
Owner(id, name) 

私はサロゲートキーPet.idPet.ownerFKで "スコープ"にするか、または複合キー[ownerFk, id]を最小キーとして使用したいと考えています。私は、テーブルは次のように動作するようにしたい:

INSERT Pet(1, ?, "Garfield", 8); 
INSERT Pet(1, ?, "Pluto", 12); 
INSERT Pet(2, ?, "Mortimer", 1); 

SELECT * FROM Pet; 
    RESULT: 
    Pet(1, 1, "Garfield", 8) 
    Pet(1, 2, "Pluto", 12) 
    Pet(2, 1, "Mortimer", 1) 

あなたが複数列のインデックス内の二列にAUTO_INCREMENTを指定することができますここで、」この場合、AUTO_INCREMENT列の生成された値を、私は現在このfeature of MyISAMを使用しています。 MAX(auto_increment_column) + 1 WHERE prefix=given-prefixと計算されます。データを順序付けられたグループに入れたい場合に便利です。

しかし、いろいろな理由から、私はいくつかの場所でトランザクションが必要なので、MyISAMからInnoDBに切り替える必要があります。

この効果を達成する方法はありますか?InnoDB

私はこの問題についていくつかの記事を見つけましたが、その多くは挿入前に書き込みロックすることを提案しました。私はこれにあまり慣れていませんが、テーブルライトロックではないでしょうか?私は、これらが可能な場合には書面で安全な取引(これまで決してなかったこと)を考えていました。つまり、Owner.current_pet_counterをヘルパーフィールドとして使用しました。

だから、別の受け入れ可能な解決策は次のようになり は...実は私は、実際のキーの一部であることを、「スコープ」IDは必要ありません。実際のデータベース設計では、この「機能」を使用する別の「パーマリンク」テーブルを使用しています。私は現在、不足しているトランザクションの回避策として使用しています。

Pet(id, ownerFK, scopedId, name, age), KEY(id), UNIQUE(ownerFK, scopedId) 
Owner(id, name, current_pet_counter) 

START TRANSACTION WITH CONSISTENT SNAPSHOT; 
SELECT @new=current_pet_counter FROM Owner WHERE id = :owner_id; 
INSERT Pet(?, :owner_id, @new, "Pluto", 21); 
UPDATE Owners SET current_pet_counter = @new + 1 WHERE id = :owner_id; 
COMMIT; 

私はまだMySQLでのトランザクション/ transactionvarsで働いていないので、私はこの1つの深刻な問題が存在することになるかどうかわからない:私は、次の代替を考えました。 注:私はペットに一度与えられたidを再利用したくありません。だから私はMAX()を使わない。 このソリューションには注意点がありますか?

答えて

1

私はそう信じません。あなたが本当にそのスキーマを持っていなければならない場合は、トランザクションを使用してMAX(id)WHERE ownerFKを選択してからINSERTすることができます。

私は非常に懐疑的ですが、そのスキーマには十分な理由があります。プライマリ・キーはキーに関する事実でもあり、データベースの理論家に不満を抱かせる可能性があります。

通常は、idを本当に適切なプライマリキーにする必要があります。ownerFKをグループ化し、必要に応じて、所有者ごとに特定の順序でペットを配置する別の「ランク」列を使用します、UNIQUEインデックス(ownerFK、rank)を超えています。

+0

私はあなたのポイントを見ます。私の実際のデータベース設計は少し異なりますし、プライマリキーの一部である必要もありません。私は評価している現在の解決策で質問を更新しました。 –