データを挿入する
このドキュメントでは、さまざまなプログラミング言語でSQL言語を使用してTiDBにデータを挿入する方法について説明します。
始める前に
この文書を読む前に、以下のものを準備してください。
行を挿入する
複数の行のデータを挿入する方法は2つあります。たとえば、 3人の選手のデータを挿入する必要がある場合などです。
複数行挿入ステートメント:
INSERT INTO `player` (`id`, `coins`, `goods`) VALUES (1, 1000, 1), (2, 230, 2), (3, 300, 5);複数の単一行挿入ステートメント:
INSERT INTO `player` (`id`, `coins`, `goods`) VALUES (1, 1000, 1); INSERT INTO `player` (`id`, `coins`, `goods`) VALUES (2, 230, 2); INSERT INTO `player` (`id`, `coins`, `goods`) VALUES (3, 300, 5);
一般的にmulti-line insertion statementは、複数のsingle-line insertion statementsよりも高速に動作します。
CREATE TABLE `player` (`id` INT, `coins` INT, `goods` INT);
INSERT INTO `player` (`id`, `coins`, `goods`) VALUES (1, 1000, 1), (2, 230, 2);
この SQL の使用方法の詳細については、 TiDB Cloud Starterインスタンスに接続しますを参照し、クライアントを使用してTiDB Cloud Starterインスタンスに接続した後、SQL ステートメントを入力する手順に従ってください。
// ds is an entity of com.mysql.cj.jdbc.MysqlDataSource
try (Connection connection = ds.getConnection()) {
connection.setAutoCommit(false);
PreparedStatement pstmt = connection.prepareStatement("INSERT INTO player (id, coins, goods) VALUES (?, ?, ?)"))
// first player
pstmt.setInt(1, 1);
pstmt.setInt(2, 1000);
pstmt.setInt(3, 1);
pstmt.addBatch();
// second player
pstmt.setInt(1, 2);
pstmt.setInt(2, 230);
pstmt.setInt(3, 2);
pstmt.addBatch();
pstmt.executeBatch();
connection.commit();
} catch (SQLException e) {
e.printStackTrace();
}
MySQL JDBCDriverのデフォルト設定では、一括挿入のパフォーマンスを向上させるために、いくつかのパラメータを変更する必要があります。
MySQL JDBCDriverは、 useConfigsという統合構成も提供しています。 maxPerformanceで構成すると、一連の構成を構成するのと同等になります。 mysql:mysql-connector-java:8.0.28を例にとると、 useConfigs=maxPerformanceには以下が含まれます。
cachePrepStmts=true
cacheCallableStmts=true
cacheServerConfiguration=true
useLocalSessionState=true
elideSetAutoCommits=true
alwaysSendSetIsolation=false
enableQueryTimeouts=false
connectionAttributes=none
useInformationSchema=true
mysql-connector-java-{version}.jar!/com/mysql/cj/configurations/maxPerformance.propertiesを確認すると、対応するバージョンの MySQL JDBCDriverのuseConfigs=maxPerformanceに含まれる設定を取得できます。
以下は、JDBC接続文字列構成の典型的なシナリオです。この例では、ホスト: 127.0.0.1 、ポート: 4000 、ユーザー名: root 、パスワード: null、デフォルトデータベース: test :
jdbc:mysql://127.0.0.1:4000/test?user=root&useConfigs=maxPerformance&useServerPrepStmts=true&prepStmtCacheSqlLimit=2048&prepStmtCacheSize=256&rewriteBatchedStatements=true&allowMultiQueries=true
Javaでの完全な例については、以下を参照してください。
package main
import (
"database/sql"
"strings"
_ "github.com/go-sql-driver/mysql"
)
type Player struct {
ID string
Coins int
Goods int
}
func bulkInsertPlayers(db *sql.DB, players []Player, batchSize int) error {
tx, err := db.Begin()
if err != nil {
return err
}
stmt, err := tx.Prepare(buildBulkInsertSQL(batchSize))
if err != nil {
return err
}
defer stmt.Close()
for len(players) > batchSize {
if _, err := stmt.Exec(playerToArgs(players[:batchSize])...); err != nil {
tx.Rollback()
return err
}
players = players[batchSize:]
}
if len(players) != 0 {
if _, err := tx.Exec(buildBulkInsertSQL(len(players)), playerToArgs(players)...); err != nil {
tx.Rollback()
return err
}
}
if err := tx.Commit(); err != nil {
tx.Rollback()
return err
}
return nil
}
func playerToArgs(players []Player) []interface{} {
var args []interface{}
for _, player := range players {
args = append(args, player.ID, player.Coins, player.Goods)
}
return args
}
func buildBulkInsertSQL(amount int) string {
return "INSERT INTO player (id, coins, goods) VALUES (?, ?, ?)" + strings.Repeat(",(?,?,?)", amount-1)
}
Golangでの完全な例については、以下を参照してください。
import MySQLdb
connection = MySQLdb.connect(
host="127.0.0.1",
port=4000,
user="root",
password="",
database="bookshop",
autocommit=True
)
with get_connection(autocommit=True) as connection:
with connection.cursor() as cur:
player_list = random_player(1919)
for idx in range(0, len(player_list), 114):
cur.executemany("INSERT INTO player (id, coins, goods) VALUES (%s, %s, %s)", player_list[idx:idx + 114])
Pythonでの完全な例については、以下を参照してください。
バルク挿入
TiDBに大量のデータを迅速にインポートする必要がある場合は、 PingCAPが提供するデータ移行ツール群を使用することをお勧めします。 INSERTステートメントを使用する方法は、効率が悪く、例外処理やその他の問題を自分で処理する必要があるため、最適な方法ではありません。
大量挿入に推奨されるツールは以下のとおりです。
- データエクスポート: Dumplingを使用して、MySQLまたはTiDBデータをローカルストレージまたはクラウドstorageにエクスポートします。TiDB Cloud StarterまたはEssentialインスタンスの場合は、 TiDB Cloudコンソールの輸出機能を使用して、より効率的にデータをエクスポートすることもできます。
- データのインポート: TiDB Cloudコンソールの輸入機能を使用します。 Dumplingでエクスポートしたデータをインポートしたり、ローカルの CSV ファイルをインポートしたり、クラウドstorageからCSVファイルをTiDB Cloudにインポートすることができます。
- データレプリケーション: TiDB CloudコンソールのTiDBデータ移行機能を使用します。 MySQL 互換データベースを TiDB にレプリケートできます。また、ソースデータベースからのシャーディングされたインスタンスとテーブルのマージおよび移行もサポートしています。
- データのバックアップと復元: TiDB Cloudコンソールのバックアップ機能を使用します。 Dumplingと比較して、バックアップと復元はビッグ データのシナリオにより適しています。
- データエクスポート: Dumpling 。MySQLまたはTiDBのデータをローカルまたはAmazon S3にエクスポートできます。
- データインポート: TiDB Lightning 。 Dumplingでエクスポートされたデータ、 CSVファイル、 Amazon AuroraからTiDBへのデータ移行をインポートできます。ローカル ディスクまたは Amazon S3 クラウド ディスクからのデータの読み取りもサポートします。
- データレプリケーション: TiDBデータ移行MySQL、MariaDB、Amazon AuroraデータベースをTiDBにレプリケートできます。また、ソースデータベースからのシャーディングされたインスタンスとテーブルのマージおよび移行もサポートしています。
- データのバックアップと復元:バックアップと復元 (BR) 。 Dumplingと比較して、 BRはビッグデータのシナリオにより適しています。
ホットスポットは避ける
テーブルを設計するときは、多数の挿入操作があるかどうかを考慮する必要があります。その場合、テーブルの設計中にホットスポットを回避する必要があります。 主キーを選択セクションを参照し、 主キーを選択する際のルールに従ってください。
TiDB セルフマネージドでホットスポットの問題を処理する方法の詳細については、ホットスポットの問題をトラブルシューティングする。
AUTO_RANDOMを主キーとするテーブルにデータを挿入する
挿入するテーブルの主キーにAUTO_RANDOM属性がある場合、デフォルトでは主キーを指定できません。たとえば、 bookshopデータベースでは、 usersテーブルのidフィールドにAUTO_RANDOM属性が含まれていることがわかります。
この場合、以下のようなSQLを使用して挿入することはできません。
INSERT INTO `bookshop`.`users` (`id`, `balance`, `nickname`) VALUES (1, 0.00, 'nicky');
エラーが発生します:
ERROR 8216 (HY000): Invalid auto random: Explicit insertion on auto_random column is disabled. Try to set @@allow_auto_random_explicit_insert = true.
挿入時にAUTO_RANDOM列を手動で指定することは推奨されません。
このエラーに対処するには、2つの解決策があります。
(推奨)挿入ステートメントからこの列を削除し、TiDB が初期化した
AUTO_RANDOMの値を使用してください。これはAUTO_RANDOMのセマンティクスに適合します。INSERT INTO `bookshop`.`users` (`balance`, `nickname`) VALUES (0.00, 'nicky');この列を指定する必要があることが確実な場合は、
SETステートメント使用できます。 ユーザー変数を変更することで、挿入時にAUTO_RANDOMの列を指定できるようにします。SET @@allow_auto_random_explicit_insert = true; INSERT INTO `bookshop`.`users` (`id`, `balance`, `nickname`) VALUES (1, 0.00, 'nicky');
HTAPを使用する
TiDB では、HTAP 機能により、データの挿入時に追加の操作を実行する必要がなくなります。追加の挿入ロジックはありません。 TiDB はデータの一貫性を自動的に保証します。必要なのは、テーブルの作成後に列指向レプリカ同期を有効にする、列指向レプリカを使用してクエリを直接高速化することだけです。
お困りですか?
- 不和or スラックコミュニティに質問してください。
- TiDB Cloudのサポートチケットを送信してください
- TiDB Self-Managedのサポートチケットを送信してください