MySQL5.5的分區表

變動普通表baby_user_change_log爲分區表html




1、 表列描述node

     mysql> desc baby_user_change_log ;mysql

     +--------------+------------------+------+-----+---------+----------------+sql

     | Field        | Type             | Null | Key | Default | Extra          |數據庫

     +--------------+------------------+------+-----+---------+----------------+服務器

     | id           | int(11) unsigned | NO   | PRI | NULL    | auto_increment |app

     | account_id   | int(11) unsigned | NO   | MUL | NULL    |                |ide

     | app_id       | int(11)          | YES  |     | NULL    |                |函數

     | operate      | varchar(20)      | YES  |     | NULL    |                |優化

     | old_data     | varchar(2000)    | YES  |     | NULL    |                |

     | new_data     | varchar(2000)    | YES  |     | NULL    |                |

     | change_data  | varchar(2000)    | YES  |     | NULL    |                |

     | operate_time | int(11)          | YES  |     | NULL    |                |

     +--------------+------------------+------+-----+---------+----------------+


2、 表結構特徵


      CREATE TABLE `baby_user_change_log` (

      `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增id',

      `account_id` int(11) unsigned NOT NULL COMMENT 'account_id',

      `app_id` int(11) DEFAULT NULL COMMENT '平臺ID',

      `operate` varchar(20) DEFAULT NULL COMMENT '操做類型',

      `old_data` varchar(2000) DEFAULT NULL COMMENT '修改以前的數據',

      `new_data` varchar(2000) DEFAULT NULL COMMENT '修改以後的數據',

      `change_data` varchar(2000) DEFAULT NULL COMMENT '被修改的數據',

      `operate_time` int(11) DEFAULT NULL COMMENT '時間',

      PRIMARY KEY (`id`),

      KEY `idx_account_id` (`account_id`)

      )ENGINE=MyISAM AUTO_INCREMENT=18543058 DEFAULT CHARSET=utf8;


3、適合的分區方案


      1)表總數據記錄條數:

      mysql> select count(*) from baby_user_change_log;

      +----------+

      | count(*) |

      +----------+

      | 18552945 |

      +----------+  

      

      2)其中app_id 列具備按照RANGE分區的特徵

      

      mysql> select distinct(app_id) from baby_user_change_log;

      +--------+

      | app_id |

      +--------+

      |      7 |

      |      5 |

      |      3 |

      |      1 |  

      +--------+  

     

      3)具體的分區表結構SQL

      

       CREATE TABLE `baby_user_change_log_partition` (

       `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增id',

       `account_id` int(11) unsigned NOT NULL COMMENT 'account_id',

       `app_id` int(11) DEFAULT NULL COMMENT '平臺ID',

       `operate` varchar(20) DEFAULT NULL COMMENT '操做類型',

       `old_data` varchar(2000) DEFAULT NULL COMMENT '修改以前的數據',

       `new_data` varchar(2000) DEFAULT NULL COMMENT '修改以後的數據',

       `change_data` varchar(2000) DEFAULT NULL COMMENT '被修改的數據',

       `operate_time` int(11) DEFAULT NULL COMMENT '時間',

       PRIMARY KEY (`id`,`app_id`),

       KEY `idx_account_id` (`account_id`)

       )ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8

       PARTITION BY RANGE (app_id) (

       PARTITION p0 VALUES LESS THAN (1),

       PARTITION p1 VALUES LESS THAN (3),

       PARTITION p2 VALUES LESS THAN (5),

       PARTITION p3 VALUES LESS THAN (7),

       PARTITION p4 VALUES LESS THAN MAXVALUE

       );  

      

      4)插入數據

        

        insert into baby_user_change_log_partition select* from baby_user_change_log;

     

      5)驗證結果

      

      mysql> explain partitions select *  from baby_user_change_log_partition where app_id=1;

      +----+-------------+-----------------------------------------+------------+------+---------------+------------+---------+-------+-------+-------+

      | id | select_type | table                                   | partitions | type | possible_keys | key        | key_len | ref   | rows  | Extra |

      +----+-------------+-----------------------------------------+------------+------+---------------+------------+---------+-------+-------+-------+

      |  1 | SIMPLE      | baby_user_change_log_partition | p1         | ref  | idx_app_id    | idx_app_id | 4       | const | 25739 |       |

      +----+-------------+-----------------------------------------+------------+------+---------------+------------+---------+-------+-------+-------+

      1 row in set (0.00 sec)

      

      mysql> explain partitions select *  from baby_user_change_log_partition where app_id=7;

      +----+-------------+-----------------------------------------+------------+------+---------------+------------+---------+-------+------+-------+

      | id | select_type | table                                   | partitions | type | possible_keys | key        | key_len | ref   | rows | Extra |

      +----+-------------+-----------------------------------------+------------+------+---------------+------------+---------+-------+------+-------+

      |  1 | SIMPLE      | baby_user_change_log_partition | p4         | ref  | idx_app_id    | idx_app_id | 4       | const |  276 |       |

      +----+-------------+-----------------------------------------+------------+------+---------------+------------+---------+-------+------+-------+

      1 row in set (0.00 sec)

      

      mysql> explain partitions select *  from baby_user_change_log_partition;

      +----+-------------+-----------------------------------------+----------------+------+---------------+------+---------+------+-------+-------+

      | id | select_type | table                                   | partitions     | type | possible_keys | key  | key_len | ref  | rows  | Extra |

      +----+-------------+-----------------------------------------+----------------+------+---------------+------+---------+------+-------+-------+

      |  1 | SIMPLE      | baby_user_change_log_partition | p0,p1,p2,p3,p4 | ALL  | NULL          | NULL | NULL    | NULL | 56269 |       |

      +----+-------------+-----------------------------------------+----------------+------+---------------+------+---------+------+-------+-------+

      1 row in set (0.00 sec)



