0

私のテーブルは次のようになります。

CREATE TABLE IF NOT EXISTS `entry_title` (
  `entry_title_id` int(11) NOT NULL AUTO_INCREMENT,
  `entry_id` int(11) NOT NULL,
  `accepted` tinyint(1) DEFAULT NULL,
  `entry_title_lang` char(2) CHARACTER SET ascii NOT NULL,
  `entry_title_value` varchar(255) NOT NULL,
  `entry_title_created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`entry_title_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

表の行は、Webサイトのコンテンツのタイトルを表します。

アイデアは、誰でも新しい(うまくいけば改善された)タイトルを提出できるということです。

次に、コミュニティは変更を受け入れるか破棄します。

承認されたフラグが等しい場合、NULLこれは変更がコミュニティによるレビューを保留していることを表します。0は破棄され、1は受け入れられたと解釈されます。

timestampWebサイトには、受け入れられたフラグがに等しい最新のタイトルが表示されます1

変更が保留中のレビューである場合、保留中の変更が承認または拒否されるまで、他の変更を送信することはできません。

entry_idしたがって、の値がである場所ごとに行のみが存在することを確認する制約がデータベースに必要acceptedですNULL

pending_reviewまたはのいずれ1かである個別のフィールドを使用することを考え、。NULLと組み合わせてUNIQUE制約を設定しましたentry_id

それに関する問題は、変更が受け入れられるか拒否されるときに、どういうわけかそのフィールドの設定を解除する必要があり、そのレベルでの一貫性は、上記のより単純な解決策と同じ問題につながる別の制約を必要とすることです。

4

1 に答える 1

1

[更新] 標準主導の理想的な世界では:

CHECK(NOT EXISTS(SELECT 1 FROM entry_title WHERE accepted IS NULL GROUP BY entry_id HAVING COUNT(*) > 1))

悲しいかな、私たちは不完全な世界に住んでいます。この質問を参照してください

そのため、代わりに同じロジックでトリガーを使用してください。

【更新~きっかけ】

何かのようなもの

CREATE TRIGGER triggerName BEFORE INSERT ON entry_title FOR EACH ROW
BEGIN
    IF EXISTS(SELECT 1 FROM entry_title 
              WHERE accepted IS NULL AND entry_id = NEW.entry_id 
              GROUP BY entry_id 
              HAVING COUNT(*) > 1) THEN
        SIGNAL SQLSTATE '45000'
    END IF;
END

BEFORE UPDATE に対しても同じことを行います。免責事項、私はこれをチェックしませんでした。

于 2012-06-13T10:07:17.547 に答える