Mycat之数据库主键自增长(数据库增长的方式)-yellowcong

我们先来通过mycat实现一个自增长的主键,现在有两个数据库,mycat和mycat2,然后设定数据库增长的方式,按照自增长的方式实现。自增长实现步骤:1、创建数据库,2、创建mycat的自增长函数,3、插入需要自增长策略,4、配置schemal.xml,添加自增长的表,5、配置server.xml,设置主键增长策略,6、配置sequence_db_conf.properties,添加需要自增长的表。 如果我们后期想添加自增长的表,只需要进行步骤3、4、6 三个步骤。

数据准备

1、创建数据库

创建两个数据库,并都创建test表

#创建数据库
create database mycat;

#添加表
use mycat 
#创建表test
create table test3(id int auto_increment primary key,name varchar(32)) ;

#创建数据库
create database mycat3;

#添加表
use mycat 2
#创建表test
create table test3(id int auto_increment primary key,name varchar(32)) ;

Mycat之数据库主键自增长(数据库增长的方式)-yellowcong_第1张图片

添加后的表数据,看了一下,表示表建立好了
这里写图片描述

2、创建Mycat生成唯一主键所需要的函数

我将自增长的函数都创建在了mycat这个db中

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 ;


INSERT INTO MYCAT_SEQUENCE(NAME,current_value,increment) VALUES ('GLOBAL', 100000, 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_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 ;


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 ;

3、测试添加结果

#查询当前所在db ,这个语句只是想给大家证明,我是在mycat 这个数据库里面添加的函数
select database();

#查询doubi这张表里面的数据
select mycat_seq_nextval('doubi');

Mycat之数据库主键自增长(数据库增长的方式)-yellowcong_第2张图片

4、插入要自增的表名称到MYCAT_SEQUENC表

插入数据的时候,一定要注意,自己需要插入的表,一定要是大写的

#设定TEST3表的增长方式为 步进为1 ,
insert into MYCAT_SEQUENCE (name,current_value,increment) values ('TEST3',0,1);

#查询结果
 select * from MYCAT_SEQUENCE;

Mycat之数据库主键自增长(数据库增长的方式)-yellowcong_第3张图片

配置maycat

1、配置schemal.xml

vim conf/schemal.xml, 数据库的表名称为test2,设定表的主键,这样mycat好给我们生成主键,而且我们是自增长,所以需要配置autoIncrement="true",这个里面 type="global" 表示是全局的表, 每个子节点,都会存在



<mycat:schema xmlns:mycat="http://io.mycat/">

        <schema name="yellowcong" checkSQLschema="true" sqlMaxLimit="1000">
                <table name="test3" dataNode="jdbc_node1,jdbc_node2" primaryKey="id" autoIncrement="true"  type="global"/>
        schema>

        <dataNode name="jdbc_node1" dataHost="localhost" database="mycat" />
        <dataNode name="jdbc_node2" dataHost="localhost" database="mycat2" />

        <dataHost name="localhost" maxCon="1000" minCon="10" balance="0"
                          writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
                <heartbeat>select user()heartbeat>

                <writeHost host="hostM1" url="127.0.0.1:3306" user="root" password="root" />

        dataHost>


mycat:schema>

2、配置server.xml

需要修改sequnceHandlerType 为1,1

vim conf/server.xml

0 表示是表示使用本地文件方式。
1 表示的是根据数据库来生成,就是我们自己配置的自增长
2 表示时间戳的方式 ID= 64 位二进制 (42(毫秒)+5(机器 ID)+5(业务编码)+12(重复累加)
<property name="sequnceHandlerType">1property>

下面是全部配置




<mycat:server xmlns:mycat="http://io.mycat/">
        <system>
        <property name="serverPort">8066property>
        <property name="useSqlStat">0property>  
        <property name="useGlobleTableCheck">0property>  

                <property name="sequnceHandlerType">1property>

                
                <property name="processorBufferPoolType">0property>

                
                <property name="handleDistributedTransactions">0property>

                        
                <property name="useOffHeapForMerge">1property>

                
                <property name="memoryPageSize">1mproperty>

                
                <property name="spillsFileBufferSize">1kproperty>

                <property name="useStreamOutput">0property>

                
                <property name="systemReserveMemorySize">384mproperty>


                
                <property name="useZKSwitch">trueproperty>
        system>

        <user name="root">
                <property name="password">rootproperty>
                <property name="schemas">yellowcongproperty>
        user>

        <user name="user">
                <property name="password">userproperty>
                <property name="schemas">yellowcongproperty>
                <property name="readOnly">trueproperty>
        user>

mycat:server>

3、配置sequence_db_conf.properties

#配置默认的表自增长设置
vim ./conf/sequence_db_conf.properties

#添加需要自增长的表名称
TEST3=jdbc_node1

Mycat之数据库主键自增长(数据库增长的方式)-yellowcong_第4张图片

测试插入数据

重启mycat服务后,连接数据库,测试插入数据到TEST3表

#连接mycat
mysql -h 127.0.0.1 -P 8066 -u root -proot

#使用yellowocng 数据库
use yellowcong ;

#查看表信息
show tables ;

#插入数据
#插入多条数据
insert into test3 (name) values ('doubi1'),('doubi2'),('doubi3'),('yellowcong');

#查询数据
select * from test3;

Mycat之数据库主键自增长(数据库增长的方式)-yellowcong_第5张图片

查询数据,结果可以看到,角标的增长很完美。是增长的步进是1.
Mycat之数据库主键自增长(数据库增长的方式)-yellowcong_第6张图片

查看子节点,可以看到对mycat操作后,由于是全局表,所以每个子节点数据中,都存在表信息。
Mycat之数据库主键自增长(数据库增长的方式)-yellowcong_第7张图片

错误集合

ERROR 1064 (HY000): bad insert sql (sharding column:ID not provided,INSERT INTO test2 (NULL, ‘doubi1’)

包这个问题的原因很明显,就是我们没有设置mycat中虚拟表的id自增,所以导致没有获取到id,所以导致了这个问题。

这里写图片描述

#修改后的语句
insert into test2(name) values('doubi1'),('doubi2'),('doubi3'),('yellowcong');

ERROR 1064 (HY000): insert must provide ColumnList

必须提供添加的列,直接插入,导致了问题,所以我们需要修该插入语句
这里写图片描述

#原来语句
insert into test2 (null,'doubi1'),(null,'doubi2'),(null,'doubi3'),(null,'yellowcong');

#修改后的语句
insert into test2(name) values('doubi1'),('doubi2'),('doubi3'),('yellowcong');

Out of range value for column ‘id’ at row 1

导致这个问题的大致原因可能是由于mycat生成的id和数据库的字符长度对不上,超过了数据库配置的默认长度所导致的。解决办法,就是修改数server.xml,设定id生成策略是根据数据库生成的。
这里写图片描述

vim conf/server.xml

0 表示是表示使用本地文件方式。
1 表示的是根据数据库来生成
2 表示时间戳的方式 ID= 64 位二进制 (42(毫秒)+5(机器 ID)+5(业务编码)+12(重复累加)
<property name="sequnceHandlerType">1property>

Mycat之数据库主键自增长(数据库增长的方式)-yellowcong_第8张图片

mycat sequnce err.io.mycat.config.util.ConfigException: can’t find definition for sequence :TEST2

mycat对应sequence_db_conf.properties增加相应设置
这里写图片描述

#配置默认的表自增长设置
vim ./conf/sequence_db_conf.properties

#添加需要自增长的表名称
TEST3=jdbc_node1

Mycat之数据库主键自增长(数据库增长的方式)-yellowcong_第9张图片

mycat sequnce err.java.lang.RuntimeException: can’t fetch sequnce in db,sequnce :TEST2

报错,说没办法获取到 id,从数据库中,这个说明我们sequence_db_conf.properties 的配置文件有问题
这里写图片描述

mycat sequnce err.java.lang.RuntimeException: can’t fetch sequnce in db,sequnce :TEST2 detail:FUNCTION mycat.mycat_seq_nextval does not exist

说没有mycat.mycat_seq_nextval 这个函数,说明在rule.xml中还需要添加这个配置
这里写图片描述

#添加表
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 ;


INSERT INTO MYCAT_SEQUENCE(name,current_value,increment) VALUES ('GLOBAL', 100000, 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_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 ;


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 ;




#插入一条数据,这条数据是我们这个表所需要的。
#必须是大写的字符,不然就会报错
#插入需要自增张的表的策略
insert into  MYCAT_SEQUENCE (name,current_value,increment) values ('TEST3',0,1);

参考文章

http://www.linuxidc.com/Linux/2016-01/127829.htm

你可能感兴趣的:(数据库中间件)