mysql分区

介绍

Mysql5.5只支持水平分区,还不支持垂直分区。
MySQL分区不能与使用 MERGE,CSV或 FEDERATED存储引擎。
分区适用于表的所有数据和索引; 您不能只分区数据而不分区索引,反之亦然,也不能只分区表的一部分。
通过分区,可以在一个表中存储比在单个磁盘或文件系统分区上保存的数据更多的数据。

查看当前数据库是否支持分区功能

查看当前数据库版本:

mysql> status
--------------
mysql  Ver 14.14 Distrib 5.7.24, for Linux (x86_64) using  EditLine wrapper

Connection id:      25
Current database:   
Current user:       root@localhost
SSL:            Not in use
Current pager:      stdout
Using outfile:      ''
Using delimiter:    ;
Server version:     5.7.24-log MySQL Community Server (GPL)
Protocol version:   10
Connection:     Localhost via UNIX socket
Server characterset:    latin1
Db     characterset:    latin1
Client characterset:    latin1
Conn.  characterset:    latin1
UNIX socket:        /var/lib/mysql/mysql.sock
Uptime:         3 days 23 hours 15 min 58 sec

Threads: 1  Questions: 167  Slow queries: 0  Opens: 125  Flush tables: 2  Open tables: 17  Queries per second avg: 0.000
--------------

查看当前数据库是否支持分区:

mysql> show plugins;
+----------------------------+----------+--------------------+----------------------+---------+
| Name                       | Status   | Type               | Library              | License |
+----------------------------+----------+--------------------+----------------------+---------+
| binlog                     | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| mysql_native_password      | ACTIVE   | AUTHENTICATION     | NULL                 | GPL     |
| sha256_password            | ACTIVE   | AUTHENTICATION     | NULL                 | GPL     |
| CSV                        | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| MEMORY                     | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| InnoDB                     | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| INNODB_TRX                 | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_LOCKS               | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_LOCK_WAITS          | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMP                 | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMP_RESET           | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMPMEM              | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMPMEM_RESET        | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMP_PER_INDEX       | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMP_PER_INDEX_RESET | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_BUFFER_PAGE         | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_BUFFER_PAGE_LRU     | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_BUFFER_POOL_STATS   | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_TEMP_TABLE_INFO     | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_METRICS             | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_DEFAULT_STOPWORD | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_DELETED          | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_BEING_DELETED    | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_CONFIG           | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_INDEX_CACHE      | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_INDEX_TABLE      | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_TABLES          | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_TABLESTATS      | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_INDEXES         | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_COLUMNS         | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_FIELDS          | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_FOREIGN         | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_FOREIGN_COLS    | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_TABLESPACES     | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_DATAFILES       | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SYS_VIRTUAL         | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| MyISAM                     | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| MRG_MYISAM                 | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| PERFORMANCE_SCHEMA         | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| ARCHIVE                    | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| BLACKHOLE                  | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| FEDERATED                  | DISABLED | STORAGE ENGINE     | NULL                 | GPL     |
| partition                  | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| ngram                      | ACTIVE   | FTPARSER           | NULL                 | GPL     |
| validate_password          | ACTIVE   | VALIDATE PASSWORD  | validate_password.so | GPL     |
+----------------------------+----------+--------------------+----------------------+---------+
45 rows in set (0.00 sec)

RANGE分区

确定行数据在某个给定连续区间的列值。然后放入该分区。

CREATE TABLE pt_range(
    id int(16) unsigned NOT NULL AUTO_INCREMENT,
    username VARCHAR(32) NOT NULL,
    pwd VARCHAR(32) NOT NULL,
    create_date datetime DEFAULT NULL,
    PRIMARY KEY (`id`)
) PARTITION BY RANGE(id) (
    PARTITION p0 VALUES LESS THAN (10),
    PARTITION p1 VALUES LESS THAN (20),
    PARTITION p2 VALUES LESS THAN (30),
    PARTITION p3 VALUES LESS THAN MAXVALUE
);

INSERT INTO pt_range(id, username, pwd, create_date)
VALUES (1, '张三', '123456', NOW()),
(2, '李四', '123456', NOW()),
(11, '张三', '123456', NOW()),
(21, '张三', '123456', NOW()),
(31, '张三', '123456', NOW());

