1、oracel可以直接支援sequence,但是mysql不支援sequence,因此我們要通過模擬sequence的方法在mysql中建立sequence。
模擬sequence的方法:
專案場景:
專案應用中,曾有以下一個場景:
介面中要求傳送一個int型別的流水號,由於多執行緒模式,如果用時間戳,可能會有重複的情況(當然概率很小)。
所以想到了利用一個獨立的自增的sequence來解決該問題。
當前資料庫為:mysql
由於mysql和oracle不太一樣,不支援直接的sequence,所以需要建立一張table來模擬sequence的功能,sql語句如下:
第一步:建立--Sequence 管理表
DROP TABLE IF EXISTS sequence;
CREATE TABLE sequence (
name VARCHAR(50) NOT NULL,
current_value INT NOT NULL,
increment INT NOT NULL DEFAULT 1,
PRIMARY KEY (name)
) ENGINE=InnoDB;
第二步:建立--取當前值的函式
DROP FUNCTION IF EXISTS currval;
DELIMITER $
CREATE FUNCTION currval (seq_name VARCHAR(50))
RETURNS INTEGER
LANGUAGE SQL
DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE value INTEGER;
SET value = 0;
SELECT current_value INTO value
FROM sequence
WHERE name = seq_name;
RETURN value;
END
$
DELIMITER ;
第三步:建立--取下一個值的函式
DROP FUNCTION IF EXISTS nextval;
DELIMITER $
CREATE FUNCTION nextval (seq_name VARCHAR(50))
RETURNS INTEGER
LANGUAGE SQL
DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
UPDATE sequence
SET current_value = current_value + increment
WHERE name = seq_name;
RETURN currval(seq_name);
END
$
DELIMITER ;
第四步:建立--更新當前值的函式
DROP FUNCTION IF EXISTS setval;
DELIMITER $
CREATE FUNCTION setval (seq_name VARCHAR(50), value INTEGER)
RETURNS INTEGER
LANGUAGE SQL
DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
UPDATE sequence
SET current_value = value
WHERE name = seq_name;
RETURN currval(seq_name);
END
$
DELIMITER ;
第五步:測試函式功能
當上述四步完成後,可以用以下資料設定需要建立的sequence名稱以及設定初始值和獲取當前值和下一個值。
INSERT INTO sequence VALUES ('TestSeq', 0, 1);----新增一個sequence名稱和初始值,以及自增幅度
SELECT SETVAL('TestSeq', 10);---設定指定sequence的初始值
SELECT CURRVAL('TestSeq');--查詢指定sequence的當前值
SELECT NEXTVAL('TestSeq');--查詢指定sequence的下一個值
在java程式碼中,可直接建立sql語句查詢下一個值,這樣就解決了流水號唯一的問題。
貼出部分程式碼(已測試通過)
public void testGetSequence() {
Connection conn = JDBCUtils.getConnection(url, userName, password);
String sql = "SELECT CURRVAL('TestSeq');";
PreparedStatement ptmt = null;
ResultSet rs = null;
try {
ptmt = conn.prepareStatement(sql);
rs = ptmt.executeQuery();
int count = 0;
while (rs.next()) {
count = rs.getInt(1);
}
System.out.println(count);
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCUtils.close(rs, ptmt, conn);
}
}
ps:在應用中,還有一種用java程式碼去實現模擬自增sequence的方式,具體思路是建立一張存放sequence的table,然後通過java呼叫sql語句去查詢和修改這個table中指定sequence名稱的值,這種方式請加上synchronized。具體程式碼這裡就不上傳了,因為實現了,未去測試過。
【轉】MySQL中增加sequence管理功能(模擬建立sequence)
相關文章
- 在MySQL中建立實現自增的序列(Sequence)MySql
- sequence to sequence模型模型
- mysql實現sequenceMySql
- Sequence 批量更改與建立
- Oracle中Sequence的使用Oracle
- ORACLE SEQUENCEOracle
- Sequence recognition
- Redis實現sequence功能自增idRedis
- oracle中sequence使用的限制Oracle
- ORACLE SEQUENCE用法Oracle
- PostgreSQL 序列(Sequence)SQL
- PostgreSQL sequence (一)SQL
- Oracle - Sequence序列Oracle
- Oracle Sequence NocacheOracle
- Oracle序列sequenceOracle
- Oracle中sequence cache的測試Oracle
- Oracle中sequence的使用方法Oracle
- 論文閱讀:Sequence to sequence learning for joint extraction of entities and relations
- python sequence序列Python
- 3. Swift SequenceSwift
- Oracle之Sequence(序列)Oracle
- request gap sequence is FailedAI
- ACM Longest Repeated SequenceACM
- Oracle Sequence Audses$研究Oracle
- oracle sequence語法Oracle
- oracle sequence 試用Oracle
- 詳解序列(sequence)
- 裁剪序列Cut the Sequence
- F - Two Sequence Queries
- E. Block SequenceBloC
- Increasing Sequence with Fixed OR
- Rainbow Bracket SequenceAIRacket
- Oracle建立自增欄位方法-ORACLE SEQUENCE的簡單介紹(轉帖)Oracle
- oracle的scn及sequenceOracle
- Linux_Arithmetic_SequenceLinux
- DeepLearning – Overview of Sequence modelView
- Overview of the Sequence Generator (192)View
- Oracle 基本操作之 建立自增欄位方法-ORACLE SEQUENCEOracle