2013-06-27 34 views
2

我想創建一個分區表,這個分區表將被填充數以百萬計的記錄。使用分區我怎樣才能讓特定的一天的記錄進入一個分區,然後是第二天的另一個分區,等等。然後,在九十多天後,我可以從最舊的分區中刪除舊數據。如何分區MySql表格以便與90天旋轉分區一起使用?

我試過這個聲明(哈希函數使用模數來對分區數量進行計算,哪個分區獲取數據)。這確保每天使用92個分區中的不同分區之一;除非它不起作用。

CREATE TABLE records(
    id INT NOT NULL AUTO_INCREMENT, 
    dt DATETIME, 
    PRIMARY KEY (id) 
) 
PARTITION BY HASH((MOD(DAYOFYEAR(dt), 92) + 92)) 
PARTITIONS 92; 

上面的代碼片段的問題是,在哈希表達式中使用的列必須是表中的唯一鍵。

我該如何解決這個問題,以便根據每天的記錄有九十個(ish)旋轉分區?

如果我只是將dt列添加到主鍵,它似乎擊中所有分區,如果選擇一個日期範圍,這不是我想要的。

任何想法?

回答

1

原因是,要在日期字段上進行分區並按範圍進行查詢,您必須在分區表達式中使用YEAR()TO_DAYS()

分區像這樣按預期工作:

CREATE TABLE `alert` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `eventId` int(10) unsigned NOT NULL, 
    `occurred` datetime NOT NULL, 
    KEY `id` (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin 
/*!50100 PARTITION BY RANGE (TO_DAYS(occurred)) 
(PARTITION 28_06 VALUES LESS THAN (735413) ENGINE = InnoDB, 
PARTITION 29_06 VALUES LESS THAN (735414) ENGINE = InnoDB, 
PARTITION 30_06 VALUES LESS THAN (735415) ENGINE = InnoDB, 
PARTITION 01_07 VALUES LESS THAN (735416) ENGINE = InnoDB, 
PARTITION 02_07 VALUES LESS THAN (735417) ENGINE = InnoDB, 
PARTITION 03_07 VALUES LESS THAN (735418) ENGINE = InnoDB, 
PARTITION 04_07 VALUES LESS THAN (735419) ENGINE = InnoDB, 
PARTITION 05_07 VALUES LESS THAN (735420) ENGINE = InnoDB, 
PARTITION 06_07 VALUES LESS THAN (735421) ENGINE = InnoDB, 
PARTITION 07_07 VALUES LESS THAN (735422) ENGINE = InnoDB) */ 

mysql> explain partitions SELECT * FROM alert WHERE occurred >= '2013-07-02' and occurred <= '2013-07-04'; 
+----+-------------+-------+-------------------+------+---------------+------+---------+------+------+-------------+ 
| id | select_type | table | partitions  | type | possible_keys | key | key_len | ref | rows | Extra  | 
+----+-------------+-------+-------------------+------+---------------+------+---------+------+------+-------------+ 
| 1 | SIMPLE  | alert | 02_07,03_07,04_07 | ALL | NULL   | NULL | NULL | NULL | 3 | Using where | 
+----+-------------+-------+-------------------+------+---------------+------+---------+------+------+-------------+ 

然後,你需要管理刪除和分區自己創造。

0

實際上,問題是如果密鑰中的所有列未包含在散列函數中,則您無法在分區表上定義PRIMARY或UNIQUE鍵。

一個可能的「修復」是從KEY定義中刪除「PRIMARY」關鍵字。

問題是,當你聲明一個密鑰是UNIQUE或PRIMARY時,MySQL必須執行唯一性。爲了執行該操作,MySQL需要能夠檢查鍵值是否已經存在。 MySQL不是檢查每個分區,而是使用分區功能來確定發現特定密鑰的分區。