MYCAT 自建主键

本文介绍了MyCAT数据库中间件中的全局序列号机制,包括本地文件模式、数据库模式及基于时间戳算法的三种实现方式。此外,还详细阐述了如何通过自定义序列号来确保在分库分表场景下主键的全局唯一性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

全局序列号是MyCAT提供的一个新功能,为了实现分库分表情况下,表的主键是全局唯一,而默认的MySQL的自增长主键无法满足这个要求。全局序列号的语法符合标准SQL规范,其格式为:

next value for MYCATSEQ_GLOBAL

其中MYCATSEQ_GLOBAL是序列号的名字,MyCAT自动创建新的序列号,免去了开发的复杂度,另外,MyCAT也提供了一个全局的序列号,名称为:MYCATSEQ_GLOBAL。

注意,MYCATSEQ_必须大写才能正确识别。

MyCAT温馨提示:实践中,建议每个表用自己的序列号,序列号的命名建议为MYCATSEQ _tableName_ID_SEQ。

SQL中使用说明

自定义序列号的标识为:MYCATSEQ_XXX ,其中XXX为具体定义的sequence的名称,应用举例如下:

使用默认的全局sequence :

insert into tb1(id,name) values(next value for MYCATSEQ_GLOBAL,’micmiu.com’);

使用自定义的 sequence :

insert into tb2(id,name) values(next value for MYCATSEQ_MY1,’micmiu.com’);

获取最新的值

Select next value for MYCATSEQ_xxx

注意:

序列:MYCATSEQ_MYCAT

配置:MYCAT=dn1
表为:MYCAT 也就是”表名“=序列号后半部分的名字(MYCATSEQ_xxx 中的xxx)

目前全局序列号提供了本地文件跟数据库模式及本地基于时间戳算法的三种方式:

  1. 本地文件:

  2. 配置server.xml
    0

  3. 配置sequence_conf.properties

    default global sequence

    GLOBAL.HISIDS=
    GLOBAL.MINID=10001
    GLOBAL.MAXID=20000
    GLOBAL.CURID=10000

    self define sequence

    COMPANY.HISIDS=
    COMPANY.MINID=1001
    COMPANY.MAXID=2000
    COMPANY.CURID=1000
    测试:

  4. 数据库方式:

  5. 配置server.xml
    1

  6. 配置sequence_db_conf.properties
    #sequence stored in datanode
    GLOBAL=dn1
    MYST=dn1

3.数据库本地创建脚本:
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 100, PRIMARY KEY (name) ) ENGINE=InnoDB;


– Function structure for mycat_seq_currval


DROP FUNCTION IF EXISTS mycat_seq_currval;
DELIMITER ;;
CREATE DEFINER=root@% FUNCTION mycat_seq_currval(seq_name VARCHAR(50)) RETURNS varchar(64) CHARSET latin1
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 ;


– Function structure for mycat_seq_nextval


DROP FUNCTION IF EXISTS mycat_seq_nextval;
DELIMITER ;;
CREATE DEFINER=root@% FUNCTION mycat_seq_nextval(seq_name VARCHAR(50)) RETURNS varchar(64) CHARSET latin1
DETERMINISTIC
BEGIN
UPDATE MYCAT_SEQUENCE
SET current_value = current_value + increment WHERE name = seq_name;
RETURN mycat_seq_currval(seq_name);
END
;;
DELIMITER ;


– Function structure for mycat_seq_setval


DROP FUNCTION IF EXISTS mycat_seq_setval;
DELIMITER ;;
CREATE DEFINER=root@% FUNCTION mycat_seq_setval(seq_name VARCHAR(50), value INTEGER) RETURNS varchar(64) CHARSET latin1
DETERMINISTIC
BEGIN
UPDATE MYCAT_SEQUENCE
SET current_value = value
WHERE name = seq_name;
RETURN mycat_seq_currval(seq_name);
END
;;
DELIMITER ;
INSERT INTO MYCAT_SEQUENCE VALUES (‘GLOBAL’, 0, 100);
SELECT MYCAT_SEQ_SETVAL(‘GLOBAL’, 1);
SELECT MYCAT_SEQ_CURRVAL(‘GLOBAL’);
SELECT MYCAT_SEQ_NEXTVAL(‘GLOBAL’);
4.插入序列数据:
INSERT INTO MYCAT_SEQUENCE VALUES (‘GLOBAL’, 0, 100);
INSERT INTO MYCAT_SEQUENCE VALUES (‘GLOBAL’, 0, 100);
脚本下载:/attached/file/20150323/20150323175900_382.txt
说明:

• 在某个分区(dataNode)数据库上创建序列号相关的表格和函数,SQL脚本在doc目录下的sequnce-sql.txt中,需要在数据库上而非Mycat上执行。
• Mycat_home/conf/quence_db_conf.properties 中记录了sequnce所存放的db对应的配置信息。

sequence stored in datanode

GLOBAL=dn1
COMPANY=dn1
CUSTOMER=dn1
• 在sequnce表中,插入相应的sequnce记录,并确定其初始值,以及增长步长,步长建议一个合适的范围,比如50-500,需要在数据库上而非Mycat上执行。
INSERT INTO MYCAT_SEQUENCE VALUES (‘GLOBAL’, 0, 100);
• 修改sequnce的当前值为某个新值,需要在数据库上而非Mycat上执行。
SELECT mycat_seq_curval(‘GLOBAL’);

提示:步长选择多大,取决与你数据插入的TPS,假如是每秒1000个,则步长为1000×60=6万,也不是很大,即60秒会重新从数据库读取下一批次的序列号值。

测试:

  1. 本地时间戳算法:

ID= 64位二进制 (42(毫秒)+5(机器ID)+5(业务编码)+12(重复累加)

换算成十进制为18位数的long类型,每毫秒可以并发12位二进制的累加。

使用方式:

a. 配置server.xml

2

b. 在mycat下配置:sequence_time_conf.properties

       WORKID=0-31 任意整数

       DATAACENTERID=0-31 任意整数

多个个mycat节点下每个mycat配置的 WORKID,DATAACENTERID不同,组成唯一标识,总共支持32*32=1024种组合。

ID示例:56763083475511

自增主键配置:

     从MyCAT 1.3开始,支持自增长主键,依赖于全局序列号机制,建议采用数据库方式的全局序列号,并正确设置步长,以免影响实际性能。

     首先要开启数据库方式的全局序列号,对于需要定义自增长主键的表,建立对应的全局序列号,与table名称同名大写,

     如customer序列名为CUSTOMER,然后再 schema.xml 中对customer表的table元素增加属性autoIncrement值为true.

    <table name=”CUSTOMER”  autoIncrement=”true”>

执行insert into customer (name,company_id,sharding_id) values (‘test’,2,10000);查看效果,

暂不支持主键为null如:insert into customer (id,name,company_id,sharding_id) values (null,’test’,2,10000);

应用获得自增主键:

MyCAT自增字段和返回生成的主键ID的经验分享
说明:
1、mysql本身对非自增长主键,使用last_insert_id()是不会返回结果的,只会返回0.
2、mysql只会对定义自增长主键,可以用last_insert_id()返回主键值。

mycat目前提供了自增长主键功能,但是如果对应的mysql节点上数据表,没有定义auto_increment,
那么在mycat层调用last_insert_id()也是不会返回结果的。
正确使用方式如下:

1、mysql定义自增主键
CREATE TABLE tt2 (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
nm INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (id)
) ENGINE=MYISAM AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
2、mycat定义自增
[root@test conf]# vim schema.xml

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值