2012-08-28 40 views
1

我有這種形式的插入查詢:不希望分區密鑰成爲唯一密鑰的一部分。任何解決方法?

on INSERT into abc values .... on DUPLICATE KEY UPDATE .... 

我在原來的表不分區,唯一的關鍵是對(subject_id, object_id),但現在我被ts分區和我被迫具有獨特的密鑰(subject_id, object_id, ts)因爲mysql要求在所有唯一鍵中有分區鍵。

這意味着我的插入查詢將會失敗,因爲插入具有與之前插入相同的subject_id和object_id,但不同的時間戳將被視爲唯一的新行,並將插入而不是所需的更新。

有什麼解決方法嗎?

CREATE TABLE `abc` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT, 
    `subject_id` varchar(40) COLLATE utf8_unicode_ci NOT NULL, 
    `object_id` varchar(36) COLLATE utf8_unicode_ci NOT NULL, 
    `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 
    PRIMARY KEY (`id`,`ts`), 
    UNIQUE KEY `userint_sub_type_obj` (`subject_id`,`object_id`, `ts`) 
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci 
/*!50100 PARTITION BY RANGE (unix_timestamp(ts)) 
(PARTITION p2012_08_27 VALUES LESS THAN (1346025600) ENGINE = InnoDB, 
PARTITION p2012_08_28 VALUES LESS THAN (1346112000) ENGINE = InnoDB, 
PARTITION p2012_08_29 VALUES LESS THAN (1346198400) ENGINE = InnoDB, 
PARTITION p2012_08_30 VALUES LESS THAN (1346284800) ENGINE = InnoDB, 
PARTITION p2012_08_31 VALUES LESS THAN (1346371200) ENGINE = InnoDB) */ 

回答

2

說得很快,沒有辦法,我知道的添加分區未做分區鍵的所有獨特的(因此也初級)鍵的一部分。

http://dev.mysql.com/doc/refman/5.5/en/partitioning-limitations-partitioning-keys-unique-keys.html

其實我上週有同樣的問題,嘗試在啓用/禁用列刪除分區。想到兩種解決方案。

  1. 您可以將時間戳移動到meta_info表中並對其進行分區。您的外觀有時間條件,然後可以使用該分區而不會混淆(subject_id,object_id)鍵。開銷是當然你需要做一個加入。如果你的桌子很大,這可能是不可行的。
  2. 更新前請檢查。您不必使用ON DUPLICATE KEY選項,而是將動作分成SELECT以查看記錄是否存在,然後根據對其的答案進行INSERT或UPDATE。

不用說,我已經找到了分區的這種限制是在後一個巨大的痛苦,但它似乎是在MySQL和一些谷歌賦後,問身邊的限制,它好像有簡單繞過它。