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...

Easy Laravel Reverb Setup For Beginners

Easy Laravel Reverb Setup For Beginners

Laravel Reverb Lần đầu tiên, Laravel ra mắt một official package cho phép bạn xây dựng một Websocket Server. Trước đây, chúng ta phải sử dụng package bên thứ 3 như Laravel Websocket. Reverb được...

Laravel One to Many Polymorphic Relationship

Laravel One to Many Polymorphic Relationship

One to Many Polymorphic Model Relationship được sử dụng khi một model thuộc về nhiều model khác trên một model kết hợp duy nhất. Ví dụ: Nếu chúng ta có bảng post và video, cả hai đều cần thêm hệ thống...

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...

Laravel Socialite Login With Github

Laravel Socialite Login With Github

GitHub GitHub là một nền tảng phát triển phần mềm trực tuyến. Nó được sử dụng để lưu trữ, theo dõi và cộng tác trong các dự án phần mềm. Nó giúp các nhà phát triển dễ dàng chia sẻ các tập tin mã...

Laravel Logging Of Database Queries

Laravel Logging Of Database Queries

Laravel là một Framework PHP mạnh mẽ và linh hoạt, giúp cho việc phát triển ứng dụng trở nên đơn giản và dễ dàng hơn. Một trong những tính năng hữu ích của Laravel là khả năng ghi nhật ký truy vấn...

Amazon S3 Pre-Signed URL with DropzoneJs in Laravel

Amazon S3 Pre-Signed URL with DropzoneJs in Laravel

Chức năng upload file hay hình ảnh là một chức năng rất phổ biến, hầu hết các dự án đều có chức năng này. Đa số các nhà phát triển khi thực hiện chức năng upload file, thường sẽ sử dụng cách làm nh...

Integrating elFinder into TinyMCE 6 in Laravel

Integrating elFinder into TinyMCE 6 in Laravel

TinyMCE TinyMCE là một trình soạn thảo WYSIWYG được xây dựng trên nền tảng Javascript, được phát triển dưới dạng mã nguồn mở theo giấy phép MIT bởi Tiny Technologies Inc. TinyMCE cho phép người d...

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...

ManhDanBlogs