← 告别mysql_create_db(),PHP中创建数据库的方法 PHP插入数据库记录:告别mysql_query正确使用mysqli与PDO →

PHP创建MySQL表的三种方式:告别mysql_query

原创 2026-05-21 PHP 已有人查阅

还记得早年用PHP开发,操作MySQL数据库几乎是mysql_query()一统天下。但随着PHP 5.5版本开始,官方正式废弃了这个函数,意味着它不该再出现在新的项目里。原因很简单:不安全(容易引发SQL注入)且功能落后

现在,PHP开发者需要转向两个主流选择:

  • mysqli扩展 (MySQL Improved),它同时支持面向过程和面向对象两种写法。

  • PDO扩展 (PHP Data Objects),一个更现在的数据库抽象层。

这篇文章,我们专注于其中一个基础但核心的操作:创建MySQL数据表。我不会只给你甩两段代码,而是会把原理、细节、个人踩坑经验,以及不同场景下该怎么选,都掰扯清楚。

先温习一下:数据库里的“表”到底是个啥?

你可以把表想象成一张Excel电子表格。它由列(字段) 和行(记录) 组成。

  • :定义了数据的结构,比如“用户名”、“邮箱”、“注册时间”。每一列都有严格的数据类型(如VARCHAR文本、INT整数)。

  • :就是每一条具体的数据记录。

每个表在同一个数据库里必须有唯一的名字,并且通常会设置一个主键(Primary Key),用来唯一标识每一行数据,就像每个人的号。

核心定义:CREATE TABLE语句

不管你用mysqli还是PDO,最终执行的SQL命令核心都是CREATE TABLE。一个标准的创建表语句通常长这样:

CREATE TABLE 表名 (
    列名1 数据类型 列属性,
    列名2 数据类型 列属性,
    ...
    PRIMARY KEY (某个列)
);

几个你必须搞懂的列属性(专业名词):

  • NOT NULL: 强制要求这一列在插入数据时不能为空。如果某个字段必须有值(比如用户名),就必须加上它。

  • DEFAULT: 设置默认值。当插入数据时没有给这一列赋值,系统会自动填入你设定的值。

  • UNSIGNED: 专用于数字类型。它表示这一列只能存储0和正数。比如年龄、薪水,用这个能稍微扩展一点正数的范围。

  • AUTO_INCREMENT: 自动递增。通常用在主键ID上。你插入数据时不需要指定ID值,MySQL会自动给你+1,保证每条记录ID唯一。

  • PRIMARY KEY: 主键。这是表的“灵魂”,唯一标识一行记录。一个表只能有一个主键,通常是id列。

方法一:MySQLi(面向过程写法)

这种写法非常直白,适合新手快速理解执行流程,或者在写一个简单的独立脚本时使用。

代码号示例:创建一个简单的员工表 emp_basic

<?php  
$host = 'localhost:3306';    // 数据库地址
$user = 'code_user';         // 你的数据库用户名
$pass = 'SafePass2026';      // 你的数据库密码
$dbname = 'company_db';      // 你要操作的数据库名

// 1. 建立连接
$conn = mysqli_connect($host, $user, $pass, $dbname);

// 2. 检查连接
if(!$conn){  
    die('连接挂了: ' . mysqli_connect_error());    
}  
echo 'Connected successfully<br/>';  

// 3. 编写建表SQL (id自增,作为主键;姓名和薪水不能为空)
$sql = "CREATE TABLE emp_basic (
    id INT AUTO_INCREMENT,
    name VARCHAR(20) NOT NULL,    
    salary INT NOT NULL, 
    PRIMARY KEY (id)
)";  

// 4. 执行查询
if(mysqli_query($conn, $sql)){    
    echo "Table emp_basic created successfully";    
} else {    
    echo "创建失败: " . mysqli_error($conn);    
}    

// 5. 关闭连接
mysqli_close($conn);    
?>  

个人经验分享:用这种方式,最容易出问题的地方在于第4步。如果你之前执行过别的SQL语句有残留,或者表名已经存在,mysqli_error($conn) 是你很好的调试朋友。新手一定要学会看这个函数返回的错误信息。

核心注意点:这种面向过程的方法,函数都在全局空间,小项目很灵活,但项目一大,代码就容易变得杂乱,不好维护。

方法二:MySQLi(面向对象写法)

这种写法更结构化,是很多PHP开发者在进阶时的选择。它和上面实现的功能一样,但代码组织和可读性更优。

代码号示例:创建一个详细的用户表 users_profile

<?php  
$servername = "localhost";  
$username = "code_user";  
$password = "SafePass2026";  
$dbname = "company_db";  

