0

これらの 2 つのテーブルを使用したオークション アプリケーションがあります (これは明らかに非常に単純化されています)。

create table auctions (
   auction_id int,
   end_time datetime
);

create table bids (
   bid_id int,
   auction_id int,
   user_id int,
   amount numeric,
   bid_time timestamp,
   constraint foreign key (auction_id) references auctions (auction_id)
);

オークション終了後の入札を希望しません。つまり、bids テーブルの行は、bid_time がそのオークションの end_time より早い場合にのみ許可されるべきです。MySQL でこれを行う最も簡単な方法は何ですか?

4

3 に答える 3

1

CHECK残念ながら、MySQL には制約機能がありません。ただし、トリガーを使用してこれを強制できるはずです。ただし、MySQL トリガーのサポートは、他の RDBMS ほど高度でも最適化されていないため、この方法で実行すると、パフォーマンスが大幅に低下します。したがって、これが大量の同時ユーザーを持つリアルタイム取引システムである場合は、別のソリューションを探す必要があります。

CREATE TRIGGER bir_bids
BEFORE INSERT ON bids
FOR EACH ROW
BEGIN
    DECLARE v_end_time datetime;
    -- declare a custom error condition. 
    -- SQLSTATE '45000' is reserved for that.
    DECLARE ERR_AUCTION_ALREADY_CLOSED CONDITION FOR SQLSTATE '45000';

    SELECT end_time INTO v_end_time
    FROM   auctions
    WHERE  auction_id = NEW.auction_id;

    -- the condition is written like this so that a signal is raised 
    -- only in case the bid time is greater than the auction end time.
    -- if either bid time or auction end time are NULL, no signal will be raised.
    -- You should avoid complex NULL handling here if bid time or auction end time
    -- must not be NULLable - simply define a NOT NULL column constraint for those cases.
    IF NEW.bid_time > v_end_time THEN
        SIGNAL ERR_AUCTION_ALREADY_CLOSED;
    END IF;
END:

このSIGNAL構文は MySQL 5.5 (現在 GA) 以降でのみ使用できることに注意してください。トリガーは MySQL 5.0 以降で使用できます。したがって、5.5 より前のバージョンの MySQL でこれを実装する必要がある場合は、シグナルを発生できないようにハックする必要があります。が失敗することを保証するデータに変更を加えることで、これを行うことができますINSERT。たとえば、次のように書くことができます。

    IF NEW.bid_time > v_end_time THEN
        SET NEW.auction_id = NULL;
    END IF;

acution_idはテーブルで宣言されているためNOT NULL、データは挿入できない状態になります。欠点は、NOT NULL 制約違反が発生することです。アプリケーションは、これがこのトリガーの起動によるものか、それとも「実際の」NOT NULL 制約違反によるものかを推測する必要があります。

詳細については、http://rpbouman.blogspot.nl/2009/12/validating-mysql-data-entry-with_15.html および http://rpbouman.blogspot.nl/2006/02/dont-you- を参照しください。 need-proper-error-handling.html

于 2012-07-31T11:59:13.353 に答える
1
Insert into bids (auction_id, user_id, amount, bid_time)
Select auction_id, [USER_ID], [AMOUNT], [TIMESTAMP]
From auctions
WHERE UNIX_TIMESTAMP() <= UNIX_TIMESTAMP(end_time)

もちろん、「[]」値を置き換える必要があります

于 2012-07-31T11:44:14.167 に答える
0

代わりに、列名のステータスを作成する簡単なことを行います。その型を列挙型に設定します。ブロックする場合は、値を 0 に更新します。デフォルトは 1 で、開いていることを意味します。0 は閉じていることを意味します

于 2012-07-31T11:38:45.073 に答える