Trong quá trình thực hiện dự án cho công ty, một trong những yêu cầu đặt ra là import dữ liệu từ file CSV (chứa dữ liệu từ hệ thống cũ) vào cơ sở dữ liệu MySQL của hệ thống mới.

Do sự thay đổi cấu trúc dữ liệu trong hệ thống mới, việc xử lý dữ liệu trước khi import vào trở thành bước quan trọng.

Tuy nhiên, thách thức đặt ra là kích thước lớn của dữ liệu từ hệ thống cũ, yêu cầu quá trình import phải diễn ra một cách nhanh chóng.

Sau quá trình nghiên cứu và thảo luận với đồng đội trong công ty, mình đã đề xuất một phương pháp xử lý hiệu quả như sau:

Trong bài viết này, mình sử dụng Laravel Framework phiên bản 10.

Tạo Command trong Laravel

php artisan make:command ImportCSV

Đọc và Xử lý Dữ liệu từ File CSV

 Đọc dữ liệu từ file CSV bằng phương pháp Chunk.

Sau đó sẽ xử lý dữ liệu cũ để tương thích với hệ thống mới và ghi kết quả xử lý thành CSV mới.

public function handle()
{
    $filename     = storage_path('transfers/data.csv');
    $filetransfer = storage_path('transfers/data-transfer.csv');
    $chunk_size   = 10000;
    
    if (($handle = fopen($filename, "r")) !== FALSE) {
        $header    = fgetcsv($handle);
        $now       = now();
        $row_count = 0;
        $chunk     = [];
        $transfer  = fopen($filetransfer, 'w');
        
        while (($row = fgetcsv($handle)) !== FALSE) {
            $row_count++;
            $chunk[] = $row;
            
            if ($row_count >= $chunk_size) {
                $this->_writeCSV($header, $chunk, $now, $transfer);
                $chunk     = [];
                $row_count = 0;
            }
        }
        
        if (!empty($chunk)) {
            $this->_writeCSV($header, $chunk, $now, $transfer);
        }
        
        fclose($handle);
        fclose($transfer);
        $this->_loadDataLocalInFile($filetransfer);
    } else {
        echo "Cannot open file $filename.";
    }
}

private function _writeCSV($header, $chunk, $now, $transfer)
{
    foreach ($chunk as $row) {
        fputcsv($transfer, [
            # Xử lý dữ liệu cũ và ghi thành file CSV
        ]);
    }
}

Import Dữ liệu vào Cơ sở Dữ liệu mới

Mình sẽ sử dụng LOAD DATA LOCAL INFILE đây một câu lệnh trong MySQL được sử dụng để nạp dữ liệu từ một file local vào một bảng trong cơ sở dữ liệu.

Đây là một cách hiệu quả để import dữ liệu từ các tệp CSV hoặc văn bản vào MySQL mà không cần phải truyền qua ứng dụng trung gian.

private function _loadDataLocalInFile($file)
{
    $table = 'name_table';
    $query = "
        LOAD DATA LOCAL INFILE '{$file}'
        INTO TABLE {$table}
        FIELDS TERMINATED BY ','
        ENCLOSED BY '\"'
        LINES TERMINATED BY '\n'
        (table_columns)
    ";
    DB::connection()->getPdo()->exec($query);
}

Cấu hình Laravel cho LOAD DATA LOCAL INFILE

Để thực hiện được lệnh LOAD DATA LOCAL INFILE trong Laravel.

Cần phải thêm option MYSQL_ATTR_LOCAL_INFILE vào MySQL trong config/database.php

'mysql' => [
    ...
    'options' => extension_loaded('pdo_mysql') ? array_filter([
        ...
        PDO::MYSQL_ATTR_LOCAL_INFILE => true,
    ]) : [],
],

Hy vọng rằng, với cách tiếp cận này, quá trình import dữ liệu sẽ diễn ra một cách hiệu quả và nhanh chóng, đồng thời đảm bảo tính chính xác và sự đồng bộ giữa hệ thống cũ và mới trong dự án của bạn.

CÓ THỂ BẠN QUAN TÂM

Method WhereAny / WhereAll  in Laravel Eloquent

Method WhereAny / WhereAll in Laravel Eloquent

New Laravel 10: Eloquent WhereAny() và WhereAll() Laravel cung cấp cho chúng ta khả năng xây dựng các truy vấn dữ liệu mạnh mẽ với Eloquent ORM, giúp chúng ta có thể xử lý các truy vấn cơ sở dữ li...

Laravel Scout Full Text Search With Meilisearch

Laravel Scout Full Text Search With Meilisearch

Laravel Scout cung cấp một giải pháp đơn giản, dựa trên trình điều khiển để thêm tìm kiếm Full Text vào các mô hình Eloquent của bạn. Khi sử dụng Eloquent, Scout sẽ tự động giữ chỉ mục tìm kiếm của bạ...

Csv import with Validation for Laravel

Csv import with Validation for Laravel

Trong một bài viết lúc trước, mình đã chia sẻ đến các bạn cách xây dựng một service import và export CSV sử dụng Facades, nếu có bạn nào không biết hoặc đã quên các bạn có thể tham khảo lại bài viết t...

Laravel Has Many Through Eloquent Relationship

Laravel Has Many Through Eloquent Relationship

Has Many Through Relationship hơi phức tạp để hiểu một cách đơn giản, nó sẽ cung cấp cho chúng ta một con đường tắt để có thể truy cập dữ liệu của một quan hệ xa xôi thông qua một mối quan hệ trung gi...

Encrypted HTTP Live Streaming with Laravel FFMpeg

Encrypted HTTP Live Streaming with Laravel FFMpeg

HTTP Live Streaming (HLS)  HTTP Live Streaming (HLS) là một trong những giao thức phát trực tuyến video được sử dụng rộng rãi nhất . Mặc dù nó được gọi là HTTP "live" streaming, nhưng nó được sử dụn...

Efficient Laravel PDF Export for Large Datasets

Efficient Laravel PDF Export for Large Datasets

Xuất file PDF là một tính năng quan trọng của nhiều ứng dụng web, đặc biệt là các trang thương mại điện tử, giúp người dùng tạo và lưu trữ các bản báo cáo, hóa đơn, v.v.  Tuy nhiên, khi phải xử lý...

Laravel UI Custom Email Verification Template

Laravel UI Custom Email Verification Template

Nếu bạn đang dùng thư viện laravel/ui để làm các chức năng liên quan đến authentication, và trong dự án của bạn, bạn cần thay đổi template email verification thay vì sử dụng template email verificatio...

Laravel Socialite Login With Gitlab

Laravel Socialite Login With Gitlab

GitLab GitLab là kho lưu trữ Git dựa trên web cung cấp các kho lưu trữ mở và riêng tư miễn phí, các khả năng theo dõi vấn đề và wiki. Đây là một nền tảng DevOps hoàn chỉnh cho phép các chuyên gia...

Integrating AI Assistant with CKEditor 5 in Laravel using Vite

Integrating AI Assistant with CKEditor 5 in Laravel using Vite

OpenAI OpenAI là một công ty nghiên cứu và triển khai trí tuệ nhân tạo, nổi tiếng với việc phát triển các mô hình AI tiên tiến. Mục tiêu của OpenAI là đảm bảo rằng trí tuệ nhân tạo tổng quát (AGI...

ManhDanBlogs