sql >> データベース >  >> RDS >> Mysql

PHPを使用して.frmファイルからテーブル構造を取得するにはどうすればよいですか?

    はい、情報の少なくとも一部を回復することは可能です。 (他の読者の利益のために、質問の提起者は、列のメタデータを取得するより簡単な方法があることをすでに知っています。)

    課題は、一般的なコミュニティが.frmファイルを解読する必要が非常にまれであるため、.frmファイルが十分に文書化されていないことです。また、ファイルの形式はオペレーティングシステムによって異なる場合があります。

    ただし、hexdumpまたは同様のユーティリティを使用してファイルを表示すると、何が起こっているかを部分的に確認できます。次に、PHPプログラムでファイルを読み取り、生のバイナリデータをデコードするように通知します。

    しばらく前にこれを演習として行い、列の数、列名、列タイプを復元することができました。

    以下は、列名を抽出する方法を示すサンプルです。私の.frmは「stops」という名前のテーブル用でしたが、独自の.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);
    

    これで始められるはずです。正しい方向に向かっていると思われる場合は、今後数日のうちに時間があれば、これに追加します。

    編集。 コードを更新して、(表の)すべての.frmファイルで機能するようにしました。確かに、mySQL(innoDBエンジンに基づく)を回復するための無料のツールが https:/にあります。 /github.com/twindb/undrop-for-innodb 。コードと関連するブログを読んだ後、彼らは回復のために.FRMファイルを使用していません。同じテーブル情報もinnoDBディクショナリに格納されており、テーブル形式などを復元するためにこれを使用しています。

    .FRMファイルの内容を読み取る方法もあります。これについては、ここで説明します https://twindb.com / how-to-recover-table-structure-from-frm-files-online / 。ただし、彼らはmySQLを使用して.frmファイルを読み取り、そこからテーブルを再作成しています。

    ここには、ユーティリティのパッケージであるユーティリティもあります。 https:// www .mysql.com / why-mysql / projects / mysql-utilities / .frmリーダーが含まれています。これは、.frmファイルの形式を知っている唯一の人物であるOracleによって作成されました。ユーティリティは無料なので、ダウンロードできます。

    Oracleは、.frmファイルの形式に関する情報を公開しています https: //dev.mysql.com/doc/internals/en/frm-file-format.html 、しかしそれは不完全で間違っています!この前のスタックの質問を参照してください。 https://dba.stackexchange.com/questions/208198/mysql-frm-file-format-h​​ow-to-extract-column-info

    それでも、楽しみや学習のために.frmファイルを自分で解析したい場合は、辛抱強く、非常に複雑な構造を解明するために時間を費やす必要があります。引き続き試してみたい場合は、.FRMファイルを送ってください( example @ sqldat .com )それで私はそれをチェックすることができます、そして私はあなたにデータ型と表示サイズのようないくつかの追加情報を抽出するいくつかのPHPコードを数日で送ります。




    1. データベースからcsvファイルにテーブルをエクスポートします

    2. 整数をチェックするSQLLIKE条件?

    3. pyodbcおよびMSSQLServerとの1つの接続で複数のカーソルを使用できますか?

    4. 正規表現を使用して数字のみを取得する