前言
在实现分库分表的情况下,数据库自增主键已无法保证自增主键的全局唯一。为此,MyCat 提供了全局sequence,并且提供了包含本地配置和数据库配置等多种实现方式。
一、本地文件方式
在 servler.xml 文件中配置 sequnceHandlerType = 0
在 conf/sequence_conf.properties 中维护主键信息
如果想要每个表生成的主键连续,可以在 sequence_conf.properties 配置当前表的生成值,一般将 Global 替换为自己对应的前缀即可 (三个地方) 。
取值的时候通过 next value for MYCATSEQ_XXXX 获取。
二、时间戳方式
sequnceHandlerType=2
这种方式,需要将主键设置为 varchar 类型,长度一般 20
三、数据库方式
这里是数据库方式生成主键 ID,不是采用数据库的主键自增,而是 MyCat 利用 MySQL 数据库生成一个主键。
A、在数据库中创建一张表,三个函数
DROP TABLE IF EXISTS MYCAT_SEQUENCE;
CREATE TABLE MYCAT_SEQUENCE (
name VARCHAR(50) NOT NULL,
current_value INT NOT NULL,
increment INT NOT NULL DEFAULT 1,
PRIMARY KEY(name)
) ENGINE=InnoDB default charset=utf8;
INSERT INTO MYCAT_SEQUENCE(name,current_value,increment) VALUES ("GLOBAL", 0, 100);
DROP FUNCTION IF EXISTS mycat_seq_currval;
DELIMITER //
CREATE FUNCTION mycat_seq_currval(seq_name VARCHAR(50))
RETURNS varchar(64) CHARSET utf8
DETERMINISTIC
BEGIN
DECLARE retval VARCHAR(64);
SET retval="-999999999,null";
SELECT concat(CAST(current_value AS CHAR),",",CAST(increment AS CHAR)) INTO retval FROM MYCAT_SEQUENCE WHERE name = seq_name;
RETURN retval;
END //
DELIMITER ;
DROP FUNCTION IF EXISTS mycat_seq_setval;
DELIMITER //
CREATE FUNCTION mycat_seq_setval(seq_name VARCHAR(50),value INTEGER)
RETURNS varchar(64) CHARSET utf8
DETERMINISTIC
BEGIN
UPDATE MYCAT_SEQUENCE
SET current_value = value
WHERE name = seq_name;
RETURN mycat_seq_currval(seq_name);
END //
DELIMITER ;
DROP FUNCTION IF EXISTS mycat_seq_nextval;
DELIMITER //
CREATE FUNCTION mycat_seq_nextval(seq_name VARCHAR(50)) RETURNS varchar(64) CHARSET utf8
DETERMINISTIC
BEGIN
UPDATE MYCAT_SEQUENCE
SET current_value = current_value + increment WHERE name = seq_name;
RETURN mycat_seq_currval(seq_name);
END //
DELIMITER ;
B、server.xml 配置
<property name="sequnceHandlerType">1</property>
注:sequnceHandlerType 需要配置为1,表示使用数据库方式生成 sequence
C、sequence_db_conf.properties 配置
指定 sequence 相关配置在哪个节点上,例如我们如果在 p2p-admin 上创建的生成主键的表,那么根据我们在 schema.xml 文件中的配置,对应的节点应该是 dn2,所以在 sequence_db_conf.properties 中配置的 GLOBAL 应该就是 dn2
GLOBAL=dn2
D、插入时怎么用
insert into tb1(id,name) values(next value for MYCATSEQ_GLOBAL,"test");