查看分区中的各个分区文件:

mysql> system ls -lh /var/lib/mysql/sunpy/pt*
-rw-r----- 1 mysql mysql  96K Jan 16 11:38 /var/lib/mysql/sunpy/pt_range#P#p0.ibd
-rw-r----- 1 mysql mysql  96K Jan 16 11:36 /var/lib/mysql/sunpy/pt_range#P#p1.ibd
-rw-r----- 1 mysql mysql  96K Jan 16 11:36 /var/lib/mysql/sunpy/pt_range#P#p2.ibd
-rw-r----- 1 mysql mysql  96K Jan 16 11:36 /var/lib/mysql/sunpy/pt_range#P#p3.ibd
-rw-r----- 1 mysql mysql 8.5K Jan 16 11:21 /var/lib/mysql/sunpy/pt_range.frm

查看information_schema的PARTITIONS表下的每个分区的具体信息:

mysql> select * from information_schema.PARTITIONS WHERE table_schema=database() and table_name='pt_range'\G;
*************************** 1. row ***************************
                TABLE_CATALOG: def
                 TABLE_SCHEMA: sunpy
                   TABLE_NAME: pt_range
               PARTITION_NAME: p0
            SUBPARTITION_NAME: NULL
   PARTITION_ORDINAL_POSITION: 1
SUBPARTITION_ORDINAL_POSITION: NULL
             PARTITION_METHOD: RANGE
          SUBPARTITION_METHOD: NULL
         PARTITION_EXPRESSION: id
      SUBPARTITION_EXPRESSION: NULL
        PARTITION_DESCRIPTION: 10
                   TABLE_ROWS: 2
               AVG_ROW_LENGTH: 8192
                  DATA_LENGTH: 16384
              MAX_DATA_LENGTH: NULL
                 INDEX_LENGTH: 0
                    DATA_FREE: 0
                  CREATE_TIME: 2019-01-16 11:21:27
                  UPDATE_TIME: 2019-01-16 11:38:33
                   CHECK_TIME: NULL
                     CHECKSUM: NULL
            PARTITION_COMMENT: 
                    NODEGROUP: default
              TABLESPACE_NAME: NULL
*************************** 2. row ***************************
                TABLE_CATALOG: def
                 TABLE_SCHEMA: sunpy
                   TABLE_NAME: pt_range
               PARTITION_NAME: p1
            SUBPARTITION_NAME: NULL
   PARTITION_ORDINAL_POSITION: 2
SUBPARTITION_ORDINAL_POSITION: NULL
             PARTITION_METHOD: RANGE
          SUBPARTITION_METHOD: NULL
         PARTITION_EXPRESSION: id
      SUBPARTITION_EXPRESSION: NULL
        PARTITION_DESCRIPTION: 20
                   TABLE_ROWS: 1
               AVG_ROW_LENGTH: 16384
                  DATA_LENGTH: 16384
              MAX_DATA_LENGTH: NULL
                 INDEX_LENGTH: 0
                    DATA_FREE: 0
                  CREATE_TIME: 2019-01-16 11:21:27
                  UPDATE_TIME: 2019-01-16 11:36:14
                   CHECK_TIME: NULL
                     CHECKSUM: NULL
            PARTITION_COMMENT: 
                    NODEGROUP: default
              TABLESPACE_NAME: NULL
*************************** 3. row ***************************
                TABLE_CATALOG: def
                 TABLE_SCHEMA: sunpy
                   TABLE_NAME: pt_range
               PARTITION_NAME: p2
            SUBPARTITION_NAME: NULL
   PARTITION_ORDINAL_POSITION: 3
SUBPARTITION_ORDINAL_POSITION: NULL
             PARTITION_METHOD: RANGE
          SUBPARTITION_METHOD: NULL
         PARTITION_EXPRESSION: id
      SUBPARTITION_EXPRESSION: NULL
        PARTITION_DESCRIPTION: 30
                   TABLE_ROWS: 1
               AVG_ROW_LENGTH: 16384
                  DATA_LENGTH: 16384
              MAX_DATA_LENGTH: NULL
                 INDEX_LENGTH: 0
                    DATA_FREE: 0
                  CREATE_TIME: 2019-01-16 11:21:27
                  UPDATE_TIME: 2019-01-16 11:36:14
                   CHECK_TIME: NULL
                     CHECKSUM: NULL
            PARTITION_COMMENT: 
                    NODEGROUP: default
              TABLESPACE_NAME: NULL
