CodeIgniter 프레임워크를 사용하여 어레이에서 여러 행을 삽입하는 방법
삽입 명령어를 사용하여 큰 데이터 세트를 MySQL 테이블로 전달하고 있는데, 1마일 길이의 문자열 끝에 각 값을 추가한 후 실행하는 것 외에 쿼리를 통해 한 번에 약 1000개의 행을 삽입할 수 있는지 궁금합니다.저는 CodeIgniter 프레임워크를 사용하고 있기 때문에 그 기능도 사용할 수 있습니다.
의 1개의 INSERT가 MySQL보다 .INSERT각 행의 스테이트먼트를 지정합니다.
PHP에서 하고 있는 이것은 언어의 문제가 아니라 알고리즘의 문제입니다.기본적으로 큰 문자열로 작업할 때는 불필요한 복사를 최소화해야 합니다.이는 주로 연결을 피해야 함을 의미합니다.을 작성하는 은 예를 수백 을 한입니다.implode()★★★★★★★★★★★★★★★★★★★★★★★★★★
$sql = array();
foreach( $data as $row ) {
$sql[] = '("'.mysql_real_escape_string($row['text']).'", '.$row['category_id'].')';
}
mysql_query('INSERT INTO table (text, category) VALUES '.implode(',', $sql));
이 접근법의 장점은 지금까지 조립한 SQL 문을 각 연결로 복사하고 다시 복사하지 않는다는 것입니다. 대신 PHP는 이 작업을 한 번 수행합니다.implode()진술.이것은 큰 승리이다.
컬럼이 여러 긴 내부 하여 같은 작업을 할 수 . 루프를 사용하면 .implode() 구를 outer arrayvalues에 합니다.
이제 CodeIgniter에서 다중 삽입/배치 삽입이 지원됩니다.
$data = array(
array(
'title' => 'My title' ,
'name' => 'My Name' ,
'date' => 'My date'
),
array(
'title' => 'Another title' ,
'name' => 'Another Name' ,
'date' => 'Another date'
)
);
$this->db->insert_batch('mytable', $data);
// Produces: INSERT INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date'), ('Another title', 'Another name', 'Another date')
mysqli_stmt 클래스를 사용하여 한 행을 삽입하기 위한 쿼리를 준비한 다음 데이터 배열에 대해 반복할 수 있습니다.예를 들어 다음과 같습니다.
$stmt = $db->stmt_init();
$stmt->prepare("INSERT INTO mytbl (fld1, fld2, fld3, fld4) VALUES(?, ?, ?, ?)");
foreach($myarray as $row)
{
$stmt->bind_param('idsb', $row['fld1'], $row['fld2'], $row['fld3'], $row['fld4']);
$stmt->execute();
}
$stmt->close();
여기서 'idsb'는 바인딩할 데이터의 유형(int, double, string, blob)입니다.
PHP 5의 mysqli는 위의 답변의 삽입 시간을 단축할 수 있는 몇 가지 좋은 기능을 가진 객체입니다.
$mysqli->autocommit(FALSE);
$mysqli->multi_query($sqlCombined);
$mysqli->autocommit(TRUE);
행을 여러 개 삽입할 때 자동 커밋을 해제하면 삽입 속도가 크게 향상되므로 해제한 후 위와 같이 실행하거나 세미콜론과 멀티쿼리로 구분된 다수의 삽입문인 문자열(sqlCombined)을 작성하기만 하면 문제가 없습니다.
언제든지 mysql을 사용할 수 있습니다.LOAD DATA:
LOAD DATA LOCAL INFILE '/full/path/to/file/foo.csv' INTO TABLE `footable` FIELDS TERMINATED BY ',' LINES TERMINATED BY '\r\n'
다발을 사용하지 않고 대량 삽입을 하다INSERT진술들.
1000개의 쿼리 콜을 실행하고 싶지는 않지만, 다음과 같이 해도 괜찮습니다.
$stmt= array( 'array of statements' );
$query= 'INSERT INTO yourtable (col1,col2,col3) VALUES ';
foreach( $stmt AS $k => $v ) {
$query.= '(' .$v. ')'; // NOTE: you'll have to change to suit
if ( $k !== sizeof($stmt)-1 ) $query.= ', ';
}
$r= mysql_query($query);
데이터 소스에 따라서는, 어레이에의 기입은, 파일을 열어 컨텐츠를 어레이에 덤프 하는 것만으로 간단하게 실시할 수 있습니다.file().
$query= array();
foreach( $your_data as $row ) {
$query[] = '("'.mysql_real_escape_string($row['text']).'", '.$row['category_id'].')';
}
mysql_query('INSERT INTO table (text, category) VALUES '.implode(',', $query));
코드 시그너로 여러 가지 방법을 사용할 수 있습니다.
퍼스트바이루프
foreach($myarray as $row)
{
$data = array("first"=>$row->first,"second"=>$row->sec);
$this->db->insert('table_name',$data);
}
두 번째 - 배치 삽입
$data = array(
array(
'first' => $myarray[0]['first'] ,
'second' => $myarray[0]['sec'],
),
array(
'first' => $myarray[1]['first'] ,
'second' => $myarray[1]['sec'],
),
);
$this->db->insert_batch('table_name', $data);
세 번째 방법 - 다중 값 패스로
$sql = array();
foreach( $myarray as $row ) {
$sql[] = '("'.mysql_real_escape_string($row['first']).'", '.$row['sec'].')';
}
mysql_query('INSERT INTO table (first, second) VALUES '.implode(',', $sql));
비록 이 질문에 답하기에는 너무 늦었지만.같은 내용의 답변입니다.
CodeIgniter를 사용하는 경우 query_builder 클래스에 정의된 삽입 메서드를 사용할 수 있습니다.
$this->db->insert_model()
입력한 데이터를 기반으로 삽입 문자열을 생성하고 쿼리를 실행합니다.함수에 배열 또는 개체를 전달할 수 있습니다.어레이 사용 예를 다음에 나타냅니다.
$data = array(
array(
'title' => 'My title',
'name' => 'My Name',
'date' => 'My date'
),
array(
'title' => 'Another title',
'name' => 'Another Name',
'date' => 'Another date'
)
);
$this->db->insert_batch('mytable', $data);
// Produces: INSERT INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date'), ('Another title', 'Another name', 'Another date')
첫 번째 매개 변수에는 테이블 이름이 포함되며 두 번째 매개 변수에는 값의 연관 배열이 포함됩니다.
query_builder에 대한 자세한 내용은 여기를 참조하십시오.
다음과 같이 여러 줄을 수행하는 클래스를 만들었습니다.
$pdo->beginTransaction();
$pmi = new PDOMultiLineInserter($pdo, "foo", array("a","b","c","e"), 10);
$pmi->insertRow($data);
// ....
$pmi->insertRow($data);
$pmi->purgeRemainingInserts();
$pdo->commit();
클래스는 다음과 같이 정의됩니다.
class PDOMultiLineInserter {
private $_purgeAtCount;
private $_bigInsertQuery, $_singleInsertQuery;
private $_currentlyInsertingRows = array();
private $_currentlyInsertingCount = 0;
private $_numberOfFields;
private $_error;
private $_insertCount = 0;
/**
* Create a PDOMultiLine Insert object.
*
* @param PDO $pdo The PDO connection
* @param type $tableName The table name
* @param type $fieldsAsArray An array of the fields being inserted
* @param type $bigInsertCount How many rows to collect before performing an insert.
*/
function __construct(PDO $pdo, $tableName, $fieldsAsArray, $bigInsertCount = 100) {
$this->_numberOfFields = count($fieldsAsArray);
$insertIntoPortion = "REPLACE INTO `$tableName` (`".implode("`,`", $fieldsAsArray)."`) VALUES";
$questionMarks = " (?".str_repeat(",?", $this->_numberOfFields - 1).")";
$this->_purgeAtCount = $bigInsertCount;
$this->_bigInsertQuery = $pdo->prepare($insertIntoPortion.$questionMarks.str_repeat(", ".$questionMarks, $bigInsertCount - 1));
$this->_singleInsertQuery = $pdo->prepare($insertIntoPortion.$questionMarks);
}
function insertRow($rowData) {
// @todo Compare speed
// $this->_currentlyInsertingRows = array_merge($this->_currentlyInsertingRows, $rowData);
foreach($rowData as $v) array_push($this->_currentlyInsertingRows, $v);
//
if (++$this->_currentlyInsertingCount == $this->_purgeAtCount) {
if ($this->_bigInsertQuery->execute($this->_currentlyInsertingRows) === FALSE) {
$this->_error = "Failed to perform a multi-insert (after {$this->_insertCount} inserts), the following errors occurred:".implode('<br/>', $this->_bigInsertQuery->errorInfo());
return false;
}
$this->_insertCount++;
$this->_currentlyInsertingCount = 0;
$this->_currentlyInsertingRows = array();
}
return true;
}
function purgeRemainingInserts() {
while ($this->_currentlyInsertingCount > 0) {
$singleInsertData = array();
// @todo Compare speed - http://www.evardsson.com/blog/2010/02/05/comparing-php-array_shift-to-array_pop/
// for ($i = 0; $i < $this->_numberOfFields; $i++) $singleInsertData[] = array_pop($this->_currentlyInsertingRows); array_reverse($singleInsertData);
for ($i = 0; $i < $this->_numberOfFields; $i++) array_unshift($singleInsertData, array_pop($this->_currentlyInsertingRows));
if ($this->_singleInsertQuery->execute($singleInsertData) === FALSE) {
$this->_error = "Failed to perform a small-insert (whilst purging the remaining rows; the following errors occurred:".implode('<br/>', $this->_singleInsertQuery->errorInfo());
return false;
}
$this->_currentlyInsertingCount--;
}
}
public function getError() {
return $this->_error;
}
}
코드 시그너에 배치 삽입을 사용하여 데이터 행을 여러 개 삽입합니다.
$this->db->insert_batch('tabname',$data_array); // $data_array holds the value to be inserted
테이블에 14000개 이상의 행을 삽입해야 했는데 Mysqli가 준비한 문과의 행에 10분 이상 걸리는 반면 Mysqli가 준비한 문과 동일한 문자열 매개 변수를 사용하여 인수를 풀면 10초도 걸리지 않았습니다.내 데이터는 id의 배수이고 하나의 정수이기 때문에 매우 반복적이었다.
10분 코드:
$num = 1000;
$ent = 4;
$value = ['id' => 1,
'id' => 2,
'id' => 3,
'id' => 4,
'id' => 5,
'id' => 6,
'id' => 7,
'id' => 8,
'id' => 9,
'id' => 10,
'id' => 11,
'id' => 12,
'id' => 13,
'id' => 14];
$cnt = 0;
$query = "INSERT INTO table (col1, col2) VALUES (?,?)";
$stmt = $this->db->prepare($query);
$stmt->bind_param('ii', $arg_one,$arg_two);
foreach ($value as $k => $val) {
for ($i=0; $i < $num; $i++) {
$arg_one = $k;
$arg_two = $ent;
if($stmt->execute()) {
$cnt++;
}
}
}
10초 코드:
$ent = 4;
$num = 1000;
$value = ['id' => 1,
'id' => 2,
'id' => 3,
'id' => 4,
'id' => 5,
'id' => 6,
'id' => 7,
'id' => 8,
'id' => 9,
'id' => 10,
'id' => 11,
'id' => 12,
'id' => 13,
'id' => 14];
$newdat = [];
foreach ($value as $k => $val) {
for ($i=0; $i < $num; $i++) {
$newdat[] = $val;
$newdat[] = $ent;
}
}
// create string of data types
$cnt = count($newdat);
$param = str_repeat('i',$cnt);
// create string of question marks
$rec = (count($newdat) == 0) ? 0 : $cnt / 2 - 1;
$id_q = str_repeat('(?,?),', $rec) . '(?,?)';
// insert
$query = "INSERT INTO table (col1, col2) VALUES $id_q";
$stmt = $db->prepare($query);
$stmt->bind_param($param, ...$newdat);
$stmt->execute();
여러분이 쉽게 사용할 수 있는 간단한 기능을 만들었습니다.테이블 이름을 전달해야 합니다.($tbl), 테이블 필드($insertFieldsArr)데이터 삽입, 데이터 배열($arr).
insert_batch('table',array('field1','field2'),$dataArray);
function insert_batch($tbl,$insertFieldsArr,$arr){ $sql = array();
foreach( $arr as $row ) {
$strVals='';
$cnt=0;
foreach($insertFieldsArr as $key=>$val){
if(is_array($row)){
$strVals.="'".mysql_real_escape_string($row[$cnt]).'\',';
}
else{
$strVals.="'".mysql_real_escape_string($row).'\',';
}
$cnt++;
}
$strVals=rtrim($strVals,',');
$sql[] = '('.$strVals.')';
}
$fields=implode(',',$insertFieldsArr);
mysql_query('INSERT INTO `'.$tbl.'` ('.$fields.') VALUES '.implode(',', $sql));
}
언급URL : https://stackoverflow.com/questions/779986/how-to-insert-multiple-rows-from-array-using-codeigniter-framework
'programing' 카테고리의 다른 글
| Java Big Decimal:가장 가까운 정수 값으로 반올림 (0) | 2023.01.17 |
|---|---|
| 테스트 러너 'JUnit 4'를 사용하여 테스트를 찾을 수 없습니다. (0) | 2023.01.17 |
| PHP: stdClass 개체 수 (0) | 2023.01.17 |
| !== "displicate" vs. != null 유형 (0) | 2023.01.17 |
| 옵션이 설정된 경우 BitmapFactory.decodeStream이 null을 반환합니다. (0) | 2023.01.17 |