繁体   English   中英

有没有一种方法可以搜索mySQL数据库中的所有表?

[英]Is there a way to search all the tables in a mySQL database?

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

谢谢!

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)中找到了短语“奥斯丁”。 在表towns的列name (主键71)中也可以找到它;

这样的搜索结果可能对您来说足够了。 否则,您可以进一步处理列表以从每个表中选择整行:

$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字段=值),因此您可能要在此处引入一些灵活性。 如果是这样,则需要将搜索运算符委派给外部类并将其注入到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或DidNotContain的类。

查看更新的解决方案用法:

$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不会清除输入数据。 我强烈建议您使用带有绑定参数的准备好的语句,以避免巨大的安全风险。
  • 上面介绍的搜索算法是一种幼稚的算法。 可以进行一些优化(即,将引用同一表的查询分组)。 但是不要过早地进行优化-请等到成为实际问题为止。

希望这会有所帮助。

好主意。 但是,如果您需要搜索所有表 (并且您正在使用MySQL),则可以使用以下内容获取列表:

SHOW TABLES;

然后遍历每个(并假设您知道这些列)查询它们。

我猜您可以为此使用Mysql的全文搜索吗?

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

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

您能否为我们提供一些背景说明您为什么需要这样做? 也许还有更好的选择?

您可以使用以下命令获取数据库中的所有表

SHOW TABLES;

然后,您可以遍历表并找出每个表的结构

DISPLAY table_name;

但是您仍然需要对如何查询每个表的列以找到任何内容有一个模糊的想法。 因此,除非您有一个更专业的问题(例如,所有表具有相同的已知结构),否则我会同意这样一种观点,即您可能错误地使用了数据库,并且可能会有更好的方法。

ridona有一个不错的图书馆,可以读取所有表格

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM