由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/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM