LW IT Solutions
« Blog Overview /IT & Networks / Ekstrakcja konkretnych fragmentów z ogromnych zrzutów SQL...
This post in other languages:

Ekstrakcja konkretnych fragmentów z ogromnych zrzutów SQL przy użyciu PHP

Zdarzyło Ci się kiedyś, że musiałeś przywrócić tylko jedną bazę danych lub określoną tabelę z wielogigabajtowego (np. 5 GB) zrzutu MySQL? Otwarcie tak dużego pliku w standardowych edytorach tekstu, takich jak VS Code czy Notepad++, zazwyczaj kończy się drastycznym spadkiem wydajności lub całkowitym zawieszeniem programu.

Zamiast męczyć się z oprogramowaniem desktopowym lub skomplikowanymi narzędziami wiersza poleceń (jak awk czy sed), możemy użyć prostego, wydajnego pod względem pamięci skryptu PHP, aby wyciągnąć dokładnie to, czego potrzebujemy.

Rozwiązanie: Przetwarzanie strumieniowe

Sztuczka polega na tym, aby nie ładować całego pliku do pamięci naraz (co robią funkcje takie jak file_get_contents()). Używając funkcji fgets() w PHP, możemy przetwarzać ogromny plik strumieniowo, linia po linii.

Poniższy skrypt szuka standardowych komentarzy mysqldump, które wskazują początek docelowej bazy danych lub tabeli (np. -- Current Database: db„). Gdy znajdzie nasz cel, przełącza flagę, aby rozpocząć zapisywanie tych linii do nowego pliku. Gdy tylko natrafi na początek innej bazy danych lub tabeli, wyłącza zapis.

Oto kompletny skrypt:

PHP

<?php
ini_set('memory_limit', '2G');

$inputFile = 'dump_5GB.sql';
$outputFile = 'db_fragment.sql';
$targetName = 'db';

$in = fopen($inputFile, 'r');
$out = fopen($outputFile, 'w');

$isExtracting = false;

while (($line = fgets($in)) !== false) {
    if (strpos($line, '-- Current Database: `' . $targetName . '`') === 0 || 
        strpos($line, 'USE `' . $targetName . '`;') === 0) {
        $isExtracting = true;
    } elseif (strpos($line, '-- Current Database: `') === 0 || 
              strpos($line, 'USE `') === 0) {
        $isExtracting = false;
    }

    if (!$isExtracting) {
        if (strpos($line, '-- Table structure for table `' . $targetName . '`') === 0 ||
            strpos($line, '-- Table structure for table `' . $targetName . '_') === 0) {
            $isExtracting = true;
        } elseif (strpos($line, '-- Table structure for table `') === 0) {
            $isExtracting = false;
        }
    }

    if ($isExtracting) {
        fwrite($out, $line);
    }
}

fclose($in);
fclose($out);

Ta metoda utrzymuje zużycie pamięci na ułamkowym poziomie – nie przekraczając kilku megabajtów – i w ciągu kilku sekund przetwarza gigabajty danych SQL.

Lukas Wojcik

Lukas Wojcik

Systems architect and technology enthusiast specializing in scalable tracking solutions, GMP Stack (GA4 & GTM), and robust backend architectures. Advocate for clean code and privacy-first design.

Get in Touch

Briefly describe your project or inquiry for a tailored response. This site is protected by reCAPTCHA.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Wymagane pola są oznaczone *

ALL ARTICLES & CATEGORIES

CCTV

Data Privacy

Digital Analytics

Digital Marketing

IT & Networks

Raspberry Pi

Smart Home

Tutorials

Tutorials

Tutorials

Tutorials

Tutorials

Tworzenie stron internetowych

Wordpress Hacks

Home Sitemap