使用说明

本文将详细介绍多主分区表的使用说明。

背景信息

PolarDB MySQL版的多主分区表是一种全新的云原生数据库,它支持自动水平拆分、混合共享存储以及shared nothing架构。同时,能够根据预设的拆分规则,将数据自动分散到多个数据库集群中,从而使每个节点均具备读写能力,实现真正的分布式处理能力。

通过水平拆分,PolarDB能够有效地实现数据库的横向扩展,线性提升整体的并发吞吐能力。同时,多主分区表的架构还结合了共享存储数据库按需资源分配的优势,确保资源利用率的最大化。

前提条件

DDL语句

CREATE DATABASE

CREATE DATABASE语句用于创建数据库,并允许指定数据库的默认属性,如默认字符集和校验规则等。其语法与MySQL完全兼容。此外,您可以使用DIST_DB={'Y' | 'N'}来指示所创建的数据库是否支持分库模式的多主分区表,其中默认为'N'

说明

多主集群分区表目前不支持普通库转DIST_DB属性库。

语法

CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name
[create_option] ...
create_option: [DEFAULT] {
CHARACTER SET [=] charset_name
| COLLATE [=] collation_name
| ENCRYPTION [=] {'Y' | 'N'}
| DIST_DB [=] {'Y' | 'N'}
}

示例

创建数据库test1,允许在test1库中创建分库模式的多主分区表,分库数默认是8。

CREATE DATEBASE test1 DIST_DB='Y';

CREATE TABLE

分库模式

CREATE TABLE语句用于创建表。对于标识为DIST_DB='Y'的数据库,仅能创建分库模式的多主分区表。使用新的关键字DBDISTRIBUTION来指定多主分区表的分布方式。目前,分库的数量固定为8个。

语法

CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
    (create_definition,...)
    [table_options]
    [dbdistribution_options]

dbdistribution_options:
    DBDISTRIBUTION BY
        { [LINEAR] HASH(expr)
        | [LINEAR] KEY [ALGORITHM={1 | 2}] (column_list)
        | RANGE{(expr) | COLUMNS(column_list)}
        | LIST{(expr) | COLUMNS(column_list)} }
    [(dbdistribution_definition [, dbdistribution_definition] ...)]

dbdistribution_definition:
    DBDISTRIBUTION distribution_name
        [VALUES
            {LESS THAN {(expr | value_list) | MAXVALUE}
            |
            IN (value_list)}]
        [[STORAGE] ENGINE [=] engine_name]
        [COMMENT [=] 'string' ]
        [DATA DIRECTORY [=] 'data_dir']
        [INDEX DIRECTORY [=] 'index_dir']
        [MAX_ROWS [=] max_number_of_rows]
        [MIN_ROWS [=] min_number_of_rows]
        [TABLESPACE [=] tablespace_name]

示例:

  • 单库单表
CREATE database test;
CREATE TABLE t1(
 id bigint NOT NULL, 
 name varchar(30), 
 PRIMARY key(id)
);
    支持分库模式的多主分区表
使用哈希函数做拆分

创建一张多主分区表,共分为8个分库,采用ID列进行哈希拆分,分库将分布在集群的各个节点中。

CREATE TABLE dist1(
 id bigint NOT NULL, 
 c1 int, 
 c2 varchar(30), 
 PRIMARY key(id)
) dbdistribution BY hash(id);
LIST分片

list是枚举值列表的集合,可以满足枚举分片的需求。在list分片中,使用DBDISTRIBUTION BY LIST(expr)来进行定义,其中expr是expression的缩写,表示一个列的值或基于列值的表达式,要求expr返回整数值。然后,可以通过VALUES IN (value_list)定义每个分片,其中value_list是以逗号分隔的整数值列表。

CREATE TABLE t1 (
    id INT NOT NULL,
    store_id INT,
    partion_no INT,
    PRIMARY key(id, partion_no)
) DBDISTRIBUTION BY LIST(partion_no) (
  DBDISTRIBUTION a VALUES IN (1),
  DBDISTRIBUTION b VALUES IN (2)
);
LIST-COLUMNS分片

