における複合サロゲートキーはここに私の現在のデータベースの抜粋です(理解を容易にするために、テーブル名を変更):スコープ/ MySQLの
id
は常に
auto_increment
で作成した代理キー、ある
Pet(ownerFK, id, name, age)
Owner(id, name)
。
私はサロゲートキーPet.id
をPet.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()
を使わない。 このソリューションには注意点がありますか?
私はあなたのポイントを見ます。私の実際のデータベース設計は少し異なりますし、プライマリキーの一部である必要もありません。私は評価している現在の解決策で質問を更新しました。 –