MySQL
インサート
サーチ…
構文
INSERT [LOW_PRIORITY |遅れて| [(パーティション名、...)] [(col_name、...)] {VALUES | VALUE}({expr | DEFAULT}、...)、...(...)、... [重複キー更新ではcol_name = expr [、col_name = expr] ...]
INSERT [LOW_PRIORITY |遅れて| HIGH_PRIORITY] [IGNORE] [INTO] tbl_name [PARTITION(パーティション名、...)] SET col_name = {expr | DEFAULT}、... [重複キー更新ではcol_name = expr [、col_name = expr] ...]
INSERT [LOW_PRIORITY | (col_name、...)] SELECT ... [重複キー更新時にcol_name = expr [、col_name = expr] ...]
式exprは、値リストで先に設定された列を参照できます。たとえば、col2の値が以前に割り当てられていたcol1を参照するため、これを行うことができます。
INSERT INTO tbl_name(col1、col2)VALUES(15、col1 * 2);VALUES構文を使用するINSERTステートメントは、複数の行を挿入できます。これを行うには、括弧で囲まれカンマで区切られた複数の列値のリストを含めます。例:
INSERT INTO tbl_name(a、b、c)VALUES(1,2,3)、(4,5,6)、(7,8,9);各行の値リストは、かっこで囲む必要があります。リスト内の値の数が列名の数と一致しないため、次の文は無効です。
INSERT INTO tbl_name(a、b、c)VALUES(1,2,3,4,5,6,7,8,9);INSERT ... SELECT構文
INSERT [LOW_PRIORITY | [(col_name、...)] SELECT ... [重複キー更新時col_name = expr、...]INSERT ... SELECTを使用すると、1つまたは複数の表から多くの行を表にすばやく挿入できます。例えば:
INSERT INTO tbl_temp2(fld_id)SELECT tbl_temp1.fld_order_id FROM tbl_temp1 WHERE tbl_temp1.fld_order_id> 100;
備考
基本挿入
INSERT INTO `table_name` (`field_one`, `field_two`) VALUES ('value_one', 'value_two');
この簡単な例では、 table_name
はデータを追加する場所、 field_one
とfield_two
はデータを設定するフィールド、 value_one
とvalue_two
はそれぞれfield_one
とfield_two
に対して行うデータです。
コード内にデータを挿入するフィールドをリストすることは、テーブルが変更され、新しい列が追加された場合、挿入物がそこに存在しない場合に破損するようにすることをお勧めします
デュプリケートキー更新でINSERT
INSERT INTO `table_name`
(`index_field`, `other_field_1`, `other_field_2`)
VALUES
('index_value', 'insert_value', 'other_value')
ON DUPLICATE KEY UPDATE
`other_field_1` = 'update_value',
`other_field_2` = VALUES(`other_field_2`);
これにより、指定された値がtable_name
INSERT
されますが、ユニークキーがすでに存在する場合は、 other_field_1
が新しい値に更新されます。
ときどき重複キーを更新すると、値を直接設定する代わりにINSERT
に渡された元の値にアクセスするためにVALUES()
を使用すると便利です。これにより、 INSERT
とUPDATE
を使用して異なる値を設定できます。上記の例を参照してくださいother_field_1
するように設定されているinsert_value
にINSERT
またはするupdate_value
にUPDATE
ながらother_field_2
常にに設定されているother_value
。
重複キー更新(IODKU)が機能するために重要なのは、重複した衝突を通知するユニークなキーを含むスキーマです。このユニークキーは、プライマリキーであってもなくてもよい。これは、単一の列または複数列(複合キー)上の一意のキーにすることができます。
複数の行を挿入する
INSERT INTO `my_table` (`field_1`, `field_2`) VALUES
('data_1', 'data_2'),
('data_1', 'data_3'),
('data_4', 'data_5');
これは、1つのINSERT
ステートメントで複数の行を一度に追加する簡単な方法です。
この種のバッチインサートは、行を1つずつ挿入するよりもはるかに高速です。一般的に、この方法で1行の挿入物に100行を挿入するのは、それらをすべて個別に挿入する場合の10倍です。
既存の行を無視する
大規模なデータセットをインポートする場合、特定の状況下では、列の制約(通常は主キーの重複など)によってクエリが失敗する行をスキップすることが望ましい場合があります。これは、 INSERT IGNORE
を使用して行うことができINSERT IGNORE
。
次の例のデータベースを検討してください。
SELECT * FROM `people`;
--- Produces:
+----+------+
| id | name |
+----+------+
| 1 | john |
| 2 | anna |
+----+------+
INSERT IGNORE INTO `people` (`id`, `name`) VALUES
('2', 'anna'), --- Without the IGNORE keyword, this record would produce an error
('3', 'mike');
SELECT * FROM `people`;
--- Produces:
+----+--------+
| id | name |
+----+--------+
| 1 | john |
| 2 | anna |
| 3 | mike |
+----+--------+
重要なことは、 INSERT IGNOREも静かに他のエラーをスキップすることです.Mysqlの公式ドキュメントには次のように書かれています。
IGNOREが指定されていない場合、エラーを引き起こすデータ変換によって文が中止されます。 IGNOREでは、無効な値が最も近い値に調整され、>挿入されます。警告は生成されますが、文は中止されません。
注: - 以下のセクションは完全性のために追加されていますが、ベストプラクティスとはみなされません(たとえば、別の列がテーブルに追加された場合など)。
表のすべての列に対応する列の値を指定すると、次のようにINSERT
文の列リストを無視できます。
INSERT INTO `my_table` VALUES
('data_1', 'data_2'),
('data_1', 'data_3'),
('data_4', 'data_5');
INSERT SELECT(別のテーブルからのデータの挿入)
これは、SELECTステートメントで別のテーブルのデータを挿入する基本的な方法です。
INSERT INTO `tableA` (`field_one`, `field_two`)
SELECT `tableB`.`field_one`, `tableB`.`field_two`
FROM `tableB`
WHERE `tableB`.clmn <> 'someValue'
ORDER BY `tableB`.`sorting_clmn`;
SELECT * FROM
できますが、 tableA
とtableB
列数と対応するデータ型が一致している必要があります。
AUTO_INCREMENT
列は、 INSERT
with VALUES
句のように扱われます。
この構文を使用すると、他のテーブルのデータで簡単にテーブルを埋めることができます(さらに、挿入時にデータをフィルタリングする場合)。
AUTO_INCREMENT + LAST_INSERT_ID()によるINSERT
表にAUTO_INCREMENT
PRIMARY KEY
がある場合、通常はその列には挿入されません。代わりに、他の列をすべて指定してから、新しいIDが何であるかを尋ねます。
CREATE TABLE t (
id SMALLINT UNSIGNED AUTO_INCREMENT NOT NULL,
this ...,
that ...,
PRIMARY KEY(id) );
INSERT INTO t (this, that) VALUES (..., ...);
SELECT LAST_INSERT_ID() INTO @id;
INSERT INTO another_table (..., t_id, ...) VALUES (..., @id, ...);
LAST_INSERT_ID()
はセッションに結びついているので、複数の接続が同じテーブルに挿入されていても、それぞれが独自のIDを取得します。
あなたのクライアントAPIはおそらく実際にSELECT
を実行せずに値をクライアントに戻すことなく、 LAST_INSERT_ID()
を得る別の方法を@variable
ています。これが通常好ましい。
より長く、より詳細な例
IODKUの「通常の」使用法は、 AUTO_INCREMENT PRIMARY KEY
ではなく、 UNIQUE
キーに基づいて「重複キー」をトリガーすることです。以下はそのようなことを示しています。これは、INSERTにid
を供給しないことに注意してください。
以下の例のセットアップ:
CREATE TABLE iodku (
id INT AUTO_INCREMENT NOT NULL,
name VARCHAR(99) NOT NULL,
misc INT NOT NULL,
PRIMARY KEY(id),
UNIQUE(name)
) ENGINE=InnoDB;
INSERT INTO iodku (name, misc)
VALUES
('Leslie', 123),
('Sally', 456);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
+----+--------+------+
| id | name | misc |
+----+--------+------+
| 1 | Leslie | 123 |
| 2 | Sally | 456 |
+----+--------+------+
IODKUが「更新」をLAST_INSERT_ID()
、関連するid
取得するLAST_INSERT_ID()
INSERT INTO iodku (name, misc)
VALUES
('Sally', 3333) -- should update
ON DUPLICATE KEY UPDATE -- `name` will trigger "duplicate key"
id = LAST_INSERT_ID(id),
misc = VALUES(misc);
SELECT LAST_INSERT_ID(); -- picking up existing value
+------------------+
| LAST_INSERT_ID() |
+------------------+
| 2 |
+------------------+
IODKUが「挿入」を実行し、 LAST_INSERT_ID()
が新しいid
取得する場合:
INSERT INTO iodku (name, misc)
VALUES
('Dana', 789) -- Should insert
ON DUPLICATE KEY UPDATE
id = LAST_INSERT_ID(id),
misc = VALUES(misc);
SELECT LAST_INSERT_ID(); -- picking up new value
+------------------+
| LAST_INSERT_ID() |
+------------------+
| 3 |
+------------------+
結果のテーブルの内容:
SELECT * FROM iodku;
+----+--------+------+
| id | name | misc |
+----+--------+------+
| 1 | Leslie | 123 |
| 2 | Sally | 3333 | -- IODKU changed this
| 3 | Dana | 789 | -- IODKU added this
+----+--------+------+
失われたAUTO_INCREMENT ids
いくつかの '挿入'機能でIDを焼くことができます。以下は、InnoDBを使った例です(他のエンジンは動作が異なるかもしれません):
CREATE TABLE Burn (
id SMALLINT UNSIGNED AUTO_INCREMENT NOT NULL,
name VARCHAR(99) NOT NULL,
PRIMARY KEY(id),
UNIQUE(name)
) ENGINE=InnoDB;
INSERT IGNORE INTO Burn (name) VALUES ('first'), ('second');
SELECT LAST_INSERT_ID(); -- 1
SELECT * FROM Burn ORDER BY id;
+----+--------+
| 1 | first |
| 2 | second |
+----+--------+
INSERT IGNORE INTO Burn (name) VALUES ('second'); -- dup 'IGNOREd', but id=3 is burned
SELECT LAST_INSERT_ID(); -- Still "1" -- can't trust in this situation
SELECT * FROM Burn ORDER BY id;
+----+--------+
| 1 | first |
| 2 | second |
+----+--------+
INSERT IGNORE INTO Burn (name) VALUES ('third');
SELECT LAST_INSERT_ID(); -- now "4"
SELECT * FROM Burn ORDER BY id; -- note that id=3 was skipped over
+----+--------+
| 1 | first |
| 2 | second |
| 4 | third | -- notice that id=3 has been 'burned'
+----+--------+
それを考える(おおよそ)この方法は、まず、インサートが挿入される可能性がありますどのように多くの行を参照することになります。次に、そのテーブルのauto_incrementから多くの値を取得します。最後に、必要に応じてIDを使用して行を挿入し、残りの部分を焼く。
システムがシャットダウンして再起動した場合、残っている部分を回復できるのは唯一の時間です。再起動すると、効果的にMAX(id)
が実行されます。これは、焼かれたID、または最も高いidのDELETEs
によって解放されたIDを再利用することがあります。
本質的に、 INSERT
( DELETE
+ INSERT
であるREPLACE
を含む)のフレーバーはIDを焼くことができます。 InnoDBでは、グローバルな(セッションではない!)変数innodb_autoinc_lock_mode
を使って、何が起こっているのかを制御できます。
長い文字列をAUTO INCREMENT id
に「正規化」すると、簡単に書き込みが行われます。これは、の大きさ溢れるにつながる可能性が INT
あなたが選んだの。