4、 分區表的原理及優缺點



     1)分區表是什麼?分區表是由多個相關的底層表實現,這些底層表也是由句柄對象表示,因此咱們也能夠直接訪問各個分區,

        存儲引擎管理分區的各個底層表和管理普通表同樣(全部的底層表都必須使用相同的存儲引擎),分區表的索引只是在各個

        底層表上各自加上一個相同的索引,從存儲引擎的角度來看,底層表和一個普通表沒有任何不一樣,存儲引擎也無須知道這是

        一個普通表仍是一個分區表的一部分。

     

     2)在分區表上的操做按照下面的操做邏輯進行:

     

        1.select查詢:

     

          當查詢一個分區表的時候,分區層先打開並鎖住全部的底層表,優化器判斷是否能夠過濾部分分區,

          而後再調用對應的存儲引擎接口訪問各個分區的數據

     

        2.insert操做:

     

          當寫入一條記錄時,分區層打開並鎖住全部的底層表,而後肯定哪一個分區接受這條記錄,再將記錄寫入對應的底層表

     

        3.delete操做:

     

          當刪除一條記錄時,分區層先打開並鎖住全部的底層表,而後肯定數據對應的分區,最後對相應底層表進行刪除操做

     

        4.update操做:

     

          當更新一條數據時,分區層先打開並鎖住全部的底層表,mysql先肯定須要更新的記錄在哪一個分區,而後取出數據並更新,

          再判斷更新後的數據應該放在哪一個分區,而後對底層表進行寫入操做,並對原數據所在的底層表進行刪除操做

     

     3)雖然每一個操做都會打開並鎖住全部的底層表,但這並非說分區表在處理過程當中是鎖住全表的,若是存儲引擎可以本身實現行級鎖,

         如:innodb,則會在分區層釋放對應的表鎖,這個加鎖和解鎖過程與普通Innodb上的查詢相似。

     

     4)分區表適用的場景

     

        1.表很是大以致於沒法所有都放在內存中,或者只在表的最後部分有熱點數據,其餘都是歷史數據

     

        2.分區表的數據更容易維護,如:想批量刪除大量數據可使用清除整個分區的方式。另外,

          還能夠對一個獨立分區進行優化、檢查、修復等操做

     

        3.分區表的數據能夠分佈在不一樣的物理設備上,從而高效地利用多個硬件設備

     

        4.可使用分區表來避免某些特殊的瓶頸,如:innodb的單個索引的互斥訪問,ext3文件系統的inode鎖競爭等

     

        5.若是須要,還能夠備份和恢復獨立的分區,這在很是大的數據集的場景下效果很是好

     

        6.優化查詢,在where字句中包含分區列時,能夠只使用必要的分區來提升查詢效率,

          同時在涉及sum()和count()這類聚合函數的查詢時,能夠在每一個分區上面並行處理,

          最終只須要彙總全部分區獲得的結果。

          

     5)分區表的限制

        

     

        1.一個表最多隻能有1024個分區,包含子分區(mysql5.6以後支持8192個分區)

     

        2.在mysql5.1中分區表達式必須是整數,或者是返回整數的表達式,

          在5.5以後某些場景能夠直接使用字符串列和日期類型列來進行分區

          使用varchar字符串類型列時,通常仍是字符串的日期做爲分區。

     

        3.若是分區字段中有主鍵或者惟一索引列,那麼全部主鍵列和惟一索引列都必須包含進來,

          若是表中有主鍵或惟一索引,那麼分區鍵必須是主鍵或惟一索引

     

        4.分區表中沒法使用外鍵約束

     

        5.mysql數據庫支持的分區類型爲水平分區,並不支持垂直分區,

          所以mysql數據庫的分區中索引是局部分區索引,一個分區中既存放了數據又存放了索引,

          而全局分區是指的數據庫放在各個分區中,可是全部的數據的索引放在另一個對象中

     

        6.目前mysql不支持空間類型和臨時表類型進行分區。不支持全文索引

     


5、分區表的分區類型

     

    1)分區表根據數據類型的特徵適用不一樣的分區類型主要的類型有:

    

       1.RANGE分區:基於屬於一個給定連續區間的列值,把多行分配給分區。


       2.LIST分區:相似於按RANGE分區,區別在於LIST分區是基於列值匹配一個離散值集合中的某個值來進行選擇。


       3.HASH分區:基於用戶定義的表達式的返回值來進行選擇的分區,該表達式使用將要插入到表中的這些行的列值進行計算。

         這個函數能夠包含MySQL 中有效的、產生非負整數值的任何表達式。


       4.KEY分區:相似於按HASH分區,區別在於KEY分區只支持計算一列或多列,且MySQL服務器提供其自身的哈希函數。

         必須有一列或多列包含整數值。




     分區表官方文檔的解釋與說明:

    

     http://dev.mysql.com/doc/refman/5.5/en/partitioning.html

相關文章
相關標籤/搜索