1. 程式人生 > >由mysql分割槽想到的分表分庫的方案

由mysql分割槽想到的分表分庫的方案

在分割槽分庫分表前一定要了解分割槽分庫分表的動機。

對實時性要求比較高的場景,使用資料庫的分割槽分表分庫。

對實時性要求不高的場景,可以考慮使用索引庫(es/solr)或者大資料hadoop平臺來解決(如資料分析,挖掘,報表等)或者混合使用(如es+hbase/mongodb)。

...分割槽解決冷熱資料分離的問題;

...分庫解決網際網路的高併發問題;

...分表解決網際網路的高容量問題;

...分庫分表解決高併發和高容量的問題。

今天細細品味了一下mysql分割槽的官方資料,有一點點收穫,記錄下來。

1.mysql的分割槽

官方文件介紹的比較詳細,這裡就以例項為主介紹。

1.1 分割槽型別

    1.range分割槽 

CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT NOT NULL,
    store_id INT NOT NULL
)
PARTITION BY RANGE (store_id) (
    PARTITION p0 VALUES LESS THAN (6),
    PARTITION p1 VALUES LESS THAN (11),
    PARTITION p2 VALUES LESS THAN (16),
    PARTITION p3 VALUES LESS THAN (21)
);

  2.list分割槽

CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT,
    store_id INT
)
PARTITION BY LIST(store_id) (
    PARTITION pNorth VALUES IN (3,5,6,9,17),
    PARTITION pEast VALUES IN (1,2,10,11,19,20),
    PARTITION pWest VALUES IN (4,12,13,14,18),
    PARTITION pCentral VALUES IN (7,8,15,16)
);

  3.多列分割槽

   多列分割槽有分為range分割槽和list分割槽

      多列range分割槽

mysql> CREATE TABLE rcx (
    ->     a INT,
    ->     b INT,
    ->     c CHAR(3),
    ->     d INT
    -> )
    -> PARTITION BY RANGE COLUMNS(a,d,c) (
    ->     PARTITION p0 VALUES LESS THAN (5,10,'ggg'),
    ->     PARTITION p1 VALUES LESS THAN (10,20,'mmm'),
    ->     PARTITION p2 VALUES LESS THAN (15,30,'sss'),
    ->     PARTITION p3 VALUES LESS THAN (MAXVALUE,MAXVALUE,MAXVALUE)
    -> );

  多列list分割槽

CREATE TABLE customers_1 (
    first_name VARCHAR(25),
    last_name VARCHAR(25),
    street_1 VARCHAR(30),
    street_2 VARCHAR(30),
    city VARCHAR(15),
    renewal DATE
)
PARTITION BY LIST COLUMNS(city) (
    PARTITION pRegion_1 VALUES IN('Oskarshamn', 'Högsby', 'Mönsterås'),
    PARTITION pRegion_2 VALUES IN('Vimmerby', 'Hultsfred', 'Västervik'),
    PARTITION pRegion_3 VALUES IN('Nässjö', 'Eksjö', 'Vetlanda'),
    PARTITION pRegion_4 VALUES IN('Uppvidinge', 'Alvesta', 'Växjo')

       4.Linear hash分割槽

CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT,
    store_id INT
)
PARTITION BY LINEAR HASH( YEAR(hired) )
PARTITIONS 4;

  5. Key分割槽

CREATE TABLE tm1 (
    s1 CHAR(32) PRIMARY KEY
)
PARTITION BY KEY(s1)
PARTITIONS 10;

  6.Sub分割槽

CREATE TABLE ts (id INT, purchased DATE)
    PARTITION BY RANGE( YEAR(purchased) )
    SUBPARTITION BY HASH( TO_DAYS(purchased) )
    SUBPARTITIONS 2 (
        PARTITION p0 VALUES LESS THAN (1990),
        PARTITION p1 VALUES LESS THAN (2000),
        PARTITION p2 VALUES LESS THAN MAXVALUE
    );

  7.對控制的處理

  range分割槽,null 分到最低的分割槽;

  list分割槽,如果包含null的列,則進去,否則會報錯,如下例項

