有没有办法搜索mySQL数据库中的所有表?

时间:2010-12-03 21:20:39

标签: php search mysql search-engine

基本上我有一个充满表格的数据库,我想通过它们直到找到与我的搜索查询匹配的结果。有没有办法做到这一点?或者至少是一个返回所有表名的命令,以便我可以遍历它们直到找到正确的值?

谢谢!

6 个答案:

答案 0 :(得分: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)中找到了短语“austin”。在列towns(主键71)中的表name中也可以找到它;

这样的搜索结果可能就足够了。或者,您可以进一步处理列表以从每个表中选择完整行:

$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;

通过这种方式,您将获得完整的搜索结果(而不是上一个表格的中间结果):

id: 276, login: austin, last_name: Powers, email: austin.powers@gmail.com
id: 1782, login: michael, last_name: austin, email: michael.e@gmail.com
id: 71, name: austin, state: texas, country: usa

由于当前实现仅限于固定比较运算符(WHERE field = value),因此您可能需要在此处引入一些灵活性。如果是这样,则需要将搜索运算符委托给外部类并注入search()函数:

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

然后需要通过用以下内容替换WHERE条件来考虑SearchOperator

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

现在让我们关注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 :(得分:1)

非常糟糕的主意。但是,如果您需要搜索all tables(并且您使用的是MySQL),则可以获得一个列表:

SHOW TABLES;

然后循环遍历每个(假设您知道列)查询它们。

答案 2 :(得分:0)

我想你可以使用Mysql的full-text search吗?

答案 3 :(得分:0)

正如其他人所说,可以从元数据字典中提取所有表名及其列名。看一下“information_schema”数据库。您可以获得一个表格列表,然后您可以迭代它们。

但是你可能错误地使用了数据库。我们不查询数据库,我们查询数据模型。数据模型实现为一组表/视图等。

您能否向我们提供一些背景信息,说明您需要这样做的原因?也许有更好的选择?

答案 4 :(得分:0)

您可以使用

获取数据库中的所有表格
SHOW TABLES;

然后,您可以遍历表格并使用

查找每个表格的结构
DISPLAY table_name;

但是你仍然需要对如何查询每个表的列以查找任何内容有一个模糊的想法。因此,除非您有更专业的问题,例如al table具有相同的已知结构,我同意你可能使用数据库错误的情绪,并且可能有更好的方法。

答案 5 :(得分:0)

有一个很好的库可以读取所有表格ridona