【问题标题】:How can I check if a MySQL table exists with PHP?如何使用 PHP 检查 MySQL 表是否存在?
【发布时间】:2011-09-19 21:41:56
【问题描述】:

理论上听起来很简单,但我已经进行了大量研究,但无法弄清楚这一点。

如何检查 MySQL 表是否存在以及它是否确实执行了某些操作。 (我想一个简单的 php if/else 语句可以解决这个问题)

有没有办法做到这一点?

这是我对 cwallenpoole 的回复所做的:

mysql_connect("SERVER","USERNAME","PASSWORD");
mysql_select_db('DATABASE');

$val = mysql_query('select 1 from `TABLE`');

if($val !== FALSE)
{
   print("Exists");
}else{
   print("Doesn't exist");
}

【问题讨论】:

  • 在做出最终答案之前,请阅读我的基准测试。
  • 请注意,如果您尝试检查表是否存在以便添加它,如果它不存在,您可以使用类似CREATE TABLE IF NOT EXISTS `my_table`的查询

标签: php mysql if-statement


【解决方案1】:
// Select 1 from table_name will return false if the table does not exist.
$val = mysql_query('select 1 from `table_name` LIMIT 1');

if($val !== FALSE)
{
   //DO SOMETHING! IT EXISTS!
}
else
{
    //I can't find it...
}

诚然,它比 PHP 惯用语更 Pythonic,但另一方面,您不必担心处理大量额外数据。

编辑

因此,在我撰写此消息时,此答案至少已被标记两次。假设我犯了一些巨大的错误,我跑了一些benchmarks,这就是我发现当表不存在时,我的解决方案比最接近的替代方案快 10% 以上,并且快 25% 以上当表确实存在时:

:::::::::::::::::::::::::BEGINNING NON-EXISTING TABLE::::::::::::::::::::::::::::::
23.35501408577 for bad select
25.408507823944 for select from schema num rows -- calls mysql_num_rows on select... from information_schema.
25.336688995361 for select from schema fetch row -- calls mysql_fetch_row on select... from information_schema result
50.669058799744 for SHOW TABLES FROM test
:::::::::::::::::::::::::BEGINNING EXISTING TABLE::::::::::::::::::::::::::::::
15.293519973755 for good select
20.784908056259 for select from schema num rows
21.038464069366 for select from schema fetch row
50.400309085846 for SHOW TABLES FROM test

我尝试对 DESC 运行此命令,但 276 秒后超时(我的回答为 24 秒,276 秒无法完成对不存在表的描述)。

为了更好地衡量,我正在针对其中只有四个表的架构进行基准测试,这是一个几乎全新的 MySQL 安装(这是迄今为止唯一的数据库)。要查看导出,请查看here

还有更多

这个特殊的解决方案也更加独立于数据库,因为相同的查询可以在 PgSQL 和 Oracle 中工作。

终于

mysql_query() 对于不是“此表不存在”的错误返回 FALSE。

如果需要保证表存在,使用mysql_errno()获取错误码并与相关的MySQL errors比较。

【讨论】:

  • 好的,我明白了。 !== FALSE 表示该表存在(答案已更新)。这是我的测试:mysql_select_db('test', $c);if(mysql_query( 'SELECT 1 FROM foo' ) !== FALSE) echo 'foo';if(mysql_query( 'SELECT 1 FROM bar' ) !== FALSE) echo 'bar'; foo 不存在,bar 存在。我将“条形”输出到浏览器。
  • 那里,我再次将其反弹为积极的 +1。
  • @j-j-kim 虽然我同意mysql_query 有点过时,但这是我在编写答案时使用的原始函数,它与 pastebin 代码使用的函数相同。为了保持一致性,我宁愿保持原样。
  • 注意:这也是 Drupal 处理事情的方式。
  • mysql_query() 出错时返回 false,因此请在假设 false 表示“表不存在”之前检查错误。错误代码 1146 和 1051 是检查“未知表”的代码:dev.mysql.com/doc/refman/5.1/en/error-messages-server.html
【解决方案2】:

在 PHP 中实现此目的的最简洁方法是简单地使用 DESCRIBE 语句。

if ( mysql_query( "DESCRIBE `my_table`" ) ) {
    // my_table exists
}

我不确定为什么其他人会针对这样一个直截了当的问题发布复杂的查询。

更新

使用 PDO

// assuming you have already setup $pdo
$sh = $pdo->prepare( "DESCRIBE `my_table`");
if ( $sh->execute() ) {
    // my_table exists
} else {
    // my_table does not exist    
}

【讨论】:

  • 这是最慢的解决方案。
  • @MichalM 感谢您富有洞察力的评论。让我们玩一个叫做“把钱放在嘴边”的游戏。我什至不会提到你应该缓存结果的事实,但让我们继续。我们可以吗?
  • "已弃用:mysql_query():mysql 扩展已弃用,将来将被删除:改用 mysqli 或 PDO"
  • @IberoMedia 问题是针对 mysql_* 扩展的,并且是从 2011 年开始的......您可以对 mysqli_* 使用相同的方法。
  • @AlekseyKorzun 你能提供你的实际测试(和 MySQL 版本)吗?
【解决方案3】:
$res = mysql_query("SELECT table_name FROM information_schema.tables WHERE table_schema = '$databasename' AND table_name = '$tablename';");

如果没有返回记录则不存在。

【讨论】:

  • 如何查看记录是否返回?
  • 请检查我的基准,因为这似乎不是最快的
【解决方案4】:

125 微秒表存在检查

.000125 秒。 (125µs)

mysql_unbuffered_query("SET profiling = 1");  // for profiling only

@mysql_unbuffered_query("SELECT 1 FROM `table` LIMIT 1 ");
if (mysql_errno() == 1146){

 // NO EXISTING TABLE CODE GOES HERE

}
elseif(mysql_errno() > 0){

  echo mysql_error();    

}

$results = mysql_query("SHOW PROFILE");  // for profiling only

执行时间,使用 mysql 分析测量,当一个表存在或不存在时,大约是 .000125 秒。 (125µs)

LIMIT 1 对速度很重要。这最大限度地减少了排序结果和发送数据查询状态时间。桌子大小不是一个因素。

当不需要结果时,我总是使用无缓冲查询。

个人资料结果 当表格不存在时

QUERY STATE           SECONDS   
--------------------  -------
starting              0.000025  
checking permissions  0.000006  
Opening tables        0.000065  
query end             0.000005  
closing tables        0.000003  
freeing items         0.000013  
logging slow query    0.000003  
cleaning up           0.000003  
TOTAL                 0.000123  <<<<<<<<<<<< 123 microseconds

表存在时

QUERY STATE           SECONDS   
--------------------  -------
starting              0.000024
checking permissions  0.000005
Opening tables        0.000013
System lock           0.000007
init                  0.000006
optimizing            0.000003
statistics            0.000009
preparing             0.000008
executing             0.000003
Sending data          0.000019
end                   0.000004
query end             0.000004
closing tables        0.000006
freeing items         0.00001
logging slow query    0.000003
cleaning up           0.000003
TOTAL                 0.000127 <<<<<<<<<<<< 127 microseconds

