CSV 배열의 인코딩을 일괄적으로 변경하여 키 설정
개시하다
나는 CSV가 채택한 배열 인코딩을 바꾸는 기초 위에서 연상 배열화를 하고 싶다.
최종적으로 문자 코드를 UTF-8로 설정합니다.
수량이 적을 때는 문제가 없지만, 실제 데이터(10만기록·200열)가 유입됐을 때는 처리 속도가 유난히 빨라져 조정됐다.
해본 일
이번에 한 일은 넓은 의미로 여러 삽입물이지만, 한 번에 처리할 수 없어 여러 개와 벌크 조합처럼 느껴졌다.
대량 삽입
한 번에 여러 개의 삽입을 실행합니다.제출 횟수가 적고 처리가 빠르다.
BEGIN;
INSERT INTO tbl_name (a, b, c) VALUES (1, 2, 3);
INSERT INTO tbl_name (a, b, c) VALUES (4, 5, 6);
INSERT INTO tbl_name (a, b, c) VALUES (7, 8, 9);
COMMIT;
다중 삽입질의에 여러 줄 레코드를 삽입합니다.물론 한 번만 제출할 수 있다.
BEGIN;
INSERT INTO tbl_name (a, b, c) VALUES (1, 2, 3), (4, 5, 6), (7, 8, 9);
COMMIT;
배열
csv-array
/* SJIS-WIN */
$csv_array = [
0 => [
0 => '1',
1 => 'test user1',
2 => '090-9999-9999',
3 => '28',
// more columns...
],
1 => [
0 => '2',
1 => 'test user2',
2 => '090-9999-9999',
3 => '42',
// more columns...
],
// more rows...
];
/* key array */
$keys = [
0 => 'id',
1 => 'name',
2 => 'phone',
3 => 'age',
// more keys...
];
/* 最終的にほしい配列 */
$rows = [
0 => [
'id' => '1',
'name' => 'test user1',
'phone' => '090-9999-9999',
'age' => '28',
// more columns...
],
1 => [
'id' => '2',
'name' => 'test user2',
'phone' => '090-9999-9999',
'age' => '42',
// more columns...
],
// more rows...
];
스트로크 연습
인코딩 키 교체 처리
$rows = [];
foreach ($csv_array as $line => $csv_line) {
foreach ($csv_line as $i => $buf) {
$key = $keys[$i];
$rows[$line][$key] = mb_convert_encoding($buf, 'UTF-8', 'ASCII, JIS, UTF-8, EUC-JP, SJIS-win'); // ※1
}
}
INSERT 처리
try () {
// トランザクション開始
\DB::connection('mysql_sample')->beginTransaction();
$table = \DB::connection('mysql_sample')->table('sample');
foreach ($rows as $row) {
// 1レコード追加
$table->insert($row);
}
// 問題なければコミット
\DB::connection('mysql_sample')->commit();
} catch (\Exception $e) {
// 問題が発生すればロールバック
\DB::connection('mysql_sample')->rollback();
echo $e->getTraceAsString();
}
수정 후
인코딩 키 교체 처리
/*
配列をまとめてエンコーディングする
PHP5.6・7.0・7.1だとバグがある点に注意する ※2
変換結果は元の配列にセットされる
*/
mb_convert_variables('UTF-8', 'SJIS-WIN', $csv_array);
// キー配列を指定して一括置換
$rows = array_combine($keys, $csv_array);
INSERT 처리
try () {
// トランザクション開始
\DB::connection('mysql_sample')->beginTransaction();
$table = \DB::connection('mysql_sample')->table('sample');
$bulk_counter = 0; // カラム数カウンタ
$bulk_rows = []; // 一括INSERT用配列
foreach ($rows as $row) {
$counter = count($row);
$bulk_rows[] = $row;
/*
プリペアドステートメントは65536パラメータをオーバーするとエラーとなる ※3
そのため、カラム数が規定値を上回った時点でINSERTを実行している
*/
if ($counter + $bulk_counter > 65500) {
$table->insert($bulk_rows);
$bulk_rows = [];
$bulc_counter = 0;
} else {
$bulk_counter += $counter;
}
}
if ($bulk_rows !== [null]) {
$table->insert($bulk_rows);
}
\DB::connection('mysql_sample')->commit();
} catch (\Exception $e) {
\DB::connection('mysql_sample')->rollback();
echo $e->getTraceAsString();
}
주의 사항
※1:mb_convert_encoding의 문자 코드에 대한 명시 지정
참조여기..
세 번째 매개 변수의 $fromencoding에서 변환하기 전의 문자 인코딩 이름을 지정합니다. 만약 여기에서 'auto' 라고 지정하면 환경에 따라 달라집니다.
Warning: mb_convert_encoding(): Unable to detect character encoding
의 오류로 인해 문자 인코딩 변환이 실패할 수 있습니다.
따라서 가능한 한 "auto"를 사용하지 말고 문자 인코딩을 지정하는 것을 권장합니다.
※2:mb_convert_variables 오류
참조여기..
PHP 5.6.30 or PHP 7.0.16 or PHP 7.1.1 현재 나타나는 버그의 모습은 수정 pull 요청을 받은 것 같습니다.
※ 3: 예매권 문구의 상한치를 한꺼번에 발행 가능
여기.에 마음에 드는 기록이 있다.
think the number of placeholders is limited to 65536 per query (at least in older mysql versions).
(나는 자리 차지 문자의 수량 (적어도 오래된 mysql 버전에서는) 모든 검색이 65536로 제한되어 있다고 생각한다.)
기타
10만 기록 / 200 열 INSERT 결과
처리하다.
타임
반작용
30분 초과
수정 후
5분 23초.
감상
INSERT의 대량의 데이터가 시간이 걸린다고 생각했다면 자신이 쓴 코드의 대부분이 사용된 것을 발견했다.
나는 자신의 인코딩을 반성하면서 표준이 실현된 함수의 장점도 다시 느꼈다.
Reference
이 문제에 관하여(CSV 배열의 인코딩을 일괄적으로 변경하여 키 설정), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/tosite0345/items/58f1e239451eb20a9d4c
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
INSERT의 대량의 데이터가 시간이 걸린다고 생각했다면 자신이 쓴 코드의 대부분이 사용된 것을 발견했다.
나는 자신의 인코딩을 반성하면서 표준이 실현된 함수의 장점도 다시 느꼈다.
Reference
이 문제에 관하여(CSV 배열의 인코딩을 일괄적으로 변경하여 키 설정), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/tosite0345/items/58f1e239451eb20a9d4c텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)