0

私は次のことをしたい:

基本的に、イベントテーブルのデザインは次のとおりです。

イベント:

  • id
  • コード
  • 日にち

新しいイベントが作成されたら、次のことを行います。

  • すでに利用可能なコードがあるかどうかを確認します。日付がすでに過ぎている場合は、コードを利用できます。

    $code1 = select code from event where date_add(date, INTERVAL 7 day) < NOW() AND code NOT IN (select code from event where date_start > NOW()) limit 1

  • コードが利用可能な場合は、そのコードを取得して、新しいイベントに使用します。

    insert into event (code, date) VALUES($code1, NOW())

  • コードが利用できない場合は、新しいコードを生成します。

問題は、2つのイベントが同時に作成されると、両方が同じコードを取得するのではないかと心配していることです。どうすればそれを防ぐことができますか?

目標は、イベントごとに1〜100のコードを割り当てることです。1-100は100の数字しかないため、コードをリサイクルする必要があります。そのため、古いコードをチェックして新しいイベントに割り当てます。古いコードをリサイクルして、1から100までのコードをイベントに割り当てられるようにしたいと思います。同じコードを2つの異なるイベントに割り当てたくありません。

4

2 に答える 2

0

わかりました、これはロングショットであり、私はデータベース担当者ではないので、一粒の塩で私の提案を取り、あなた自身の研究をしてください...

あなたが欲しいのはシリアル化可能なトランザクションだと思います。基本的に、最初にMySQLにを使用してトランザクション分離をシリアル化SET TRANSACTION ISOLATION LEVEL SERIALIZABLE可能にするように依頼します。次に、3つのステップの前に、を実行してトランザクションを開始し、START TRANSACTION3つのステップの後にを実行しますCOMMIT

さらに読む:

直列化可能性がもたらすオーバーヘッドについてはよくわかりません。うまくいけば、データベースに精通している誰かがチップインすることができます。

問題を回避できるのであれば、トランザクションを使用するよりも個人的にそれを実行したいと思います。

于 2012-09-12T15:33:58.153 に答える
0

作業中はテーブルをロックする必要があります。

LOCK TABLE event WRITE;
SELECT MIN(code) FROM event WHERE date_add(date_end, INTERVAL 7 day) < NOW()
     AND code NOT IN (SELECT code FROM event WHERE date_start > NOW());
...
INSERT INTO event ...
UNLOCK TABLES;

また、すべてのアクティブなコード(この場合は1から100までのすべての番号)を含むテーブルを保持することもできます。この場合INSERT、1つのステートメントでを行うことができます。

INSERT INTO event ( code, <other fields> )
    SELECT MIN(codes.code) AS code, <other values> FROM codes
        LEFT JOIN event ON ( codes.code = event code
        AND ( event.date_end > DATE_ADD(now(), INTERVAL 7 day)
              OR event.date_start >= NOW()) )
    WHERE event.code IS NULL;

これにより、「アクティブな」イベントで使用されていないすべてのコードが選択され、それらの最小のものがに挿入されますevent(必要に応じて他のフィールドを追加します)。

テーブルの代わりにsubSELECT(SELECT DISTINCT code FROM event)を使用することもできcodesますが、その場合は、少なくとも1回はすでに使用したコードのみを選択します。「新しい」コードは無視されます。

上記のロジックの副作用は、大きなコードが再利用される頻度が低くなることです。つまり、アクティブなイベントが20ある場合、1〜20のコードを使用している可能性があります。代わりにコードを均等にリサイクルしたい場合は、例SELECT ... ORDER BY RAND() LIMIT 1

于 2012-09-12T15:34:26.740 に答える