【讨论】:

    【解决方案5】:
    mysql_query("SHOW TABLES FROM yourDB");
    //> loop thru results and see if it exists
    //> in this way with only one query one can check easly more table 
    

    mysql_query("SHOW TABLES LIKE 'tblname'");

    不要使用mysql_list_tables();,因为它已被弃用

    【讨论】:

    • 如果你有 500 多个表,那将是很多迭代
    • @Nathan:有 500 张桌子的人不会问如何检查这个
    • @Nathan:你也可以添加 LIKE ''。
    • @kevmo:永远不要使用它。此功能已弃用。
    【解决方案6】:

    显示像“表名”这样的表

    如果您有任何结果,则该表存在。

    要在 PDO 中使用这种方法:

    $pdo         = new \PDO(/*...*/);
    $result      = $pdo->query("SHOW TABLES LIKE 'tableName'");
    $tableExists = $result !== false && $result->rowCount() > 0;
    

    将此方法与已弃用的 mysql_query 一起使用

    $result      = mysql_query("SHOW TABLES LIKE 'tableName'");
    $tableExists = mysql_num_rows($result) > 0;
    

    【讨论】:

    • MySQL 文档建议查看架构信息
    • 是的,我可能从 3.23 天开始就太老了 :)
    • 如何检查结果?
    • @NathanRomano 文档并不意味着我们受到限制。通过执行 -> $table_exists = $pdo-&gt;query( 'SHOW TABLES LIKE 'tableName' ); var_dump( $table_exists ); 如果表存在则输出 true,否则为 false。
    • 我喜欢这种方法
    【解决方案7】:

    比错误查询还要快:

    SELECT count((1)) as `ct`  FROM INFORMATION_SCHEMA.TABLES where table_schema ='yourdatabasename' and table_name='yourtablename';
    

    这样你可以只检索一个字段和一个值。我较慢的系统需要 0.016 秒。

    【讨论】:

    • 我最喜欢这个,我只想要一个快速简单的“是/否”。
    • 您还可以检查多个表: SELECT count((1)) as ct FROM INFORMATION_SCHEMA.TABLES where table_schema ='yourdatabasename' and ( table_name='yourtablename' or table_name='yourtablename1'或 table_name='yourtablename2' );
    【解决方案8】:

    它已经发布了,但这里是 PDO(相同的查询)...

    $connection = new PDO ( "mysql:host=host_db; dbname=name_db", user_db, pass_db );
    
    if ($connection->query ("DESCRIBE table_name"  )) {
        echo "exist";
    } else {
        echo "doesn't exist";
    }
    

    对我来说就像一个魅力......

    这是另一种方法(我认为它更慢)...

    if ($connection->query ( "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = 'db_name' AND table_name ='tbl_name'" )->fetch ()) {
        echo "exist";
    } else {
        echo "doesn't exist";
    }
    

    你也可以玩这个查询:

    SHOW TABLE STATUS FROM db_name LIKE 'tbl_name'
    

    我认为这是建议在 mysql 页面中使用。

    【讨论】:

      【解决方案9】:

      不要再使用 MYSQL。如果你必须使用mysqli但PDO是最好的:

      $pdo = new PDO($dsn, $username, $pdo); // proper PDO init string here
      if ($pdo->query("SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = 'db_name'")->fetch()) // table exists.
      

      【讨论】:

      • 对于 PHP 版本为 5.5.0 或更高版本的新项目,使用 mysql 不是一个好主意。 Deprecated 表示可能在未来的 PHP 版本中不复存在。
      • 是的,从 7 开始,该功能不再存在。
      【解决方案10】:

      或者你可以使用

      显示 Tables_in_{insert_db_name}='tablename' 的表;

      【讨论】:

        【解决方案11】:

        您可以使用许多不同的查询来检查表是否存在。下面是几个之间的比较:

        mysql_query('select 1 from `table_name` group by 1'); or  
        mysql_query('select count(*) from `table_name`');
        
        mysql_query("DESCRIBE `table_name`");  
        70000   rows: 24ms  
        1000000 rows: 24ms  
        5000000 rows: 24ms
        
        mysql_query('select 1 from `table_name`');  
        70000   rows: 19ms  
        1000000 rows: 23ms  
        5000000 rows: 29ms
        
        mysql_query('select 1 from `table_name` group by 1'); or  
        mysql_query('select count(*) from `table_name`');  
        70000   rows: 18ms  
        1000000 rows: 18ms  
        5000000 rows: 18ms  
        

        这些基准只是平均值:

        【讨论】:

        【解决方案12】:
        <?php 
        $connection = mysqli_connect("localhost","root","","php_sample_login_register"); 
        
        if ($connection){
                echo "DB is Connected <br>";
                $sql = "CREATE TABLE user(
                    id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY, 
                    name VARCHAR(255)NOT NULL,
                    email VARCHAR(255)NOT NULL,
                    password VARCHAR(255) NOT NULL
                    );";
                if(mysqli_query($connection,$sql)) {
                    echo "Created user table";
                } else{
                    echo "User table already exists";
                }
            } else {
                echo "error : DB isnot connected";
            } ?>
        

        【讨论】:

        • 虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-21
        • 2014-08-07
        • 1970-01-01
        • 2012-12-21
        • 1970-01-01
        相关资源
        最近更新 更多