Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Jak uzyskać struktury tabeli z pliku .frm przy użyciu PHP?

Tak, przynajmniej część informacji można odzyskać. (Z korzyścią dla innych czytelników osoba zadająca pytanie jest już świadoma, że ​​istnieją łatwiejsze sposoby uzyskania metadanych kolumny).

Wyzwanie polega na tym, że pliki .frm nie są tak dobrze udokumentowane, ponieważ jakakolwiek potrzeba ich odszyfrowania przez ogólną społeczność jest dość rzadka. Również format plików może się różnić w zależności od systemu operacyjnego.

Jednak przeglądając pliki za pomocą hexdump lub podobnego narzędzia, możesz częściowo zobaczyć, co się dzieje. W takim razie lepiej poinformuj, aby przeczytać pliki w programie PHP i zdekodować surowe dane binarne.

Zrobiłem to jako ćwiczenie jakiś czas temu i udało mi się odzyskać liczbę kolumn, nazwy kolumn i typy kolumn.

Poniżej znajduje się przykład pokazujący, jak wyodrębnić nazwy kolumn. Mój .frm był dla tabeli z nazwami "przystanki", ale możesz zastąpić swój własny .frm.

<?php
$fileName = "stops.frm";

// read file into an array of char
//---------------------------------
$handle = fopen($fileName, "rb");
$contents = fread($handle, filesize($fileName));
fclose($handle);
$fileSize=strlen($contents);  // save the filesize fot later printing

// locate the column data near the end of the file
//-------------------------------------------------
$index = 6;    // location of io_size
$io_size_lo = ord($contents[$index]);  
$io_size_hi = ord($contents[$index+1]);
$io_size = $io_size_hi *0x100 + $io_size_lo; // read IO_SIZE

$index = 10;  // location of record length
$rec_len_lo = ord($contents[$index]);
$rec_len_hi = ord($contents[$index+1]);
$rec_len = $rec_len_hi * 0x100 + $rec_len_lo; // read rec_length

// this formula uses io_size and rec_length to get to column data
$colIndex = ( (  (($io_size + $rec_len)/$io_size)   + 1) * $io_size ) + 258;
$colIndex -= 0x3000;   // this is not documented but seems to work!

// find number of columns in the table
//------------------------------------------------- 
echo PHP_EOL."Col data at 0x".dechex($colIndex).PHP_EOL;
$numCols = ord($contents[$colIndex]);

//Extract the column names
//--------------------------------------
$colNameIndex = $colIndex+0x50;   //0X50 by inspection
echo "Col names at 0x".dechex($colNameIndex).PHP_EOL;
$cols=array();
for ($col = 0; $col < $numCols; $col++){
    $nameLen = ord($contents[$colNameIndex++]);          // name length is at ist posn
    $cols[]['ColumnName']= substr($contents,$colNameIndex,$nameLen-1); // read the name
    $colNameIndex+=$nameLen+2;        // skip ahead to next name (2 byte gap after \0)
}
print_r($cols);

To powinno Cię zacząć. Dodam do tego, gdy będę miał czas w nadchodzących dniach, jeśli uważasz, że zmierza we właściwym kierunku.

EDYTUJ. Zaktualizowałem kod, więc powinien działać dla dowolnego pliku .frm (z tabeli). Na pewno jest darmowe narzędzie do odzyskiwania mySQL (oparte na silniku innoDB) dostępne pod adresem https:// /github.com/twindb/undrop-for-innodb . Po przeczytaniu kodu i powiązanych blogów nie używają plików .FRM do odzyskiwania. Te same informacje o tabeli są również przechowywane w słowniku innoDB i używają ich do odzyskiwania formatów tabel itp.

Istnieje również sposób na odczytanie zawartości plików .FRM. Jest to opisane tutaj https://twindb.com /jak-odzyskać-strukturę-tabeli-z-frm-files-online/ . Jednak używają mySQL do odczytywania plików .frm i odtwarzania z nich tabel.

Istnieje również narzędzie pakiet narzędzi, które można znaleźć tutaj https://www .mysql.com/why-mysql/presentations/mysql-utilities/ zawierający czytnik .frm. Zostało to wykonane przez firmę Oracle, która jako jedyna zna format plików .frm! Narzędzie jest bezpłatne, więc możesz je pobrać.

Oracle publikuje informacje na temat formatu plików .frm https://dev.mysql.com/doc/internals/en/frm-file-format.html , ale jest zarówno niekompletny, jak i niepoprawny! Zobacz poprzednie pytanie dotyczące stosu.https://dba.stackexchange.com/questions/208198/mysql-frm-file-format-how-to-extract-column-info

Teraz po tym wszystkim, jeśli nadal chcesz próbować samodzielnie analizować pliki .frm dla zabawy lub nauki, musisz uzbroić się w cierpliwość i poświęcić czas na rozwikłanie dość skomplikowanej struktury. Jeśli chcesz dalej próbować, to jest OK, ale wyślij mi swój plik .FRM (na adres example@sqldat .com ), więc mogę to sprawdzić i za kilka dni wyślę Ci kod PHP, który wydobędzie dodatkowe informacje, takie jak typ danych i rozmiary ekranu.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Kiedy wybrać Oracle zamiast MySQL?

  2. Jak pobrać nazwy tabel w bazie danych mysql za pomocą Pythona i MySQLdb?

  3. WebApp (Tomcat-jdbc) Połączenie z pulą bazy danych zgłaszające wyjątek porzucenia

  4. INSERT INTO Table z wielu tabel

  5. Zapytanie sumujące MYSQL z warunkiem IF