第四单元 · 概念、类型、改表、分页 · 第 8 / 21 节
先补概念:库、表、数据模型、SQL 分几类
不建表、不改数据,只用只读语句把四层概念摆正:服务器上的库、库里的表、表的行与列;再用系统库的两张表看清“两张表靠一个相同的值对上”的数据模型;最后把 SQL 分成 DDL/DML/DQL/DCL 四类,并说明库这一层为什么只认识不练。
约 18 分钟。这一节不建表、也不改任何数据,只把四个词摆正:库、表、行与列、表和表怎么对上;最后看清 SQL 分成哪四类,其中哪一类这门课只认识、不练。
$ / mysql> 提示符和输出。已完成 0 / 3 步
你现在在哪个提示符
应该在 mysql>。断了就先回到学习终端(PowerShell):
ssh root@8.148.204.152
mysql-learning
进去以后确认当前库:
SELECT DATABASE();
+------------+
| DATABASE() |
+------------+
| itcast |
+------------+
1 row in set (0.00 sec)
显示 itcast 就对了。如果是 NULL,执行 USE itcast;——它只切换当前连接用哪个库,不动数据。
小结:P1 课程介绍——195 集,我们只用前 50 集
这套课在平台上共 195 集,分基础篇、进阶篇、运维篇三块:基础篇是概述、SQL(建表改表、增删改查、函数、约束、多表查询)这些基本操作,进阶篇和运维篇往后走原理与运维。本课程只取基础篇的前 50 集,也就是从课程介绍走到「多表查询-小结」为止,主题是“会连、会建、会改、会查、会分组、会多表”。50 集之后的章节属于进阶与运维,原理性更强,本课程不收,也不在这里等它们(具体章节以平台目录为准,这里不替它列举)。每一节都不播放视频、不引用讲解,只按标题和公开讲义的主题自己动手。
第一步:库、表、行、列——你每天动的到底是哪一层
先说清楚层级。一台 MySQL 服务器(就是那个一直在后台跑的 mysqld 进程)上面可以放好几个库(database);一个库里放好几张表(table);一张表描述同一类东西,表里每一行是一条记录,每一列是这类东西的一个属性。你前面几节一直在 itcast 这个库里给自己建练习表、再往里插行,做的就是“在库里建表、往表里插行”这两件事。
先看这个账号能看到哪些库:
SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| itcast |
| performance_schema |
+--------------------+
3 rows in set (0.00 sec)
这是在只有 itcast.* 权限的账号下实跑的输出(课程账号就是这个范围)。你能看到几个库,取决于这个账号被授了哪些权限:information_schema、performance_schema 一般都能看到,mysql、sys 属于管理员范围,没有额外授权就不会出现在列表里。认准 itcast 就行——只有它是给你练习用的;列表里那几个系统库也照样是“库”,也照样由表组成,只不过存的是服务器自己的信息(有哪些库、有哪些表、有哪些权限)。库的个数可以直接数出来:
SELECT COUNT(*) AS 库个数 FROM information_schema.SCHEMATA;
+-----------+
| 库个数 |
+-----------+
| 3 |
+-----------+
1 row in set (0.00 sec)
information_schema.SCHEMATA 就是系统库里的一张表,一行一个库——上面数出来的那个数就是这个行数,和 SHOW DATABASES 数的是同一批库。注意这里的写法是 库名.表名:同一个服务器上有多个库,写全名才不会找错地方。
那“列”长什么样?看这张系统表的结构:
DESC information_schema.SCHEMATA;
+----------------------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------------------+------------------+------+-----+---------+-------+
| CATALOG_NAME | varchar(64) | YES | | NULL | |
| SCHEMA_NAME | varchar(64) | YES | | NULL | |
| DEFAULT_CHARACTER_SET_NAME | varchar(64) | NO | | NULL | |
| DEFAULT_COLLATION_NAME | varchar(64) | NO | | NULL | |
| SQL_PATH | binary(0) | YES | | NULL | |
| DEFAULT_ENCRYPTION | enum('NO','YES') | NO | | NULL | |
+----------------------------+------------------+------+-----+---------+-------+
6 rows in set (0.00 sec)
DESC(也可以写 DESCRIBE)不查数据,只把表的列列出来:一共 6 列,每列都有自己的名字和类型,比如 SCHEMA_NAME 是 varchar(64)。你前面用 DESC 看自己练习表时,看到的也是这六列格式。
这张表有几行?
SELECT COUNT(*) AS 行数 FROM information_schema.SCHEMATA;
+--------+
| 行数 |
+--------+
| 3 |
+--------+
1 row in set (0.00 sec)
这个行数和上面 SHOW DATABASES 的行数是同一件事:一行就是一条记录。所以要分清两句话——“这张表有几列”问的是结构(DESC),“有几行”问的是数据(COUNT(*))。
这一节不建表,所以用自己前缀查一下应该是空的:
SHOW TABLES LIKE 'lesson08_%';
Empty set (0.00 sec)
Empty set 是对的:本节全部是只读语句,看完概念就走,你的 itcast 不会多出任何东西。
小结:P3 安装与启动——服务端、客户端、端口三件事
那一集在 Windows 上装 MySQL、把它注册成服务再启动,这套课不需要你做:服务端已经在学习服务器上跑着,你只是通过 SSH 进去用客户端连它。三件事分清楚就够了——服务端是 mysqld,负责真正存数据、执行 SQL;客户端是你在 mysql> 里敲字的那个程序,它只负责把语句发给服务端、把结果排版给你看;端口 3306 是客户端找服务端的门牌,这台机器上它只监听回环地址,所以外网连不上、也不需要你开放防火墙。装和启动的细节在第 1 节已经走过一遍,本节不重复。
第二步:数据模型——两张表靠一个相同的值对上
数据模型说的是“数据怎么组织、表与表怎么发生关系”。最小的一种关系叫一对多:一个库里有多张表。先看第一张结果:
SELECT SCHEMA_NAME AS 库名 FROM information_schema.SCHEMATA ORDER BY 库名;
+--------------------+
| 库名 |
+--------------------+
| information_schema |
| itcast |
| performance_schema |
+--------------------+
3 rows in set (0.00 sec)
再看第二张结果的前 5 行:
SELECT TABLE_SCHEMA AS 库名, TABLE_NAME AS 表名
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'information_schema'
ORDER BY 表名
LIMIT 5;
+--------------------+---------------------------------------+
| 库名 | 表名 |
+--------------------+---------------------------------------+
| information_schema | ADMINISTRABLE_ROLE_AUTHORIZATIONS |
| information_schema | APPLICABLE_ROLES |
| information_schema | CHARACTER_SETS |
| information_schema | CHECK_CONSTRAINTS |
| information_schema | COLLATION_CHARACTER_SET_APPLICABILITY |
+--------------------+---------------------------------------+
5 rows in set (0.00 sec)
第一张结果里的 information_schema,在第二张结果的「库名」列里出现了 5 次。这就是“关系”的全部含义:不是指针、不是嵌套,而是两张表里存了相同的值。一张库表的一个库,对应表表里的多张表,所以叫一对多;反过来从表看库,就是多对一。
为什么非要拆成两张表?如果所有信息塞一张表,每张表都要把所属库的名字、字符集、排序规则再抄一遍,改一次要改很多行,还容易改漏。拆开以后,库的信息只在库表里写一次,表表里只留一个 TABLE_SCHEMA 指回去。后面讲多表查询时,你要做的就是把这种“相同的值”当桥梁,把两张表的数据拼回一行一行的结果。
现在还不用会写连接查询,只要记住一句话:两张表能对上,是因为它们有一个含义相同、值也相同的列。一对多、多对一、多对多,都是这条规则的组合。
第三步:SQL 分四类,写法有 4 条通用规则
SQL 不是一堆散装命令,按“管什么”分四类,后面每一节你都会落在其中一类里:
| 类别 | 全称 | 管什么 | 常见语句 | 本课程在哪 |
|---|---|---|---|---|
| DDL | Data Definition Language | 库和表的结构 | 建表、改表、删表、建库 | 第 2 节建表、第 10 节改表 |
| DML | Data Manipulation Language | 表里的数据 | 插入、更新、删除 | 第 4、5 节 |
| DQL | Data Query Language | 查数据 | SELECT(含 WHERE、GROUP BY、ORDER BY、LIMIT) | 第 3、6、7、11 节 |
| DCL | Data Control Language | 权限 | 建用户、授权、回收权限 | 只认识,不在这里练 |
四类里,DDL 改的是“表长什么样”,DML 改的是“表里有什么”,DQL 只读不改,DCL 管“谁能连、能做什么”。分清这四条,看到一条陌生语句就能先判断它会不会动结构、会不会动数据。
通用写法有四条,先看一条把注释和大小写都用上的语句:
-- 这一行是注释,服务端不会执行
select 1 + 1 as 结果; /* 块注释也可以跟在语句后面 */
+--------+
| 结果 |
+--------+
| 2 |
+--------+
1 row in set (0.00 sec)
四件事在这条语句里都能看到:语句以分号结尾(mysql> 里不敲分号它会一直等);关键字大小写不敏感,select 和 SELECT 一样,习惯上关键字大写、表名列名小写;注释有两种,-- 管到行尾,/* */ 可以夹在语句中间;一条语句可以换行写,换行不影响执行,只影响你自己读。
字符串要用单引号,比如 '北京';默认设置下双引号也能当字符串用,但别指望它——列名、表名要引就用反引号( ` )。只有启用了 ANSI_QUOTES,双引号才会被当成标识符(列名、表名)的引号。
小结:P6 建库删库——知道有这回事,但这里不练
那一集讲的是库这一层的四个动作:建库、看有哪些库、切换当前库、删库。看库你已经会了(SHOW DATABASES),切换当前库你也一直在用(USE itcast,它只影响当前连接,不动数据)。建库和删库这一节不带你练,也不给可复制的语句,原因很实在:你手里的 course 账号只被授权访问 itcast 这一个库,建库删库属于这台服务器管理员的事;而 itcast 里除了你的练习表,还有课程自己的数据,删库是不可逆的,一条语句就能把别人的东西一起抹掉。想看完整语法可以翻讲义 2.3.1(p15–17),但请不要在学习服务器上试。本课程要用到“库”的地方,全在 itcast 里用 lessonNN_ 前缀建自己的表解决。
常见报错怎么办
| 看到 | 意思 | 怎么办 |
|---|---|---|
1054 Unknown column | 列名不存在 | 用 DESC 表名 核对真实列名;系统表的列名不一定是你猜的那个 |
1064 ... syntax | 语法错,多数是拼写、引号或少了分号 | 从报错里 near '...' 指的位置往前看一个词 |
1146 Table ... doesn't exist | 表不在当前库 | SELECT DATABASE(); 看当前库,再 SHOW TABLES LIKE '...' |
说明 刻意写错的例子:把系统表的列名猜成 name
SELECT name FROM information_schema.SCHEMATA;
ERROR 1054 (42S22): Unknown column 'name' in 'field list'
SCHEMATA 里没有 name 这一列,真实列名是 SCHEMA_NAME——1054 就是在说这件事。用 DESC information_schema.SCHEMATA; 看一眼就不会猜错。
说明 刻意写错的例子:关键字少写一个字母
SELEC 1;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELEC 1' at line 1
1064 的报错信息会把出问题的位置用 near '...' 标出来,这里 near 'SELEC 1' 说明从第一个词就不对。改回 SELECT 即可。
说明 刻意写错的例子:查一张不存在的表
DESC lesson08_missing;
ERROR 1146 (42S02): Table 'itcast.lesson08_missing' doesn't exist
1146 说明当前库(itcast)里没有这张表。本节不建表,所以 lesson08_ 开头的表本来就该是空的。
练习
先自己做,再展开提示和对答案。前三题要动手,最后一题只问概念。
1. 用一条语句数出你这个账号能看到几个库,并说出其中哪个是你的。
提示 提示
库的清单在系统库 information_schema 的 SCHEMATA 表里,一行一个库;数行用 COUNT(*)。
参考答案 答案
SELECT COUNT(*) AS 库个数 FROM information_schema.SCHEMATA;
+-----------+
| 库个数 |
+-----------+
| 3 |
+-----------+
1 row in set (0.00 sec)
再 SHOW DATABASES; 看名字:itcast 是你的,其余是你这个账号能看到的系统库(mysql、sys 要额外权限才会出现)。以你屏幕上的行数为准,认出 itcast 就答对了;换一个权限不同的账号,这个数也会跟着变。
说明 常见错
写成 SELECT COUNT(*) FROM SCHEMATA; 会得到 1146——SCHEMATA 在 information_schema 库里,不写库名就变成在 itcast 里找。
**2. 查出 information_schema.SCHEMATA 每一列的名字和类型,按列的原始顺序排。**
提示 提示
列的元数据在 information_schema.COLUMNS 里,ORDINAL_POSITION 就是列的序号。
参考答案 答案
SELECT ORDINAL_POSITION AS 序号, COLUMN_NAME AS 列名, COLUMN_TYPE AS 类型
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = 'information_schema' AND TABLE_NAME = 'SCHEMATA'
ORDER BY ORDINAL_POSITION;
+--------+----------------------------+------------------+
| 序号 | 列名 | 类型 |
+--------+----------------------------+------------------+
| 1 | CATALOG_NAME | varchar(64) |
| 2 | SCHEMA_NAME | varchar(64) |
| 3 | DEFAULT_CHARACTER_SET_NAME | varchar(64) |
| 4 | DEFAULT_COLLATION_NAME | varchar(64) |
| 5 | SQL_PATH | binary(0) |
| 6 | DEFAULT_ENCRYPTION | enum('NO','YES') |
+--------+----------------------------+------------------+
6 rows in set (0.00 sec)
6 列,SCHEMA_NAME 排第 2,类型是 varchar(64)——和 DESC 看到的一致,只是换成了可以用 WHERE 筛的表。
说明 常见错
把 TABLE_SCHEMA 写成 SCHEMA_NAME:COLUMNS 表里没有 SCHEMA_NAME 这一列,会得到 1054。
**3. 写一条全小写、带注释的语句,算出 2 乘 3,并把结果列命名成 六。**
提示 提示
列名用 AS 起别名;注释可以写在语句前面一行,用 -- 开头(注意后面有个空格)。
参考答案 答案
-- 小写关键字一样能执行
select 2 * 3 as 六;
+-----+
| 六 |
+-----+
| 6 |
+-----+
1 row in set (0.00 sec)
关键字大小写不影响执行;别名是中文也能显示。
说明 常见错
把 -- 后面的空格漏掉写成 --注释:MySQL 不认这个行注释,会把它当语句的一部分,得到 1064。
**4. 概念题:USE itcast; 属于四类里的哪一类?它会不会动数据?**
参考答案 答案
它不建表也不改数据,严格说是切换当前连接默认库的会话命令,不属于 DDL/DML/DQL/DCL 四类中的任何一类;它只影响“你这条连接接下来不写库名时去哪个库找表”,对 itcast 里的数据没有任何影响。
本单元验收
做到下面 4 条,这一节就完成了。
- 能说出库、表、行、列四层各自是什么,并能用
SHOW DATABASES与DESC各演示一次。 - 能解释“两张表靠相同的值对上”,并指出
SCHEMATA与TABLES是用哪一列对上的(SCHEMA_NAME对TABLE_SCHEMA)。 - 能说出 DDL/DML/DQL/DCL 各管什么,并各举一条语句;知道 DCL 在本课程只认识、不练。
- 能写出带注释、小写关键字、以分号结尾的语句,并说明
'北京'为什么用单引号。
做到这里
做到这里今天可以停。你现在有了后面所有节的公共词汇:库、表、行、列、关系、四类 SQL。这一节没有建表,itcast 里没有多出任何 lesson08_ 开头的表。
下一节开始动结构:先搞清字段类型怎么选,再建第一张属于第四单元的表。
来源与边界
本节对应 BV1Kr4y1i7ru 平台 part 1(原标题「01.MySQL课程介绍」)、part 2(「02. 基础-课程内容-数据库相关概念」)、part 3(「03. 基础-概述-MySQL安装及启动」)、part 4(「04. 基础-概述-数据模型」)、part 5(「05. 基础-SQL-通用语法及分类」)、part 6(「06. 基础-SQL-DDL-数据库操作」),在 P01–P50 范围内;主题与同版讲义《MySQL-基础篇》1.1 数据库相关概念(p1)、1.2.1–1.2.5 安装与启动(p2–13)、1.2.6 数据模型(p13–14)、2.1/2.2 通用语法与分类(p15)、2.3.1 数据库操作(p15–17)对应。讲义为公开镜像,仅作事实核对。
本集及本课程没有逐字稿,本节未声称听过讲解;页面里的库名、语句、输出都是在作者自己的隔离 MySQL 8.0.46 实例上实跑得到的,其中 SHOW DATABASES 与库个数是在只有 itcast.* 权限的账号下采集(与课程账号同一权限范围),不是管理员视角;表名、例子与练习均为本教程原创。part 6 的建库/删库只作文字说明,不提供可复制语句,也不在学习服务器上执行。