8

tbl_jobsアプリケーションで実行されているいくつかのバックグラウンド ジョブのメタ データを格納するという名前のテーブルがあります。スキーマは次のようになります。

CREATE TABLE `tbl_jobs` (
  `type` varchar(30) NOT NULL DEFAULT '',
  `last_run_on` datetime NOT NULL,
  `records_updated` text,
  PRIMARY KEY (`type`,`last_run_on`),
  UNIQUE KEY `index2` (`type`,`last_run_on`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1$$

typeジョブが実行されるたびに、異なるジョブの一意の識別子であるrun timeとその実行の を含むエントリがテーブルに作成さrecords updatedれます。

タイプ と で同時に実行される 2 つの異なるジョブがありMAILER_UNLOCKED_REWARDS ますMAILER_ALMOST_UNLOCKED

これらのジョブが同じタイムスタンプを持つエントリを挿入しようとすると、そのうちの 1 つだけが挿入され、もう 1 つのジョブはキーエラーの重複エントリをスローします。

たとえば、2 つのジョブは次のように実行されます。

INSERT INTO tbl_jobs
            (type,
             last_run_on,
             records_updated)
VALUES     ('MAILER_ALMOST_UNLOCKED',
            '2012-08-22 19:10:00',
            'f8a35230fb214989ac75bf11c085aa28:b591426df4f340ecbce5a63c2a5a0174')

それは正常に実行されましたが、2 番目のジョブが挿入コマンドを実行したときに

INSERT INTO tbl_jobs
            (type,
             last_run_on,
             records_updated)
VALUES     ('MAILER_UNLOCKED_REWARDS',
            '2012-08-22 19:10:00',
            '8a003e8934c07f040134c30959c40009:59bcc21b33a0466e8e5dc50443beb945')

エラーをスローしました

Duplicate entry 'M-2012-08-22 19:10:00' for key 'PRIMARY'

主キーはtypelast_run_on列の組み合わせです。

timestamp最初のジョブのエントリを削除すると、挿入は成功します。つまり、単独で一意であることを求めています。

ただし、同じものに対する競合は、timestampこれら 2 つのジョブ間でのみ発生します。同じものに対して挿入される他のジョブがありますtimestamp

何が問題になる可能性があるかについてのアイデアはありますか?

4

3 に答える 3

5

インデックスで「タイプ」フィールド全体を使用していますか?それとも最初のキャラクターだけですか?MySQLが不平を言っているのは

M-2012-08-22 19:10:00

MAILER_..の代わりに

実行してみてください:

 SHOW INDEXES FROM tbl_jobs;

それは次のようなものを与えるはずです:

+----------+------------+----------+--------------+-------------+-----------+-------------+    ----------+--------+------+------------+---------+---------------+
| Table    | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| tbl_jobs |          0 | PRIMARY  |            1 | type        | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
| tbl_jobs |          0 | PRIMARY  |            2 | last_run_on | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |

..。

代わりに、PRIMARYインデックスのSub_part列に「1」が表示されると思います。

+----------+------------+----------+--------------+-------------+-----------+-------------+    ----------+--------+------+------------+---------+---------------+
| Table    | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| tbl_jobs |          0 | PRIMARY  |            1 | type        | A         |           0 |        1 | NULL   |      | BTREE      |         |               |
| tbl_jobs |          0 | PRIMARY  |            2 | last_run_on | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |

..。

ところで、主キーは常に一意であるため、index2そこで宣言する2番目のインデックスは冗長です。

于 2012-08-22T14:41:06.580 に答える
0

まず、PRIMARY KEY が AUTO_INCREMENT に設定されていることを確認する必要があります。2 つ目: 自動インクリメントを有効にするだけです: ALTER TABLE [テーブル名] AUTO_INCREMENT = 1 3 つ目: 挿入コマンドを実行するときは、このキーをスキップする必要があります。

于 2016-02-04T01:16:34.593 に答える