*************************** 4. row ***************************
                TABLE_CATALOG: def
                 TABLE_SCHEMA: sunpy
                   TABLE_NAME: pt_range
               PARTITION_NAME: p3
            SUBPARTITION_NAME: NULL
   PARTITION_ORDINAL_POSITION: 4
SUBPARTITION_ORDINAL_POSITION: NULL
             PARTITION_METHOD: RANGE
          SUBPARTITION_METHOD: NULL
         PARTITION_EXPRESSION: id
      SUBPARTITION_EXPRESSION: NULL
        PARTITION_DESCRIPTION: MAXVALUE
                   TABLE_ROWS: 1
               AVG_ROW_LENGTH: 16384
                  DATA_LENGTH: 16384
              MAX_DATA_LENGTH: NULL
                 INDEX_LENGTH: 0
                    DATA_FREE: 0
                  CREATE_TIME: 2019-01-16 11:21:27
                  UPDATE_TIME: 2019-01-16 11:36:14
                   CHECK_TIME: NULL
                     CHECKSUM: NULL
            PARTITION_COMMENT: 
                    NODEGROUP: default
              TABLESPACE_NAME: NULL
4 rows in set (0.00 sec)

LIST分区

与分区相似RANGE,只是LIST分区面向的是离散的值。

CREATE TABLE pt_list(
    id int(16) unsigned NOT NULL AUTO_INCREMENT,
    username VARCHAR(32) NOT NULL,
    pwd VARCHAR(32) NOT NULL,
    create_date datetime DEFAULT NULL,
    PRIMARY KEY (`id`)
) PARTITION BY LIST(id) (
    PARTITION p0 VALUES IN (1, 3, 5, 7, 9),
  PARTITION p1 VALUES IN (2, 4, 6, 8, 10)
);

HASH分区

根据用户自定义的表达式的返回值来进行分区,返回值不能为负数。

CREATE TABLE pt(
    id int(16) unsigned NOT NULL AUTO_INCREMENT,
    username VARCHAR(32) NOT NULL,
    pwd VARCHAR(32) NOT NULL,
    create_date datetime DEFAULT NULL,
    PRIMARY KEY (`id`)
) PARTITION BY HASH(id) PARTITIONS 4;

KEY分区

根据mysql提供的hash函数来进行分区。

CREATE TABLE pt_key(
    id int(16) unsigned NOT NULL AUTO_INCREMENT,
    username VARCHAR(32) NOT NULL,
    pwd VARCHAR(32) NOT NULL,
    create_date datetime DEFAULT NULL,
    PRIMARY KEY (`id`)
) PARTITION BY KEY(id) PARTITIONS 2;

说明:KEY仅获取零个或多个列名称的列表。用作分区键的任何列必须包含表的主键的部分或全部,如果表有一个。如果没有将列名指定为分区键,则使用表的主键(如果有)。

分区操作

  1. 添加分区
ALTER TABLE pt_range ADD PARTITION (PARTITION p4 VALUES LESS THAN (2019));
  1. 删除分区
ALTER TABLE pt_range DROP PARTITION p4;

注意

  1. 删除分区的同时也会删除分区中的数据。
  2. 如果分区字段中必须包含所有的唯一索引列。
  3. 分区表达式不允许使用存储过程或存储函数。
  4. 分区表达式不允许使用声明的用户变量等。
  5. 分区的InnoDB不支持外键。
  6. RANGE分区对于Null值是存储在最左边的分区中。
  7. LIST分区对于Null值是必须显式指定在哪个分区,要不报错。

分区好处

我们知道分区特点就是将数据按照一定规则放到不同的区域中,而查询数据会先找数据放在哪个区域下,减少了无用的行记录的扫描。

你可能感兴趣的:(mysql分区)