2010-12-03 5 views
2

基本的には、テーブルがいっぱいのデータベースがあります。検索クエリと一致する結果が見つかるまで、すべてを調べたいと思います。これを行う方法はありますか?または、私は正しい値を見つけるまで、私はそれらをループすることができるようにすべてのテーブル名を返す少なくともコマンドですか?mySQLデータベース内のすべてのテーブルを検索する方法はありますか?

ありがとうございました!

+1

ridonaは、私は、これは簡単に、動的SQLで行うことができると思います。すべての表名と列名を持ついくつかのメタ表を照会し、その結果セットをループして、必要に応じて表と列を照会します。私はこれがMySQLで実現可能であるとは確信していないので、答えとして投稿していません(私はOracleでも同様の仕組みがあると知っています) – FrustratedWithFormsDesigner

答えて

3

Aaah、検索エンジン。エキサイティングなテーマですが、むしろブルートフォースソリューションを使うよりも、内部のインテリジェンスで何かを作りたいと思っています。はい - データベース内のすべてのテーブル/カラムをチェックすることは無理です。

代わりに使用するものをお教えしましょう。以下のソリューションでは、スキャンに値する各テーブル/列を手動で追加する必要がありますが、それ以外はすべて自動的に行われます。ここでの使用です:

$e = new SearchEngine(); 
$e->addTable('users', 'id', 'login'); // table, primary key name, column to be searched in 
$e->addTable('users', 'id', 'last_name'); 
$e->addTable('towns', 'id', 'name'); 

print_r($e->search('austin')); // we search for exact match for word "austin" 

そして、ここでは、それが実装された方法は次のとおりです。

class SearchEngine { 

    protected $tables = array(); 

    public function addTable($table, $key, $column) { 
     $this->tables[] = array(
      'table' => $table, 
      'key' => $key, 
      'column' => $column 
     ); 
    } 

    public function search($term) { 
     $q = array(); 
     foreach ($this->tables as $t) { 
      list($table, $key, $column) = $t; 
      $q[] = " 
       SELECT 
        $key AS searched_key, 
        '$key' AS searched_key_name, 
        '$table' AS searched_table, 
        '$column' AS searched_column, 
        $column AS searched_value 
       FROM $table 
       WHERE $column = $term 
      "; 
     } 
     $sql = implode(' UNION ', $q); 
     // query the database 
     // return results 
    } 

} // class SearchEngine 

のは、出力例を分析してみましょう:

searched_key | searched_key_name | searched_table | searched_column | searched_value 
-------------+-------------------+----------------+-----------------+--------------- 
     276 |    id | users   | login   | austin 
     1782 |    id | users   | last_name  | austin 
      71 |    id | towns   | name   | austin 

表からは、そのフレーズ「オースティン」を把握することができ、上記表users、列login(主キー276)および列last_name(主キー1782)に見つかりました。列name(プライマリキー71)の表townsにも見つかりました。

このような検索結果で十分です。さもないと、あなたはさらに、各テーブルから行全体を選択するためのリストを処理することができます

id: 276, login: austin, last_name: Powers, email: [email protected] 
id: 1782, login: michael, last_name: austin, email: [email protected] 
id: 71, name: austin, state: texas, country: usa 
:あなたは完全な検索結果(前のテーブルから中間結果ではなく)になってしまいます

$out = array(); 
foreach ($rows as $row) { 
    $sql = " 
     SELECT * FROM {$row['searched_table']} 
     WHERE {$row['searched_key_name']} = {$row['searched_key']} 
     LIMIT 1 
    "; 
    // query the database 
    // append result to $out array 
} 
return $out; 

この方法

現在の実装は固定比較演算子(WHERE field = value)に限定されているため、ここでは柔軟性を導入することをお勧めします。

WHERE {$operator->toSQL($column, $term)} 

今してみましょう:以下との条件は、WHERE置き換えることによって、考慮しなければ

public function search(SearchOperator $operator, $term) { 
... 

その後SearchOperatorニーズ:そう、検索演算子を外部クラスに委譲し、search()機能に注入する必要がある場合SearchOperatorの実装に焦点を当てます。演算子の実装はただ一つのメソッド、すなわちtoSQLを提供するので、私たちは完全なクラス、または抽象クラスを必要としません。

interface SearchOperator { 

    public function toSQL($column, $term); 

} // interface SearchOperator 

をとのが=を表す実装のカップル(等しい)とLIKE演算子を定義してみましょう:インターフェイスは、この場合には十分でしょう

class Equals implements SearchOperator { 

    public function toSQL($column, $term) { 
     return "$column = '$term'"; 
    } 

} // class Equals 

class Like implements SearchOperator { 

    public function toSQL($column, $term) { 
     return "$column LIKE '$term'"; 
    } 

} // class Like 

当然、他の実装が可能である - STARTSWITHと呼ばれるクラスを考え、 EndsWith、またはDoesNotContainです。いくつかの最終的な発言を残して

$e = new SearchEngine(); 
$e->addTable('users', 'id', 'login'); 
$e->addTable('users', 'id', 'last_name'); 
$e->addTable('towns', 'id', 'name'); 

print_r($e->search(new Like(), 'austin%')); // here we search for columns being LIKE 'austin%' 

時間:

が更新ソリューションの使用を参照してください

  • 上記の例は不完全です。明確にするために、データベース照会コードは省略されました。
  • 例で使用されているSQLは入力データをサニタイズしません。巨大なセキュリティリスクを避けるために、バインドされたパラメータで準備されたステートメントを使用することを強くお勧めします。
  • 上記の検索アルゴリズムは単純なものです。いくつかの最適化を行うことができる(すなわち、同じテーブルを参照するクエリをグループ化する)。早めに最適化しないでください。実際の問題になるまで待ってください。

これを参考にしてください。

1

非常に悪い考えです。ただし、all tablesを検索する必要がある必要があります(そして、あなたはMySQLを使用している)あなたがリストを取得することができます。各貫通

SHOW TABLES; 

そしてループをし、それらを照会(あなたが列を知っていると仮定した場合)。

+0

これはなぜ悪い考えですか?それは単にリソース集約的なのでしょうか?データベース全体が2000行以下であるため、比較的小さいです。 – Parker

0

他の人は言っているように、メタデータ辞書からすべてのテーブル名とその列名を抽出することができます。 "information_schema"データベースを見てみましょう。あなたはそれ以上の反復処理が可能なテーブルのリストを得ることができます。

ただし、データベースを間違って使用している可能性があります。我々はデータベースに問い合わせるのではなく、データモデルに問い合わせます。データモデルは、テーブル/ビューなどのセットとして実装されています。

これを行う必要がある理由について私たちにお聞かせください。たぶんもっと良い選択肢がありますか?

0

あなたは次にあなたがテーブルをループし

DISPLAY table_name; 

で各テーブルの構造を調べることができます

SHOW TABLES; 

を使用してデータベース内のすべてのテーブルを取得することができます。しかし、あなたはまだする必要があります何かを見つけるために各テーブルの列に問い合わせる方法について曖昧な考えがあります。あなたがもっと特殊な問題を抱えていない限り、私のテーブルには同じ構造がありますが、データベースを間違って使用している可能性があり、よりよい方法があるかもしれません。

0

は、すべてのテーブルを読み取るための素敵なライブラリがあり、

関連する問題