1

2つの列で設定された単純なテーブルがあり、各列はキー値です。各フィールドに格納される値は、電子メールアドレスとキーワードを表すvarchar(45)です。収集された情報は、サイト閲覧データの収集に関連しているため、重複する可能性があります。エントリの重複を避けるために、INSERT IGNORE into、REPLACE intoを使用して、最後に次のことを試みました。

insert into <table name> (user_email, key_token) values ('<email>@<this>.com', 'discountsupplies') on duplicate key update user_email='<email>@<this>.com',key_token='discountsupplies';

しかし、まだ重複したレコードがテーブルに挿入されているのがわかります。テーブルを生成したSQL:

DROP TABLE IF EXISTS `<database name>`.`<table name>` ;

CREATE  TABLE IF NOT EXISTS `<database name>`.`<table name>` (
  `user_email` VARCHAR(45) NOT NULL ,
  `key_token` VARCHAR(45) NOT NULL,
  PRIMARY KEY (`user_email`, `key_token`) )
ENGINE = InnoDB;

これに近い質問をいくつか見ましたが、なぜこれが起こっているのかを説明する質問は見当たりませんでした。この動作について理解していないことを理解したいと思います。どんな助けでも大歓迎です。


補遺として、UNIQUE KEYステートメントを追加した後、戻ってREPLACEとINSERT IGNOREの両方を試し、目標を達成しました。これらのオプションはいずれも、重複するエントリを除外していません。

また、追加:UNIQUE INDEX(user_emailkey_token)も役に立たないようです。

これを理解できるまで、手動のルックアップルーチンを介してこのチェックを実行します。答えが見つかったら、投稿を更新させていただきます。


元のcreatetableステートメントの下に一意のインデックス行を追加しました-

-- -----------------------------------------------------
-- Table `<db name>`.`<table name>`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `<db name>`.`<table name>` ;

CREATE  TABLE IF NOT EXISTS `<db name>`.`<table name>` (
  `user_email` VARCHAR(45) NOT NULL ,
  `key_token` VARCHAR(45) NOT NULL,
  PRIMARY KEY (`user_email`, `key_token`),
  UNIQUE KEY (user_email),
  UNIQUE KEY (key_token)
  )

ENGINE = InnoDB;

CREATE UNIQUE INDEX ix_<table name>_useremail on `<db name>`.`<table name>`(user_email);
CREATE UNIQUE INDEX ix_<table name>_keytoken on `<db name>`.`<table name>`(key_token);

問題はないようですが(ソースステップでテーブルを作成するときにエラーは発生しません)、重複クエリを実行すると重複が発生します。

4

4 に答える 4

1

両方の列に複合主キーがあります。

これは、各フィールドがそのままではなく、フィールドの組み合わせであることを意味しますUNIQUE

これらのデータは次の表で可能です。

1@example.com  1
2@example.com  1
2@example.com  2

(user_email, key_token)、テーブル内の繰り返しの組み合わせはありませんがuser_emailkey_tokenそれ自体は繰り返すことができます。

個別の列をそれぞれにする場合は、フィールドに制約をUNIQUE定義します。UNIQUE

CREATE  TABLE IF NOT EXISTS `<database name>`.`<table name>` (
  `user_email` VARCHAR(45) NOT NULL ,
  `key_token` VARCHAR(45) NOT NULL,
  PRIMARY KEY (`user_email`, `key_token`),
  UNIQUE KEY (user_email),
  UNIQUE KEY (key_token)
)
ENGINE = InnoDB;

アップデート

UNIQUEのレベル1バグとしてマークされた列に重複があるMySQL

次のクエリを実行してください。

SELECT  user_email
FROM    mytable
GROUP BY
        user_email
HAVING  COUNT(*) > 1

SELECT  key_token
FROM    mytable
GROUP BY
        key_token
HAVING  COUNT(*) > 1

そして、彼らが何かを返すかどうかを確認しますか?

于 2009-10-08T13:50:57.330 に答える
0

PRIMARY KEY (user_email,key_token)両方の組み合わせが一意になることを意味しますが、個々のメールと key_tokens も一意にする場合はUNIQUE、列ごとに個別に使用する必要があります..

PRIMARY KEY ('user_email', 'key_token'),
  UNIQUE KEY (user_email),
  UNIQUE KEY (key_token)
于 2009-10-08T13:53:54.237 に答える
0

現時点での最終的な解決策: user_email で key_tokens のリストを取得するためにテーブルをクエリし、リスト エントリに対して現在の key_token をテストします。見つかった場合は挿入しません。最適でもきれいでもありませんが、機能します....

于 2009-10-08T17:48:24.590 に答える
0

私には、パフォーマンス上の理由だけで複合主キーを選択したように見えますが、そのようなインデックスである必要があります

CREATE  TABLE IF NOT EXISTS `<database name>`.`<table name>` (
  `user_email` VARCHAR(45) NOT NULL ,
  `key_token` VARCHAR(45) NOT NULL,
  PRIMARY KEY (`user_email`),
  INDEX (`user_email`, `key_token`) 
)

もちろん、重複を心配している場合key_tokenでも、一意のインデックスが必要です。

申し訳ありませんが、返信が非常に遅くなりましたが、おそらく誰かが私のようにこれに出くわすでしょう:)

于 2012-06-06T03:27:14.307 に答える