数据库是逻辑容器,表是存储数据的实际单元;数据库仅作分组与权限隔离,表才定义字段、约束并存放业务数据,建表前必须use指定数据库。

数据库是容器,表是里面装数据的抽屉
数据库(database)本身不存具体业务数据,它只是一个逻辑分组和权限边界——就像一个带锁的文件柜;而表(table)才是实际存数据的地方,相当于柜子里一个个贴了标签的抽屉。你不能往“数据库”里直接插一条用户记录,必须指定到某张表,比如 users 或 orders。
- 一个 mysql 实例可创建多个数据库,彼此完全隔离(权限、字符集、日志都独立)
- 每个数据库下可以建零个或多个表,但一张表只能属于一个数据库
-
DROP DATABASE会连同里面所有表、视图、存储过程一并清空,不可逆 - 误操作常见于:连错库(
USE没执行)却在默认库建表,结果表建到了information_schema或mysql系统库下
建库和建表的命令分工很明确
建库只管命名、字符集和校对规则;建表才真正定义字段、类型、约束和索引。两者语法层级不同,不能混用。
- 建库示例:
CREATE DATABASE app_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;—— 这里不涉及任何字段或数据 - 建表必须在某个库内执行:
USE app_db;后才能运行CREATE TABLE users (id int PRIMARY KEY, name varCHAR(50)); - 如果跳过
USE直接建表,MySQL 会报错:Error 1046 (3D000): No database selected - 表名支持库前缀写法:
app_db.users,但数据库名不能用点号,也不能嵌套
物理文件层面,库和表的落盘方式完全不同
MySQL 8.0+ 中,数据库对应磁盘上的一个目录,而每张 InnoDB 表(非共享表空间模式)对应一个独立的 .ibd 文件。这种映射关系直接影响备份、迁移和权限控制。
- 数据库目录路径类似:
/var/lib/mysql/app_db/;里面能看到users.ibd、products.ibd等文件 -
.ibd文件同时包含数据和索引,删掉它 = 表数据彻底丢失(即使frm文件还在也没用) - MyISAM 引擎则拆成三个文件:
.MYD(数据)、.MYI(索引)、.frm(表结构),但 MySQL 8.0 已移除.frm - 跨库查询(如
SELECT * FROM db1.users JOIN db2.logs)完全合法,但要注意账号是否有两个库的SELECT权限
权限粒度差异决定运维习惯
MySQL 的权限系统天然按“库 → 表 → 列”逐级细化。给开发账号开权限时,几乎从不直接授全局权限,而是精确到库甚至表。
- 常见授权语句:
GRANT SELECT, INSERT ON app_db.users TO 'dev'@'%';—— 这比ON *.*安全得多 - 无法对“某个数据库里的所有现有及未来表”一键授权;
ON app_db.*只覆盖当前已存在的表 - 视图(
VIEW)和存储过程归属数据库,但调用时可能跨库访问,权限检查发生在执行时刻,不是创建时刻 - 备份工具如
mysqldump默认按库导出:mysqldump app_db > app_db.sql,不会顺手把其他库也拖进来
数据库和表的边界看似简单,但一旦涉及权限分配、备份恢复、跨库查询或引擎切换,就很容易因混淆层级导致数据不可见、权限失效或恢复失败。最常被忽略的一点是:CREATE DATABASE 不等于 USE database,后者才是后续所有 DDL/DML 操作生效的前提。