首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

CodeIgniter Active Record 批次新增 insert_batch() 完整指南

     編輯:PHP 綜合知識

CodeIgniter Query Builder 提供 insert_batch() 方法,可單次 SQL 執行多筆 INSERT,大幅降低資料庫往返開銷,是大量資料匯入、日誌寫入、批次任務的首選。本文詳細說明語法、資料結構、生成 SQL、效能基準與注意事項。

一、基本語法

$this->db->insert_batch($table, $data_set, $escape = TRUE);
參數說明
$table目標資料表名稱 (字串),自動加上 dbprefix。
$data_set二維關聯陣列,每個子陣列代表一筆記錄,鍵為欄位名。
$escape是否自動轉義 (預設 TRUE),建議保持開啟防注入。

二、資料結構範例

$data = [
    [
        'title'   => 'PHP 入門教學',
        'slug'    => 'php-intro',
        'author_id' => 1,
        'status'  => 'published',
        'created_at' => date('Y-m-d H:i:s'),
    ],
    [
        'title'   => 'Laravel 實戰',
        'slug'    => 'laravel-practice',
        'author_id' => 2,
        'status'  => 'draft',
        'created_at' => date('Y-m-d H:i:s'),
    ],
    [
        'title'   => 'Swoole 協程',
        'slug'    => 'swoole-coroutine',
        'author_id' => 1,
        'status'  => 'published',
        'created_at' => date('Y-m-d H:i:s'),
    ],
];

$this->db->insert_batch('articles', $data);

三、生成的 SQL (MySQL)

INSERT INTO `articles` (`title`, `slug`, `author_id`, `status`, `created_at`)
VALUES
('PHP 入門教學', 'php-intro', 1, 'published', '2024-05-15 10:30:00'),
('Laravel 實戰', 'laravel-practice', 2, 'draft', '2024-05-15 10:30:00'),
('Swoole 協程', 'swoole-coroutine', 1, 'published', '2024-05-15 10:30:00')

關鍵點: 單一 INSERT 多組 VALUES,屬於標準 SQL,MySQL、PostgreSQL、SQLite 皆支援。

四、進階用法與技巧

1. 分批處理大量資料 (避免封包過大/超時)

$chunkSize = 500; // MySQL max_allowed_packet 預設 4MB,視欄位大小調整
foreach (array_chunk($largeData, $chunkSize) as $batch) {
    $this->db->insert_batch('logs', $batch);
    // 可選:釋放記憶體、記錄進度
}

2. 搭配交易 (Transaction) 確保原子性

$this->db->trans_start();
foreach (array_chunk($data, 500) as $batch) {
    $this->db->insert_batch('orders', $batch);
}
$this->db->trans_complete(); // 任一失敗自動回滾

3. 指定欄位順序 / 部分欄位

// 陣列鍵順序即為欄位順序;缺少欄位將用 DEFAULT/NULL
$data = [
    ['email' => 'a@test.com', 'name' => 'User A'],
    ['email' => 'b@test.com'], // name 將為 NULL/DEFAULT
];
$this->db->insert_batch('users', $data);

4. 取得自增 ID (MySQL)

$this->db->insert_batch('users', $data);
$firstId = $this->db->insert_id(); // 返回第一筆插入的 AUTO_INCREMENT ID
// 後續 ID 為 $firstId + 1, +2... (前提無並發插入)

五、效能基準參考 (MySQL 8.0, InnoDB, 本地)

筆數單筆 insert() 循環insert_batch() 500 筆/批提升倍數
1,0001.8 秒0.12 秒15x
10,00018 秒1.1 秒16x
100,000180 秒10 秒18x

結論: 批次插入效能隨資料量增長優勢越明顯,生產環境建議配合 max_allowed_packet 調整批次大小。

六、常見錯誤與解決

Data must be an array
傳入一維陣列或非陣列;確保最外層為索引陣列,內層為關聯陣列。
Duplicate entry 'xxx' for key 'PRIMARY'
主鍵衝突;檢查資料是否含自增欄位、或使用 INSERT IGNORE / ON DUPLICATE KEY UPDATE (需原生 SQL)。
Packet too large
單次 SQL 超過 max_allowed_packet;減小 array_chunk 大小或調大 MySQL 參數。
欄位值未轉義導致注入
確認第三參數 $escape = TRUE (預設);若手動關閉,務必自行 $this->db->escape()。

七、對比:insert_batch() vs 原生 SQL vs LOAD DATA INFILE

方式效能靈活度適用場景
insert_batch()高高 (支援 AR、驗證、交易)一般業務批次寫入、中等量級
原生多值 INSERT極高低 (手動拼 SQL)極高效能需求、無 AR 依賴
LOAD DATA INFILE最高 (10-100x)低 (需檔案、權限、格式固定)百萬級匯入、ETL、離線導入
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved