- TiDBについて
- クイックスタート
- 発展させる
- 概要
- クイックスタート
- TiDB Cloud(開発者層) で TiDB クラスターを構築する
- TiDB の CRUD SQL
- TiDB でシンプルな CRUD アプリを構築する
- 応用例
- TiDB に接続する
- データベース スキーマの設計
- 書き込みデータ
- データの読み取り
- 取引
- 最適化
- トラブルシューティング
- 参照
- 書店のサンプル アプリケーション
- ガイドライン
- アーカイブされたドキュメント
- クラウドネイティブ開発環境
- サードパーティのサポート
- デプロイ
- 移行する
- 管理
- 監視と警告
- トラブルシューティング
- TiDB トラブルシューティング マップ
- 遅いクエリを特定する
- 遅いクエリを分析する
- SQL 診断
- Top SQLを使用して高価なクエリを特定する
- ログを使用して高価なクエリを特定する
- ステートメント要約表
- ホットスポットの問題のトラブルシューティング
- 増加した読み取りおよび書き込み遅延のトラブルシューティング
- クラスターのオンサイト情報の保存と復元
- クラスタ セットアップのトラブルシューティング
- 高いディスク I/O 使用率のトラブルシューティング
- ロック競合のトラブルシューティング
- TiFlash のトラブルシューティング
- オプティミスティック トランザクションでの書き込み競合のトラブルシューティング
- データとインデックス間の不一致のトラブルシューティング
- 性能チューニング
- チューニングガイド
- Configuration / コンフィグレーションのチューニング
- システムのチューニング
- ソフトウェアのチューニング
- Configuration / コンフィグレーション
- コプロセッサ キャッシュ
- SQL チューニング
- チュートリアル
- TiDB ツール
- 概要
- ユースケース
- ダウンロード
- TiUP
- ドキュメンテーション マップ
- 概要
- 用語と概念
- TiUP コンポーネントの管理
- FAQ
- トラブルシューティングガイド
- コマンドリファレンス
- 概要
- TiUP コマンド
- TiUP クラスタ コマンド
- 概要
- tiup cluster audit
- tiup cluster check
- tiup cluster clean
- tiup cluster deploy
- tiup cluster destroy
- tiup cluster disable
- tiup cluster display
- tiup cluster edit-config
- tiup cluster enable
- tiup cluster help
- tiup cluster import
- tiup cluster list
- tiup cluster patch
- tiup cluster prune
- tiup cluster reload
- tiup cluster rename
- tiup cluster replay
- tiup cluster restart
- tiup cluster scale-in
- tiup cluster scale-out
- tiup cluster start
- tiup cluster stop
- tiup cluster template
- tiup cluster upgrade
- TiUP DMコマンド
- TiDB クラスター トポロジ リファレンス
- DM クラスタ トポロジ リファレンス
- ミラー リファレンス ガイド
- TiUP コンポーネント
- PingCAPクリニック診断サービス
- TiDB Operator
- Dumpling
- TiDB Lightning
- TiDB データ移行
- バックアップと復元 (BR)
- Binlog
- TiCDC
- Dumpling
- 同期差分インスペクター
- ティスパーク
- 参照
- クラスタ アーキテクチャ
- 主な監視指標
- セキュリティ
- 権限
- SQL
- SQL 言語の構造と構文
- SQL ステートメント
ADD COLUMN
ADD INDEX
ADMIN
ADMIN CANCEL DDL
ADMIN CHECKSUM TABLE
ADMIN CHECK [TABLE|INDEX]
ADMIN SHOW DDL [JOBS|QUERIES]
ADMIN SHOW TELEMETRY
ALTER DATABASE
ALTER INDEX
ALTER INSTANCE
ALTER PLACEMENT POLICY
ALTER TABLE
ALTER TABLE COMPACT
ALTER USER
ANALYZE TABLE
BACKUP
BATCH
BEGIN
CHANGE COLUMN
COMMIT
CHANGE DRAINER
CHANGE PUMP
CREATE [GLOBAL|SESSION] BINDING
CREATE DATABASE
CREATE INDEX
CREATE PLACEMENT POLICY
CREATE ROLE
CREATE SEQUENCE
CREATE TABLE LIKE
CREATE TABLE
CREATE USER
CREATE VIEW
DEALLOCATE
DELETE
DESC
DESCRIBE
DO
DROP [GLOBAL|SESSION] BINDING
DROP COLUMN
DROP DATABASE
DROP INDEX
DROP PLACEMENT POLICY
DROP ROLE
DROP SEQUENCE
DROP STATS
DROP TABLE
DROP USER
DROP VIEW
EXECUTE
EXPLAIN ANALYZE
EXPLAIN
FLASHBACK TABLE
FLUSH PRIVILEGES
FLUSH STATUS
FLUSH TABLES
GRANT <privileges>
GRANT <role>
INSERT
KILL [TIDB]
LOAD DATA
LOAD STATS
MODIFY COLUMN
PREPARE
RECOVER TABLE
RENAME INDEX
RENAME TABLE
REPLACE
RESTORE
REVOKE <privileges>
REVOKE <role>
ROLLBACK
SELECT
SET DEFAULT ROLE
SET [NAMES|CHARACTER SET]
SET PASSWORD
SET ROLE
SET TRANSACTION
SET [GLOBAL|SESSION] <variable>
SHOW ANALYZE STATUS
SHOW [BACKUPS|RESTORES]
SHOW [GLOBAL|SESSION] BINDINGS
SHOW BUILTINS
SHOW CHARACTER SET
SHOW COLLATION
SHOW [FULL] COLUMNS FROM
SHOW CONFIG
SHOW CREATE PLACEMENT POLICY
SHOW CREATE SEQUENCE
SHOW CREATE TABLE
SHOW CREATE USER
SHOW DATABASES
SHOW DRAINER STATUS
SHOW ENGINES
SHOW ERRORS
SHOW [FULL] FIELDS FROM
SHOW GRANTS
SHOW INDEX [FROM|IN]
SHOW INDEXES [FROM|IN]
SHOW KEYS [FROM|IN]
SHOW MASTER STATUS
SHOW PLACEMENT
SHOW PLACEMENT FOR
SHOW PLACEMENT LABELS
SHOW PLUGINS
SHOW PRIVILEGES
SHOW [FULL] PROCESSSLIST
SHOW PROFILES
SHOW PUMP STATUS
SHOW SCHEMAS
SHOW STATS_HEALTHY
SHOW STATS_HISTOGRAMS
SHOW STATS_META
SHOW STATUS
SHOW TABLE NEXT_ROW_ID
SHOW TABLE REGIONS
SHOW TABLE STATUS
SHOW [FULL] TABLES
SHOW [GLOBAL|SESSION] VARIABLES
SHOW WARNINGS
SHUTDOWN
SPLIT REGION
START TRANSACTION
TABLE
TRACE
TRUNCATE
UPDATE
USE
WITH
- データ型
- 関数と演算子
- クラスタ化インデックス
- 制約
- 生成された列
- SQL モード
- テーブル属性
- 取引
- ガベージ コレクション (GC)
- ビュー
- パーティショニング
- 一時テーブル
- キャッシュされたテーブル
- 文字セットと照合順序
- SQL の配置規則
- システム テーブル
mysql
- 情報_スキーマ
- 概要
ANALYZE_STATUS
CLIENT_ERRORS_SUMMARY_BY_HOST
CLIENT_ERRORS_SUMMARY_BY_USER
CLIENT_ERRORS_SUMMARY_GLOBAL
CHARACTER_SETS
CLUSTER_CONFIG
CLUSTER_HARDWARE
CLUSTER_INFO
CLUSTER_LOAD
CLUSTER_LOG
CLUSTER_SYSTEMINFO
COLLATIONS
COLLATION_CHARACTER_SET_APPLICABILITY
COLUMNS
DATA_LOCK_WAITS
DDL_JOBS
DEADLOCKS
ENGINES
INSPECTION_RESULT
INSPECTION_RULES
INSPECTION_SUMMARY
KEY_COLUMN_USAGE
METRICS_SUMMARY
METRICS_TABLES
PARTITIONS
PLACEMENT_POLICIES
PROCESSLIST
REFERENTIAL_CONSTRAINTS
SCHEMATA
SEQUENCES
SESSION_VARIABLES
SLOW_QUERY
STATISTICS
TABLES
TABLE_CONSTRAINTS
TABLE_STORAGE_STATS
TIDB_HOT_REGIONS
TIDB_HOT_REGIONS_HISTORY
TIDB_INDEXES
TIDB_SERVERS_INFO
TIDB_TRX
TIFLASH_REPLICA
TIKV_REGION_PEERS
TIKV_REGION_STATUS
TIKV_STORE_STATUS
USER_PRIVILEGES
VIEWS
METRICS_SCHEMA
- UI
- TiDB ダッシュボード
- 概要
- 管理
- アクセス
- 概要ページ
- クラスター情報ページ
- Top SQLページ
- キー ビジュアライザー ページ
- メトリクス関係グラフ
- SQL ステートメントの分析
- スロークエリページ
- クラスタ診断
- 検索ログ ページ
- インスタンスのプロファイリング
- セッションの管理とConfiguration / コンフィグレーション
- FAQ
- CLI
- コマンド ライン フラグ
- Configuration / コンフィグレーションファイルのパラメーター
- システム変数
- ストレージ エンジン
- テレメトリー
- エラーコード
- テーブル フィルター
- トポロジ ラベルごとにレプリカをスケジュールする
- よくある質問
- リリースノート
- すべてのリリース
- リリースのタイムライン
- TiDB のバージョニング
- v6.1
- v6.0
- v5.4
- v5.3
- v5.2
- v5.1
- v5.0
- v4.0
- v3.1
- v3.0
- v2.1
- v2.0
- v1.0
- 用語集
データの更新
このドキュメントでは、次の SQL ステートメントを使用して、さまざまなプログラミング言語で TiDB のデータを更新する方法について説明します。
- アップデート : 指定されたテーブルのデータを変更するために使用されます。
- 重複キーの更新時に挿入 : データを挿入し、主キーまたは一意のキーの競合がある場合にこのデータを更新するために使用されます。複数の一意のキー (主キーを含む) がある場合、このステートメントを使用することはお勧めしません。これは、一意のキー (主キーを含む) の競合が検出されると、このステートメントがデータを更新するためです。複数の行の競合がある場合、1 つの行のみを更新します。
始める前に
このドキュメントを読む前に、次の準備が必要です。
- TiDB Cloud(開発者層) で TiDB クラスターを構築する .
- スキーマ設計の概要 、 データベースを作成する 、 テーブルを作成する 、およびセカンダリ インデックスの作成を読んでください。
- データを
UPDATE
にしたい場合は、最初にデータを挿入するにする必要があります。
UPDATE
を使用する
テーブル内の既存の行を更新するには、 UPDATE
ステートメント句とWHERE
句を使用して、更新する列をフィルター処理する必要があります。
ノート:
多数の行 (たとえば、1 万行以上) を更新する必要がある場合は、一度に完全な更新を行うのではなく、すべての行が更新されるまで、一度に一部ずつ繰り返し更新することをお勧めします。この操作をループするスクリプトまたはプログラムを作成できます。詳細は一括更新を参照してください。
UPDATE
SQL 構文
SQL では、 UPDATE
ステートメントは通常、次の形式になります。
UPDATE {table} SET {update_column} = {update_value} WHERE {filter_column} = {filter_value}
パラメータ名 | 説明 |
---|---|
{table} | テーブル名 |
{update_column} | 更新するカラム名 |
{update_value} | 更新するカラムの値 |
{filter_column} | フィルターに一致するカラム名 |
{filter_value} | フィルタに一致するカラムの値 |
詳細については、 UPDATE 構文を参照してください。
UPDATE
のベスト プラクティス
以下は、データを更新するためのいくつかのベスト プラクティスです。
UPDATE
文には必ずWHERE
節を指定してください。UPDATE
ステートメントにWHERE
句がない場合、TiDB はテーブル内のすべての行を更新します。- 多数の行 (たとえば、1 万行以上) を更新する必要がある場合は、 一括更新を使用します。 TiDB は 1 つのトランザクションのサイズを制限しているため (デフォルトではtxn-合計サイズ制限 MB)、一度に多くのデータを更新すると、ロックが長時間保持されたり ( 悲観的な取引 )、競合が発生したりします ( 楽観的な取引 )。
UPDATE
例
著者が名前をHelen Harukiに変更したとします。 著者テーブルを変更する必要があります。彼女の一意のid
が1で、フィルターがid = 1
であるとします。
- SQL
- Java
UPDATE `authors` SET `name` = "Helen Haruki" WHERE `id` = 1;
// ds is an entity of com.mysql.cj.jdbc.MysqlDataSource
try (Connection connection = ds.getConnection()) {
PreparedStatement pstmt = connection.prepareStatement("UPDATE `authors` SET `name` = ? WHERE `id` = ?");
pstmt.setString(1, "Helen Haruki");
pstmt.setInt(2, 1);
pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
INSERT ON DUPLICATE KEY UPDATE
を使用する
新しいデータをテーブルに挿入する必要があるが、一意のキー (主キーも一意のキー) が競合している場合、最初に競合したレコードが更新されます。 INSERT ... ON DUPLICATE KEY UPDATE ...
のステートメントを使用して挿入または更新できます。
INSERT ON DUPLICATE KEY UPDATE
SQL 構文
SQL では、 INSERT ... ON DUPLICATE KEY UPDATE ...
ステートメントは通常、次の形式になります。
INSERT INTO {table} ({columns}) VALUES ({values})
ON DUPLICATE KEY UPDATE {update_column} = {update_value};
パラメータ名 | 説明 |
---|---|
{table} | テーブル名 |
{columns} | 挿入するカラム名 |
{values} | 挿入するカラムの値 |
{update_column} | 更新するカラム名 |
{update_value} | 更新するカラムの値 |
INSERT ON DUPLICATE KEY UPDATE
のベスト プラクティス
- 一意のキーが 1 つのテーブルにのみ
INSERT ON DUPLICATE KEY UPDATE
を使用します。 UNIQUE KEY (主キーを含む) の競合が検出された場合、このステートメントはデータを更新します。競合の行が複数ある場合は、1 つの行のみが更新されます。したがって、競合する行が 1 行だけであることを保証できない限り、複数の一意のキーを持つテーブルでINSERT ON DUPLICATE KEY UPDATE
ステートメントを使用することはお勧めしません。 - データを作成または更新するときに、このステートメントを使用します。
INSERT ON DUPLICATE KEY UPDATE
例
たとえば、書籍に対するユーザーの評価を含めるように評価テーブルを更新する必要があります。ユーザーがまだ書籍を評価していない場合は、新しい評価が作成されます。ユーザーが既に評価している場合、以前の評価が更新されます。
次の例では、主キーはbook_id
とuser_id
の結合主キーです。ユーザuser_id = 1
は本book_id = 1000
に5
の評価を与える。
- SQL
- Java
INSERT INTO `ratings`
(`book_id`, `user_id`, `score`, `rated_at`)
VALUES
(1000, 1, 5, NOW())
ON DUPLICATE KEY UPDATE `score` = 5, `rated_at` = NOW();
// ds is an entity of com.mysql.cj.jdbc.MysqlDataSource
try (Connection connection = ds.getConnection()) {
PreparedStatement p = connection.prepareStatement("INSERT INTO `ratings` (`book_id`, `user_id`, `score`, `rated_at`)
VALUES (?, ?, ?, NOW()) ON DUPLICATE KEY UPDATE `score` = ?, `rated_at` = NOW()");
p.setInt(1, 1000);
p.setInt(2, 1);
p.setInt(3, 5);
p.setInt(4, 5);
p.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
一括更新
テーブル内の複数行のデータを更新する必要がある場合は、 INSERT ON DUPLICATE KEY UPDATE
を使用するとWHERE
句を使用して、更新が必要なデータをフィルター処理できます。
ただし、多数の行 (たとえば、1 万行以上) を更新する必要がある場合は、データを繰り返し更新することをお勧めします。つまり、更新が完了するまで、各繰り返しでデータの一部のみを更新します。 .これは、TiDB がtxn-合計サイズ制限つのトランザクションのサイズを制限しているためです (デフォルトでは 1、100 MB)。一度に多くのデータを更新すると、ロックが長時間保持される ( 悲観的な取引 、または競合が発生する ( 楽観的な取引 ) ) ことになります。プログラムまたはスクリプトでループを使用して、操作を完了することができます。
このセクションでは、反復的な更新を処理するスクリプトの記述例を示します。この例は、一括更新を完了するためにSELECT
とUPDATE
の組み合わせを実行する方法を示しています。
一括更新ループを書く
まず、アプリケーションまたはスクリプトのループにSELECT
クエリを記述する必要があります。このクエリの戻り値は、更新が必要な行の主キーとして使用できます。このSELECT
クエリを定義するときは、 WHERE
句を使用して、更新が必要な行をフィルタリングする必要があることに注意してください。
例
過去 1 年間にbookshop
の Web サイトで多くのユーザーから本の評価があったとしますが、元のデザインの 5 段階スケールでは、本の評価に違いがありませんでした。ほとんどの本の評価は3
です。評価を差別化するために、5 点満点から 10 点満点に切り替えることにしました。
前の 5 ポイント スケールのratings
テーブルのデータに2
を掛け、評価テーブルに新しい列を追加して、行が更新されたかどうかを示す必要があります。この列を使用すると、 SELECT
で更新された行を除外できます。これにより、スクリプトがクラッシュして複数回行を更新し、不合理なデータが生成されるのを防ぐことができます。
たとえば、10 ポイント スケールかどうかの識別子としてデータ型ブールを使用して、 ten_point
という名前の列を作成します。
ALTER TABLE `bookshop`.`ratings` ADD COLUMN `ten_point` BOOL NOT NULL DEFAULT FALSE;
ノート:
この一括更新アプリケーションは、 DDLステートメントを使用して、データ テーブルにスキーマの変更を加えます。 TiDB のすべての DDL 変更操作はオンラインで実行されます。詳細については、 列を追加を参照してください。
- Golang
- Java (JDBC)
Golang では、一括更新アプリケーションは次のようになります。
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
"strings"
"time"
)
func main() {
db, err := sql.Open("mysql", "root:@tcp(127.0.0.1:4000)/bookshop")
if err != nil {
panic(err)
}
defer db.Close()
bookID, userID := updateBatch(db, true, 0, 0)
fmt.Println("first time batch update success")
for {
time.Sleep(time.Second)
bookID, userID = updateBatch(db, false, bookID, userID)
fmt.Printf("batch update success, [bookID] %d, [userID] %d\n", bookID, userID)
}
}
// updateBatch select at most 1000 lines data to update score
func updateBatch(db *sql.DB, firstTime bool, lastBookID, lastUserID int64) (bookID, userID int64) {
// select at most 1000 primary keys in five-point scale data
var err error
var rows *sql.Rows
if firstTime {
rows, err = db.Query("SELECT `book_id`, `user_id` FROM `bookshop`.`ratings` " +
"WHERE `ten_point` != true ORDER BY `book_id`, `user_id` LIMIT 1000")
} else {
rows, err = db.Query("SELECT `book_id`, `user_id` FROM `bookshop`.`ratings` "+
"WHERE `ten_point` != true AND `book_id` > ? AND `user_id` > ? "+
"ORDER BY `book_id`, `user_id` LIMIT 1000", lastBookID, lastUserID)
}
if err != nil || rows == nil {
panic(fmt.Errorf("error occurred or rows nil: %+v", err))
}
// joint all id with a list
var idList []interface{}
for rows.Next() {
var tempBookID, tempUserID int64
if err := rows.Scan(&tempBookID, &tempUserID); err != nil {
panic(err)
}
idList = append(idList, tempBookID, tempUserID)
bookID, userID = tempBookID, tempUserID
}
bulkUpdateSql := fmt.Sprintf("UPDATE `bookshop`.`ratings` SET `ten_point` = true, "+
"`score` = `score` * 2 WHERE (`book_id`, `user_id`) IN (%s)", placeHolder(len(idList)))
db.Exec(bulkUpdateSql, idList...)
return bookID, userID
}
// placeHolder format SQL place holder
func placeHolder(n int) string {
holderList := make([]string, n/2, n/2)
for i := range holderList {
holderList[i] = "(?,?)"
}
return strings.Join(holderList, ",")
}
各反復で、主キーの順序でSELECT
のクエリ。 10 ポイント スケール ( ten_point
はfalse
) に更新されていない最大1000
行の主キー値を選択します。各SELECT
ステートメントは、重複を防ぐために、前のSELECT
個の結果の最大のものよりも大きい主キーを選択します。次に、一括更新を使用し、 score
列を2
で乗算し、 ten_point
をtrue
に設定します。 ten_point
を更新する目的は、クラッシュ後の再起動時に、更新アプリケーションが同じ行を繰り返し更新するのを防ぐことです。これにより、データが破損する可能性があります。各ループでtime.Sleep(time.Second)
を指定すると、更新アプリケーションが 1 秒間一時停止し、更新アプリケーションがハードウェア リソースを消費しすぎるのを防ぎます。
Java (JDBC) では、一括更新アプリケーションは次のようになります。
コード:
package com.pingcap.bulkUpdate;
import com.mysql.cj.jdbc.MysqlDataSource;
import java.sql.*;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class BatchUpdateExample {
static class UpdateID {
private Long bookID;
private Long userID;
public UpdateID(Long bookID, Long userID) {
this.bookID = bookID;
this.userID = userID;
}
public Long getBookID() {
return bookID;
}
public void setBookID(Long bookID) {
this.bookID = bookID;
}
public Long getUserID() {
return userID;
}
public void setUserID(Long userID) {
this.userID = userID;
}
@Override
public String toString() {
return "[bookID] " + bookID + ", [userID] " + userID ;
}
}
public static void main(String[] args) throws InterruptedException {
// Configure the example database connection.
// Create a mysql data source instance.
MysqlDataSource mysqlDataSource = new MysqlDataSource();
// Set server name, port, database name, username and password.
mysqlDataSource.setServerName("localhost");
mysqlDataSource.setPortNumber(4000);
mysqlDataSource.setDatabaseName("bookshop");
mysqlDataSource.setUser("root");
mysqlDataSource.setPassword("");
UpdateID lastID = batchUpdate(mysqlDataSource, null);
System.out.println("first time batch update success");
while (true) {
TimeUnit.SECONDS.sleep(1);
lastID = batchUpdate(mysqlDataSource, lastID);
System.out.println("batch update success, [lastID] " + lastID);
}
}
public static UpdateID batchUpdate (MysqlDataSource ds, UpdateID lastID) {
try (Connection connection = ds.getConnection()) {
UpdateID updateID = null;
PreparedStatement selectPs;
if (lastID == null) {
selectPs = connection.prepareStatement(
"SELECT `book_id`, `user_id` FROM `bookshop`.`ratings` " +
"WHERE `ten_point` != true ORDER BY `book_id`, `user_id` LIMIT 1000");
} else {
selectPs = connection.prepareStatement(
"SELECT `book_id`, `user_id` FROM `bookshop`.`ratings` "+
"WHERE `ten_point` != true AND `book_id` > ? AND `user_id` > ? "+
"ORDER BY `book_id`, `user_id` LIMIT 1000");
selectPs.setLong(1, lastID.getBookID());
selectPs.setLong(2, lastID.getUserID());
}
List<Long> idList = new LinkedList<>();
ResultSet res = selectPs.executeQuery();
while (res.next()) {
updateID = new UpdateID(
res.getLong("book_id"),
res.getLong("user_id")
);
idList.add(updateID.getBookID());
idList.add(updateID.getUserID());
}
if (idList.isEmpty()) {
System.out.println("no data should update");
return null;
}
String updateSQL = "UPDATE `bookshop`.`ratings` SET `ten_point` = true, "+
"`score` = `score` * 2 WHERE (`book_id`, `user_id`) IN (" +
placeHolder(idList.size() / 2) + ")";
PreparedStatement updatePs = connection.prepareStatement(updateSQL);
for (int i = 0; i < idList.size(); i++) {
updatePs.setLong(i + 1, idList.get(i));
}
int count = updatePs.executeUpdate();
System.out.println("update " + count + " data");
return updateID;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public static String placeHolder(int n) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n ; i++) {
sb.append(i == 0 ? "(?,?)" : ",(?,?)");
}
return sb.toString();
}
}
hibernate.cfg.xml
構成:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="hibernate.dialect">org.hibernate.dialect.TiDBDialect</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:4000/movie</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password"></property>
<property name="hibernate.connection.autocommit">false</property>
<property name="hibernate.jdbc.batch_size">20</property>
<!-- Optional: Show SQL output for debugging -->
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
</session-factory>
</hibernate-configuration>
各反復で、主キーの順序でSELECT
のクエリ。 10 ポイント スケール ( ten_point
はfalse
) に更新されていない最大1000
行の主キー値を選択します。各SELECT
ステートメントは、重複を防ぐために、前のSELECT
個の結果の最大のものよりも大きい主キーを選択します。次に、一括更新を使用し、 score
列を2
で乗算し、 ten_point
をtrue
に設定します。 ten_point
を更新する目的は、クラッシュ後の再起動時に、更新アプリケーションが同じ行を繰り返し更新するのを防ぐことです。これにより、データが破損する可能性があります。各ループでTimeUnit.SECONDS.sleep(1);
を指定すると、更新アプリケーションが 1 秒間一時停止し、更新アプリケーションがハードウェア リソースを消費しすぎるのを防ぎます。