list column分片与list分片非常相似,使用DBDISTRIBUTION BY LIST COLUMNS(column_list)来定义,其中column_list可以是一个或多个列名,不再是表达式。事实上columns()不允许使用除列名以外的其他表达式。list columns分片不再局限于整数列,适用的类型包括:

  • 所有整数类型:TINYINT、SMALLINT、MEDIUMINT、INT(INTEGER) 和BIGINT。

  • 其他数值类型:例如DECIMAL和FLOAT不支持。

  • 日期类型:DATE和DATETIME。

  • 字符串类型:CHAR、VARCHAR、BINARY和VARBINARY。不支持TEXT和BLOB。

CREATE TABLE t3 (
    id INT NOT NULL,
    store_id INT,
    partion_no varchar(20),
    PRIMARY key(id, partion_no)
) DBDISTRIBUTION BY LIST COLUMNS (partion_no) (
  DBDISTRIBUTION a values in ('id_1'),
  DBDISTRIBUTION b values in ('id_2')
);

ALTER TABLE

兼容MySQL语法,更多详细信息请参见MySQL官方网站

CREATE INDEX

兼容MySQL语法,更多详细信息请参见MySQL官方网站

分布式查询

对于不带分布式键过滤条件的SQL查询或跨多个分库或分表的SQL查询,可以将其路由到全局只读节点会自动汇聚所有分区的数据,可以读取所有数据,无需额外的存储和同步链路。

全局自增列

支持全局唯一的序列(sequence),能够生成自然数序列的值,但不保证这些值是连续的或单调递增的。采用批量分配的方式,主节点(master)每次会分配一段值。因此,当多个主节点同时插入数据时,生成的自增ID可能会出现不连续的情况。在每次从存储引擎获取一个批次时,首先获取当前最后一个已分配的ID,然后再获取一个批次的ID,以确定一个范围(range)。

CREATE TABLE t1( id int NOT NULL auto_increment, c1 int, c2 int, PRIMARY key(id, c1)) tbdistribution BY RANGE (c1) ( tbdistribution p0 VALUES less than (100), tbdistribution p1 VALUES less than (1000), tbdistribution p2 VALUES less than (10000), tbdistribution p3 VALUES less than (20000) );
Query OK, 0 rows affected (0.26 sec)

INSERT INTO t1 (c1, c2) VALUES (1, 1);
Query OK, 1 row affected (0.04 sec)

MySQL单机特性

多主分区表使用序列(sequence)

每个表一个自增列

支持。

自增列上要有索引

不支持自增列同时作为分布式键(否则每次插入时需要显式提供自增列值),但支持唯一索引。

不指定列值的记录插入

支持。

指定列值的记录插入

仅支持指定的列值在本地序列范围之内,否则需要依赖全局索引进行重复判定。

全局唯一单调递增

支持全局唯一性,并且在分区内保持单调递增。

序列有空洞

序列存在空洞。

修改自增计数器

支持。

说明

需要使各本地节点的序列缓存失效。

自增列值更新

不支持。

说明

当前实现与指定列值的记录插入行为一致。

开发限制

以下限制仅针对多主分区表:

SQL语法

操作

使用约束

DDL

新建表名不能包含__mt__。

不支持子分区。

ALTER TABLE {DISCARD|IMPORT} TABLESPACE。

不支持。

ALTER TABLE PARTITION BY...。

不支持。

ALTER TABLE{DATA|INDEX} DIRECTORY='absolute path to directory'

不支持。

ALTER TABLE TABLESPACE tablespace_name [STORAGE {DISK|MEMORY}] 。

不支持。

ALTER TABLE ADD {FULLTEXT|SPATIAL} 。

不支持。

ALTER TABLE ADD[INDEX|KEY][index_name](key_part,...)[index_option]。

不支持。

CREATE VIEW|DROP VIEW

CREATE TRIGGER|PROCEDUREFUNCTIONEVENT

不支持。

DML

INSERT INTO SELECT

不支持。

嵌套NEXTVAL的语法。

例如:INSERT INTO tb(id) VALUES(SEQ1.NEXTVAL + 1);

不支持

包含列名的语法。

例如:INSERT INTO t1(id, name) VALUES (2, id + 1);

不支持。

跨分库的语句。

不支持。

DQL

跨分库的语句。

路由到全局只读(RO)节点。

游标。

不支持。

多主分区表和普通表JOIN。

路由到全局只读(RO)节点。

事务

分布式事务。

不支持。