2009-09-21 3 views
0

저는 사용자가 MS Access 데이터베이스 (csv 내보내기)를 업로드 한 다음 MySQL 데이터베이스로 변환하고 마이그레이션하는 PHP 웹 응용 프로그램을 작성합니다.데이터 번역 및 마이그레이션 방법

MS Access 데이터베이스는 100k 행의 t_product라는 하나의 테이블로 구성됩니다. 이 테이블은 잘 설계되지 않았습니다. 예를 들어, 다음 쿼리는 :

SELECT part_number, model_number FROM t_product 

반환합니다 : 당신이 볼 수 있듯이

part_number model_number 
100 AX1000, AX1001, AX1002 
101 CZ10, CZ220, MB100 

는 모델 번호 대신 다른 테이블의 개별 레코드의 쉼표로 구분 된 값으로 표시됩니다. 이런 성질의 문제가 더 많이 있습니다. mysql 데이터베이스로 가져 오기 전에이 데이터를 지우는 스크립트를 작성하고있다. 또한 스크립트는 기존 Access 열을 적절한 관계형 디자인 데이터베이스에 매핑합니다.

내 문제는 내 스크립트를 완료하는 데 너무 오래 걸리는 것입니다. 여기에 내가 뭘하는지 설명하는 코드를 단순화 것 : 여기

$handle = fopen("MSAccess.csv, "r"); 

// get each row from the csv 
while ($data=fgetcsv($handle, 1000, ",")) 
{ 
mysql_query("INSERT INTO t_product (col1, col2 etc...) values ($data[0], $data[1], etc..."); 
$prodId = mysql_last_insert_id(); 

// using model as an example, there are other columns 
// with csv values that need to be broken up 
$arrModel = explode(',', $data[2]); 
foreach($arrModel as $modelNumber) 
mysql_query("INSERT INTO t_model (product_id, col1, col2 etc...) values ($prodId, $modelNumber[0], $modelNumber[1] etc..."); 
} 

문제는 각 동안 루프 반복이 데이터베이스에 대한 호출의 엄청난 수를 만드는 것입니다. 모든 제품 레코드에 대해 N 모델 번호, Y 부품 번호, X 일련 번호 등을 삽입해야합니다.

전체 CSV를 배열에 저장하는 다른 방법을 시작했습니다. 그런 다음 같은 일괄 쿼리를 작성

$sql = "INSERT INTO t_product (col1, col2, etc...) values "; 
foreach($arrParam as $val) 
$sql .= " ($val[0], $val[1], $val[2]), " 

하지만이 접근법으로 과도한 메모리 오류가 발생했습니다. 최대 메모리 제한을 64M으로 늘렸고 메모리가 부족합니다.

이 문제를 해결하는 가장 좋은 방법은 무엇입니까?

아마도 모든 쿼리를 * .sql 파일에 작성한 다음 * .sql 파일을 mysql 데이터베이스로 가져와야할까요?

답변

0

나는 내 모든 쿼리를 .SQL 파일에 작성하기로 결정했습니다. 이로 인해 CSV 파일을 적절한 관계형 데이터베이스로 표준화 할 수있었습니다. 그 후에, 나의 PHP 스크립트는 exec ("mysql -h dbserver.com -u myuser -pmypass dbname < db.sql")라고 불렀다.

내 메모리 문제를 해결하고 PHP에서 여러 쿼리보다 훨씬 빠릅니다.

1

이것은 당신이 가고 싶은 완전히되지 방향이 될 수 있지만, 당신은 아마도 당신이 액세스 DB를 업로드하는 사용자를 허용 할 수있는 무료 MySQL Migration Toolkit

와 MS Access에서 직접 MySQL의 작성 스크립트를 생성 할 수 있습니다 PHP 스크립트에서 Migration Toolkit을 호출하게 하시겠습니까?

+0

마이그레이션 도구 키트는 대량 변환 속도를 높이기 위해 쿼리를 최적화합니다. –

0

이미 코드를 최적화하려고한다면 INSERT를 집계하여 도움이되는지 확인해보십시오. 이것은 코드에 쉽게 추가 할 수 있어야합니다. 이런 식으로 (C# 의사 코드) :

int flushCount = 0; 

while (!done) 
{ 
    // Build next query, concatenate to last set of queries 

    if (++flushCount == 5) 
    { 
     // Flush queries to database 

     // Reset query string to empty 

     flushCount = 0; 
    } 
} 

// Flush remaining queries to the database
관련 문제