简体   繁体   English

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

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

Basically I have a database full of tables and I want to go through them all until I find a result that matches my search query. 基本上,我有一个充满表的数据库,我想遍历所有表,直到找到与搜索查询匹配的结果。 Is there a way to do this? 有没有办法做到这一点? Or at least a command to return all of the table names so that I could loop through them until I find the right value? 或者至少是一个返回所有表名的命令,以便我可以遍历它们直到找到正确的值?

thanks! 谢谢!

Aaah, search engines. Aaah,搜索引擎。 Exciting subject, but I would rather build something with internal intelligence rather than using brute force solution. 令人兴奋的主题,但我宁愿使用内部智能构建某些东西,也不愿使用强力解决方案。 Yes - checking every table/column in database is brute force and may result in sluggishness and false positives. 是的-检查数据库中的每个表/列都是蛮力的,可能会导致反应迟钝和误报。

Let me present you with something I would use instead. 让我向您介绍一些我会用的东西。 With below solution each table/column worth scanning needs to be added manually, but everything else is automatic. 使用以下解决方案时,需要手动添加每个值得扫描的表/列,但其他所有操作都是自动的。 Here's the usage: 这是用法:

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

And here's how it was implemented: 这是它的实现方式:

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

Let's analyse example output: 让我们分析示例输出:

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

From the table above you can figure out that phrase "austin" was found in table users , column login (primary key 276) and column last_name (primary key 1782). 从上表中可以看出,在表users ,列login (主键276)和列last_name (主键1782)中找到了短语“奥斯丁”。 It was also found in table towns in column name (primary key 71); 在表towns的列name (主键71)中也可以找到它;

Such search result may be sufficient for you. 这样的搜索结果可能对您来说足够了。 Or else, you can further process the list to select full row from each table: 否则,您可以进一步处理列表以从每个表中选择整行:

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

This way you will end up with full search result (as opposed to intermediate results from previous table): 这样,您将获得完整的搜索结果(与上表中的中间结果相反):

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

Because current implementation is restricted to fixed comparison operator (WHERE field = value), you may want to introduce some flexibility here. 由于当前实现仅限于固定比较运算符(WHERE字段=值),因此您可能要在此处引入一些灵活性。 If so, search operator needs to be delegated to external class and injected into search() function: 如果是这样,则需要将搜索运算符委派给外部类并将其注入到search()函数中:

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

Then SearchOperator needs to be taken into account by replacing WHERE condition with the below: 然后需要通过将WHERE条件替换为以下内容来考虑SearchOperator

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

Now let's focus on SearchOperator implementation. 现在,让我们关注SearchOperator实现。 Since operator implementation provides only one method, namely toSQL , we don't need full class, or even abstract class. 由于操作员实现仅提供一种方法,即toSQL ,因此我们不需要完整的类,甚至不需要抽象类。 Interface will suffice in this case: 在这种情况下,接口就足够了:

interface SearchOperator {

    public function toSQL($column, $term);

} // interface SearchOperator

And let's define couple of implementations representing = (equals) and LIKE operators: 让我们定义几个代表= (等于)和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

Naturally, any other implementation is possible - think about classes called StartsWith, EndsWith, or DoesNotContain. 自然,任何其他实现都是可能的-考虑称为StartsWith,EndsWith或DidNotContain的类。

See updated solution usage: 查看更新的解决方案用法:

$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%'

Time to leave some final remarks: 是时候说点最后的话了:

  • Above examples are incomplete. 以上示例是不完整的。 Database querying code was omitted for clarity. 为了清楚起见,省略了数据库查询代码。
  • SQL used in examples does not sanitize input data. 示例中使用的SQL不会清除输入数据。 I strongly urge you to use prepared statements with bound parameters to avoid huge security risk. 我强烈建议您使用带有绑定参数的准备好的语句,以避免巨大的安全风险。
  • Search algorithm presented above is a naive one. 上面介绍的搜索算法是一种幼稚的算法。 Some optimisation can be done (ie grouping queries referring to the same table). 可以进行一些优化(即,将引用同一表的查询分组)。 But don't optimise prematurely - wait until it becomes a real issue. 但是不要过早地进行优化-请等到成为实际问题为止。

Hoping this was helpful. 希望这会有所帮助。

Very bad idea. 好主意。 However, should you need to search all tables (and you are using MySQL) you can get a list with: 但是,如果您需要搜索所有表 (并且您正在使用MySQL),则可以使用以下内容获取列表:

SHOW TABLES;

And then loop through each and (assuming you know the columns) query them. 然后遍历每个(并假设您知道这些列)查询它们。

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

As others have said, it's possible to extract all the tables names and their column names from meta data dictionary. 正如其他人所说,可以从元数据字典中提取所有表名及其列名。 Take a look at the "information_schema" database. 看一下“ information_schema”数据库。 You can get a list of tables which you can then iterate over. 您可以获得表列表,然后可以对其进行迭代。

But chances are you are using the database wrong. 但是可能您使用的数据库错误。 We don't query the database, we query the data model. 我们不查询数据库,而是查询数据模型。 The data model is implemented as a set of tables/views etc. 数据模型被实现为一组表/视图等。

Can you provide us with some background as to why you need to do this? 您能否为我们提供一些背景说明您为什么需要这样做? Maybe there are better alternatives? 也许还有更好的选择?

You can get all the tables in your database with 您可以使用以下命令获取数据库中的所有表

SHOW TABLES;

Then you can loop through the tables and find out the structure for each table with 然后,您可以遍历表并找出每个表的结构

DISPLAY table_name;

But you still would need to have a vague idea about how to query to columns of each table in order to find anything. 但是您仍然需要对如何查询每个表的列以找到任何内容有一个模糊的想法。 So unless you have a more specialized problem, eg al tables have the same known structure, I would agree with the sentiment that you might be using the database wrong and there might be a better way. 因此,除非您有一个更专业的问题(例如,所有表具有相同的已知结构),否则我会同意这样一种观点,即您可能错误地使用了数据库,并且可能会有更好的方法。

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

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

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