Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Làm cách nào để lấy cấu trúc bảng từ tệp .frm bằng PHP?

Có, nó có thể khôi phục ít nhất một phần thông tin. (Vì lợi ích của những người đọc khác, người đặt câu hỏi đã biết rằng có nhiều cách dễ dàng hơn để lấy siêu dữ liệu cột).

Thách thức là các tệp .frm không được ghi chép đầy đủ vì mọi nhu cầu giải mã chúng bởi cộng đồng nói chung là khá hiếm. Ngoài ra, định dạng của các tệp có thể thay đổi theo hệ điều hành.

Tuy nhiên, bằng cách xem các tệp bằng hexdump hoặc một tiện ích tương tự, bạn có thể thấy phần nào những gì đang xảy ra. Sau đó, bạn được thông báo tốt hơn để đọc các tệp trong chương trình PHP và giải mã dữ liệu nhị phân thô.

Tôi đã làm điều này như một bài tập cách đây một thời gian và tôi đã có thể khôi phục số lượng cột, tên cột và loại cột.

Dưới đây là một mẫu để hiển thị cách trích xuất tên cột. .Frm của tôi dành cho tên bảng là "điểm dừng", nhưng bạn có thể thay thế .frm của riêng mình.

<?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);

Điều này sẽ giúp bạn bắt đầu. Tôi sẽ bổ sung điều này khi có thời gian trong những ngày tới nếu bạn cho rằng mình đang đi đúng hướng.

CHỈNH SỬA. Tôi đã cập nhật mã để nó hoạt động với bất kỳ tệp .frm nào (từ Bảng). Để chắc chắn rằng có một công cụ miễn phí để khôi phục mySQL (dựa trên công cụ innoDB) có sẵn tại https:/ /github.com/twindb/undrop-for-innodb . Sau khi đọc qua mã và các blog được liên kết, họ không sử dụng tệp .FRM để khôi phục. Thông tin bảng tương tự cũng được lưu trữ trong từ điển innoDB và họ đang sử dụng thông tin này để khôi phục các định dạng bảng, v.v.

Ngoài ra còn có một cách để đọc nội dung tệp .FRM. Điều này được mô tả tại đây https://twindb.com / how-to-recovery-table-structure-from-frm-files-online / . Tuy nhiên, họ đang sử dụng mySQL để đọc các tệp .frm và tạo lại các bảng từ đó.

Ngoài ra còn có một tiện ích là một gói tiện ích được tìm thấy ở đây https://www.mysql-utilities/"> https:// www .mysql.com / why-mysql / Presentation / mysql-extensions / có chứa trình đọc .frm. Điều này được thực hiện bởi Oracle, những người duy nhất biết định dạng của tệp .frm! Tiện ích này miễn phí nên bạn có thể tải xuống.

Oracle công bố một số thông tin về định dạng của tệp .frm https://dev.mysql.com/doc/internals/en/frm-file-format.html , nhưng nó vừa không đầy đủ vừa không chính xác! Xem câu hỏi trước về Stack này. https://dba.stackexchange.com/questions/208198/mysql-frm-file-format-how-to-extract-column-info

Sau tất cả, nếu bạn vẫn muốn tự mình phân tích cú pháp các tệp .frm để giải trí hoặc để học, thì bạn cần phải kiên nhẫn và dành thời gian để làm sáng tỏ cấu trúc khá phức tạp. Nếu bạn muốn tiếp tục thử vẫn được nhưng hãy gửi cho tôi tệp .FRM của bạn (tới example @ sqldat"> example @ sqldat .com ) để tôi có thể kiểm tra và tôi sẽ gửi cho bạn một số mã PHP trong vài ngày tới sẽ trích xuất một số thông tin bổ sung như kiểu dữ liệu và kích thước hiển thị.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL chuyển đổi Bằng, Phút, Giây sang Độ thập phân

  2. Thực thi nhiều truy vấn xóa sql trong mysql cho php

  3. Lỗi SQL 1406 Dữ liệu quá dài cho cột

  4. xóa liên kết không xóa bất kỳ bản ghi nào trong cơ sở dữ liệu mysql

  5. SQL:Làm cách nào để giữ thứ tự các hàng với DISTINCT?