mysql> CREATE TABLE ts1 (
    ->     c1 INT,
    ->     c2 VARCHAR(20)
    -> )
    -> PARTITION BY LIST(c1) (
    ->     PARTITION p0 VALUES IN (0, 3, 6),
    ->     PARTITION p1 VALUES IN (1, 4, 7),
    ->     PARTITION p2 VALUES IN (2, 5, 8)
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql> INSERT INTO ts1 VALUES (9, 'mothra');
ERROR 1504 (HY000): Table has no partition for value 9

mysql> INSERT INTO ts1 VALUES (NULL, 'mothra');
ERROR 1504 (HY000): Table has no partition for value NULL

  hash分割槽和key分割槽,null做0處理,示例如下:

mysql> INSERT INTO th VALUES (NULL, 'mothra'), (0, 'gigan');
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM th;
+------+---------+
| c1   | c2      |
+------+---------+
| NULL | mothra  |
+------+---------+
|    0 | gigan   |
+------+---------+
2 rows in set (0.01 sec)

  1.2 分割槽管理

  Range和list分割槽管理

          ALTER TABLE ... DROP PARTITION 刪除分割槽

     ALTER TABLE ... ADD PARTITION 增加分割槽

    ALTER TABLE ...REORGANIZE PARTITION 移動分割槽

  Hash和key分割槽管理

    不能通過DROP來刪除分割槽,可以ALTER TABLE ... COALESCE PARTITION來合併分割槽

     ALTER TABLE ... ADD PARTITION  增加分割槽

  表間的分割槽交換和子分割槽表的交換

    ALTER TABLE ... EXCHANGE PARTITION

  維護分割槽

    表的維護:CHECK TABLE,OPTIMIZE TABLE,ANALYZE TABLE, REPAIR TABLE

    分割槽的維護:ALTER TABLE ... 

            Rebuilding partitions
            Optimizing partitions
            Analyzing partitions
            Repairing partitions
            Checking partitions
            TRUNCATE PARTITION

       獲取分割槽資訊         

            SHOW CREATE TABLE
            SHOW TABLE STATUS
            INFORMATION_SCHEMA.PARTITIONS
            EXPLAIN SELECT

  1.3 小結

    從分割槽表的設計思想上來看,支援多張分割槽方式:range,list,多列,linear hash,key,sub分割槽

   另外,還提供對分割槽的管理。

2.分庫或者分表

   分割槽,分表,分庫解決的問題不一樣,但解決思路或者架構設計有相通的地方,我們可以借鑑分割槽表的設計思維來構建分表分庫的實現。

                                                            

 

 

  分割槽具有的功能:

  分割槽遮蔽的對使用者dml和select的細節,分表或者分庫db代理應該也可以實現,分表或者分庫db代理儲存db的元資料和對映情況,對使用者來說,應該遮蔽細節,不應該暴露給使用者

        分割槽的管理提供了相應的命令,分表或者分庫db代理也應該實現該功能

   分割槽不具有的功能:

     監控,日誌,視覺化等方面分割槽做的不夠,分表或者分庫db代理可以做的更好。

  想到了hadoop的hdfs架構設計

  

 

3.mycat的實現

  根據上面的思路,是否有響應的開源實現呢?找到一個比較相近的開源實現mycat:

  • 一個徹底開源的,面向企業應用開發的大資料庫叢集
  • 支援事務、ACID、可以替代MySQL的加強版資料庫
  • 一個可以視為MySQL叢集的企業級資料庫,用來替代昂貴的Oracle叢集
  • 一個融合記憶體快取技術、NoSQL技術、HDFS大資料的新型SQL Server
  • 結合傳統資料庫和新型分散式資料倉庫的新一代企業級資料庫產品
  • 一個新穎的資料庫中介軟體產品

總結:

  mycat在國內使用的不少,可以試用。如果想定製自己的mycat,可以參考mysql分割槽的實現和hadoop儲存hdfs的架構思想。 

參考資料:

【1】https://dev.mysql.com/doc/refman/8.0/en/partitioning-limitations-partitioning-keys-unique-keys.html

【2】http://www.mycat.io/