// 1. 创建连接对象
$conn = new mysqli($servername, $username, $password, $dbname);  

// 2. 检查连接
if ($conn->connect_error) {  
    die("连接失败: " . $conn->connect_error);  
}  

// 3. 编写建表SQL,这次加点新东西:UNSIGNED和TIMESTAMP
$sql = "CREATE TABLE users_profile (  
    user_id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,  -- UNSIGNED确保ID不为负
    fullname VARCHAR(30) NOT NULL,  
    email VARCHAR(50) NOT NULL,
    last_login TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP -- 记录之后登录时间
)";  

// 4. 执行查询
if ($conn->query($sql) === TRUE) {  
    echo "Table users_profile created successfully";  
} else {  
    echo "创建出错: " . $conn->error;  
}  

// 5. 关闭连接
$conn->close();  
?>  

对核心内容的个人见解

  • 看,->query() 和之前的 mysqli_query() 本质一样,但写法更符合“对象”的思维方式。

  • TIMESTAMP 类型配合 DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP 是一个非常实用的技巧。当插入新用户时,它会自动设为当前时间;每次更新该行记录时,这个字段又会自动更新为新时间。这对于记录“之后修改时间”或“之后活动时间”简直太方便了,省了你每次手动写时间戳的麻烦。

本节课程知识要点:当你需要在一个中型项目里封装数据库操作类,或者希望代码风格统一(都用对象->方法的形式)时,mysqli的面向对象写法比面向过程更合适。

方法三:PDO(PHP数据对象)

PDO是我个人在大部分项目中更偏爱的选择。它较大的价值不是写法,而是数据库抽象。你的代码几乎不用改动,就能从MySQL切换到PostgreSQL或SQLite。这一点是mysqli做不到的。

代码号示例:同样创建 users_profile 表,但使用PDO

<?php  
$servername = "localhost";  
$username = "code_user";  
$password = "SafePass2026";  
$dbname = "company_db_pdo";  // 假设这是另一个库

try {  
    // 1. 创建PDO连接实例
    $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);  
    
    // 2. 设置PDO错误模式为异常,这非常重要
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);  
    
    // 3. 同样的SQL建表语句
    $sql = "CREATE TABLE users_profile (  
        user_id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,  
        fullname VARCHAR(30) NOT NULL,  
        email VARCHAR(50) NOT NULL,
        reg_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    )";  
    
    // 4. 执行SQL (exec()用于没有结果集返回的语句,如CREATE, INSERT, UPDATE)
    $conn->exec($sql);  
    echo "Table users_profile created successfully in PDO db";  
    
} catch(PDOException $e) {  
    // 5. 异常捕获,打印错误信息
    echo "SQL执行失败: " . $sql . "<br>" . $e->getMessage();  
}  

// 6. 关闭连接
$conn = null;  
?>  

为什么我建议你多关注PDO?

  1. 异常处理:你看上面用了try-catch。在大型应用中,这比if-else判断返回false要优雅和健壮得多。你可以把错误统一记录到日志,而不是直接展示给用户。

  2. 预处理语句:虽然建表示例没体现,但这是PDO最核心的杀手锏。它能彻底杜绝SQL注入问题。这是当年mysql_query被废弃的首要原因。

  3. 命名占位符:PDO的预处理支持:username这种命名占位符,比mysqli只能用?可读性高太多了。

一个你必须知道的区别:PDO执行CREATE TABLE这种DDL语句时,用的是$conn->exec()。而执行有结果返回的查询(如SELECT)时,要用$conn->query()

到底该怎么选?

别纠结,给你一个主观但实用的建议:

  • 你要是刚入门,为了看懂老代码或写一个几十行的小工具:用 MySQLi 面向过程。因为它最直观,和你看到的很多旧教程能对上。

  • 你要做一个标准的公司或个人项目:直接上 PDO。别犹豫。它带来的安全性和数据库迁移灵活性,绝对值回你多学的那一点点成本。这不只是赶时髦,是给未来的维护工作“减负”。

  • 你维护的遗留项目里到处是面向对象的MySQLi:那就保持一致,用 MySQLi 面向对象。没必要为了用PDO而强行重构整个项目。

之后再强调一句:忘掉mysql_query吧。现在任何一本2026年的PHP教程、任何一个上线的商业项目,如果还用它,那就是在制造技术债务。mysqli和PDO才是当下和未来一段时期内的主流。

← 告别mysql_create_db(),PHP中创建数据库的方法 PHP插入数据库记录:告别mysql_query正确使用mysqli与PDO →
分享笔记 (共有 篇笔记)
验证码:
微信公众号