MySQLでSequence管理機能を追加
プロジェクトアプリケーションでは、次のようなシーンがありました.
インタフェースではintタイプの流水番号を送信する必要がありますが、マルチスレッドモードのため、タイムスタンプを使うと重複する場合があります(もちろん確率は小さいです).
そこで,独立した自己増加sequenceを用いてこの問題を解決することを考えた.
現在のデータベース:mysql
mysqlはoracleとは異なり、直接的なsequenceはサポートされていないため、sequenceの機能をシミュレートするためにtableを作成する必要があります.理由sql文は次のとおりです.
ステップ1:--Sequence管理テーブルの作成
ステップ2:作成--現在の値を取る関数
ステップ3:作成--次の値を取る関数
ステップ4:作成--現在の値を更新する関数
ステップ5:関数機能のテスト
上記の4つのステップが完了すると、作成するsequence名を以下のデータで設定し、初期値を設定し、現在の値と次の値を取得できます.
INSERT INTO sequence VALUES ('TestSeq', 0, 1);----sequence名と初期値を追加し、自己増幅SELECT SETVAL('TestSeq',10)---指定したsequenceの初期値SELECT CURRVAL('TestSeq');クエリ指定sequenceの現在値SELECT NEXTVAL('TestSeq');--クエリーsequenceの次の値を指定
Javaコードでは、sql文を直接作成して次の値をクエリーすることで、ストリーム番号の唯一の問題を解決できます.
一部のコードを貼り付けます(テストに合格しました)
ps:アプリケーションでは、javaコードを使用してシミュレーション自己増分sequenceを実装する方法もあります.具体的には、sequenceを格納するtableを作成し、java呼び出しsql文を使用して、このtableで指定したsequence名の値をクエリーおよび変更する方法です.synchronizedを追加してください.具体的なコードはここでアップロードしません.実現したので、テストしたことがありません.
インタフェースではintタイプの流水番号を送信する必要がありますが、マルチスレッドモードのため、タイムスタンプを使うと重複する場合があります(もちろん確率は小さいです).
そこで,独立した自己増加sequenceを用いてこの問題を解決することを考えた.
現在のデータベース:mysql
mysqlはoracleとは異なり、直接的なsequenceはサポートされていないため、sequenceの機能をシミュレートするためにtableを作成する必要があります.理由sql文は次のとおりです.
ステップ1:--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;
ステップ2:作成--現在の値を取る関数
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 ;
ステップ3:作成--次の値を取る関数
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 ;
ステップ4:作成--現在の値を更新する関数
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 ;
ステップ5:関数機能のテスト
上記の4つのステップが完了すると、作成する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を追加してください.具体的なコードはここでアップロードしません.実現したので、テストしたことがありません.