2013-02-05 34 views
2

我正在使用MySQL 5.5,並且在生產中存儲了一個存儲客戶事務的現有表。該表的簡化版本是:MySQL使用分區並保持主鍵不變

CREATE TABLE transactions (
    id INT NOT NULL AUTO_INCREMENT, 
    description CHAR(100), 
    posted DATE, 
    PRIMARY KEY (id) 
) ENGINE=MyISAM 

我們正在探索採用交易發生日的分區,使使用日期過濾更快地執行報告的想法。由於MySQL Partitioning Keys documentation中解釋的主鍵和分區限制,以下嘗試失敗。

mysql> CREATE TABLE transactions (
    -> id INT NOT NULL AUTO_INCREMENT, 
    -> description CHAR(100), 
    -> posted DATE, 
    -> PRIMARY KEY (id) 
    ->) ENGINE=MyISAM 
    -> PARTITION BY HASH(MONTH(posted)) PARTITIONS 12; 
ERROR 1503 (HY000): A PRIMARY KEY must include all columns in the table's partitioning function 

一個可能的解決方法如下:

CREATE TABLE transactions (
    id INT NOT NULL AUTO_INCREMENT, 
    description CHAR(100), 
    posted DATE, 
    PRIMARY KEY (id, posted) 
) ENGINE=MyISAM 
PARTITION BY HASH(MONTH(posted)) PARTITIONS 12; 

另一種解決方法是:

CREATE TABLE transactions (
    id INT NOT NULL AUTO_INCREMENT, 
    description CHAR(100), 
    posted DATE, 
    KEY (id) 
) ENGINE=MyISAM 
PARTITION BY HASH(MONTH(posted)) PARTITIONS 12; 

在這兩種變通方法的數據庫不會使用相同的ID停止的多個記錄的情況,但發佈日期不同。有沒有辦法在發佈的字段上使用分區並保持原始的唯一約束?

回答

3

我已經面臨這個同樣的「問題」,以及一個解決辦法,我發現這是分裂我的表二,導致你的情況是這樣的:

CREATE TABLE transactions (
    id INT NOT NULL AUTO_INCREMENT, 
    description CHAR(100), 
    PRIMARY KEY (id) 
) ENGINE=MyISAM; 

另:

CREATE TABLE transactions_date (
    id INT NOT NULL, 
    posted DATE 
) ENGINE=MyISAM 
PARTITION BY HASH(MONTH(posted)) PARTITIONS 12; 

明顯的問題是,你必須使用SELECT報表時,一些額外的邏輯添加到應用程序,如需要獲取兩個表中檢索所有數據。您可以使用triggers來幫助您完成與INSERTUPDATEDELETE相關的任務。

只是注意:可以從DATEDATETIME列使用partition pruning獲益的唯一功能是:YEAR()TO_DAYS()TO_SECONDS()(最後一個只可從MySQL 5.5)。

+3

我得出的結論是,分區對於像在數據倉庫中的在線表的副本是好的,在這種情況下,您並不在乎強制實施數據完整性,而是希望獲得更好的性能。 –