標籤:舉例 載入 支援 func .com tin 序列 batch efi
一、全域序號
全域序號是MyCAT提供的一個新功能,為了實現分庫分表情況下,表的主鍵是全域唯一,而預設的MySQL的自增長主鍵無法滿足這個要求。全域序號的文法符合標準SQL規範,其格式為:
next value for MYCATSEQ_XXX
MYCATSEQ_XXX 是序號的名字,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
全域序號可通過多種方式提供
1)本地檔案
2) 資料庫方式:
3)本地時間戳記演算法:
1)本地檔案
1. 配置server.xml
<property name="sequnceHandlerType">0</property>
2. 配置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
使用樣本: insert into table1(id,name) values(next value for MYCATSEQ_GLOBAL,‘test’);
缺點:當 MyCAT 重新發布後,設定檔中的 sequence 會恢複到初始值。
優點:本地載入,讀取速度較快。
2) 資料庫方式:
1. 配置server.xml
<property name="sequnceHandlerType">1</property>
2. 配置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秒會重新從資料庫讀取下一批次的序號值。
3)本地時間戳記演算法:
ID= 64位二進位 (42(毫秒)+5(機器ID)+5(業務編碼)+12(重複累加)
換算成十進位為18位元的long類型,每毫秒可以並發12位二進位的累加。
使用方式:
a. 配置server.xml
<property name="sequnceHandlerType">2</property>
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定義自增
[[email protected] conf]# vim schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://org.opencloudb/">
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
<!-- random sharding using mod sharind rule -->
<!-- autoIncrement="true" 屬性-->
<table name="tt2" primaryKey="id" autoIncrement="true" dataNode="dn1,dn2,dn3,dn4,dn5" rule="mod-long" />
<table name="mycat_sequence" primaryKey="name" dataNode="dn1"/>
</schema>
<dataNode name="dn1" dataHost="localhost1" database="db1" />
<dataNode name="dn2" dataHost="localhost1" database="db2" />
<dataNode name="dn3" dataHost="localhost1" database="db3" />
<dataNode name="dn4" dataHost="localhost1" database="db4" />
<dataNode name="dn5" dataHost="localhost1" database="db5" />
<dataHost name="localhost1" maxCon="1000" minCon="20" balance="0" writeType="0" dbType="mysql" dbDriver="native">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="127.0.0.1:3366" user="root" password="123456">
</writeHost>
</dataHost>
</mycat:schema>
3、mycat對應sequence_db_conf.properties增加相應設定;
4、mycat的對應mycat_sequence增加對應記錄。
5、連結mycat,測試結果如下:
127.0.0.1/root:[TESTDB> insert into tt2(nm) values (99);
Query OK, 1 row affected (0.14 sec)
127.0.0.1/root:[TESTDB> select last_insert_id();
+------------------+
| LAST_INSERT_ID() |
+------------------+
| 101 |
+------------------+
1 row in set (0.01 sec)
關於批量插入使用:
如果沒有用mycat 的全域序號,是普通的批量插入 :
insert(a,b,c) values(x,x,x),(x,x,x);
如果用了全域序號必須加註解:
/*!mycat:catlet=demo.catlets.BatchInsertSequence */insert(a,b,c) values(x,x,x),(x,x,x);
是sharding key 必須包含在列枚舉中,特別是主鍵是自增的時候必須顯示調用:
/*!mycat:catlet=demo.catlets.BatchInsertSequence */insert(id,a,b,c) values(,next value for MYCATSEQ_ID,x,x,x),(next value for MYCATSEQ_ID,x,x,x);
mycat分布式mysql中介軟體(自增主鍵)