🦏 第1章 数据库简介
📄 一句话概括

装 MySQL 装的是一个服务端加一堆客户端工具,不是一个双击就完的软件。 装完必须做的三件事:设 root 密码、确认 3306 没被占、把 bin 加进 PATH。 这台沙箱真测了两句: import mysql.connector 报 ModuleNotFoundError: No module named 'mysql', shutil.which('mysql') 给 None——「没装」不是配置错了,是真的没有。

📝 本章和前面几章的关系

上一篇讲清了数据库是什么,这一篇讲怎么把它弄到机器上。 本篇一句业务 SQL 都没有,全是装和配。 它也是全书唯一一篇「本沙箱做不到」的内容——装不了就是装不了,但装的过程、装的后果、 装错的症状,都能讲清楚。

一、装完都有什么:一个服务端、一个客户端、一堆工具

mysqld 是服务端:常驻后台,默认占 3306 端口,数据全归它管,你敲的 SQL 都是发给它的。 mysql 是命令行客户端:敲一句发一句,回车就出结果。 它自己不存任何数据,断了就什么都没了。 还有几个工具:mysqladmin 改密码看状态、mysqldump 备份、mysqlimport 导数据。 它们都是客户端,都需要服务端活着。 所以「连不上」要分两头查:服务端起没起(端口通不通)、客户端连的对不对(地址、端口、 账号、密码)。这两类错误长得像,原因完全不同。

二、Windows 上两种装法

一是 MSI 安装包(官网的 Installer):一路下一步, 会问你端口、root 密码、要不要装成 Windows 服务。 新手走这条。 二是 ZIP 免安装包:解压、写一份 my.ini、mysqld --initialize 初始化、 mysqld --install 注册服务。干净、可搬、可多版本并存,老手爱这条。 不管哪条,装完都要验三句:mysql --version 有版本号、net start mysql 能起来、 mysql -u root -p 能进。 三句都过,才算装好。

三、三个最常见的第一天故障

端口被占:报 Can't connect to MySQL server on 'localhost' (10061), 多半是 3306 被别的 MySQL 实例或别的软件占了。 查 netstat -ano | findstr 3306, 要么杀进程,要么在 my.ini 里换端口。 密码忘了:停服务,用 --skip-grant-tables 起来(此时任何密码都能进), 改完密码立刻重启——这个参数是后门,别留在配置里。 旧版本没卸干净:卸载后 data 目录和 my.ini 还在,重装会继承旧密码或起不来。 装之前先确认 ProgramData 下没有残留。

四、本沙箱为什么装不了,以及替代方案

实测两句就够定性:Python 里 import mysql.connector 直接 ModuleNotFoundError; 系统里 shutil.which('mysql') 返回 None。 驱动和客户端都没有,服务端更不会有。 这不是配置问题,是环境限制:沙箱不给装系统服务,也不给开端口。 所以本课所有 SQL 都跑在 Python 自带的 SQLite 上——它是真数据库引擎,SQL 真执行,行数、 合计、排序都是当场算的。 代价要说清:SQLite 没有 SHOW DATABASES、没有存储过程、没有用户权限、类型也没那么严。 凡是这类语法,正文标「教材原码,本沙箱不执行」,再给等价做法。 不装作一样,这是本课的底线。 MySQL 的版本号倒是能查到(教材那句 SELECT VERSION();): 本沙箱用 SELECT sqlite_version(); 代替,值是 3.53.1。 两个数没有可比性,只是都在回答「你跑的是哪个版本」。

五、小结

教材小结:装 MySQL 分 MSI 与 ZIP 两种方式,装完要设密码、确认端口、配环境变量; 用命令行或图形工具连上去就算装好。 本课补三条:一是「装好了」的标准是三句话都能过,不是安装向导走完; 二是连不上先分「服务端起没起」和「客户端连得对不对」两头查; 三是本沙箱装不了 MySQL,全部 SQL 换 SQLite 真跑,差异逐处标注。

六、动手 Demo:先查有没有,再讲装什么

Demo 六段:先真查这台机器有没有 MySQL 驱动和客户端,再讲装完都有什么、本沙箱的替代品是什么、 两种装法怎么取舍。 前两段是实测,报错和 None 都是当场跑出来的,不是我猜的。

import shutil

# 有没有 MySQL 的 Python 驱动
try:
    import mysql.connector
    print("装了")
except ModuleNotFoundError as e:
    print("没装:", e)

# 有没有 mysql 命令行客户端
print(shutil.which("mysql"))     # None

# 本沙箱的替代品:SQLite
import sqlite3
c = sqlite3.connect(":memory:")
c.execute("SELECT sqlite_version(), sqlite_source_id()")

实跑输出:

--------------------------------------------------------------------
第二课:装 MySQL 这件事,在本沙箱里长什么样
--------------------------------------------------------------------

  先查一句:这台机器上有没有 MySQL 驱动
  import mysql.connector
  报错:ModuleNotFoundError: No module named 'mysql'
  **教材让你先装 MySQL 再装驱动,就是为了这一句不报错。**

  再查一句:有没有 mysql 命令行客户端
  shutil.which('mysql') -> None(没找到)
  **这就是「服务端和客户端都没装」的样子,不是配置错了。**

  装 MySQL 到底装了什么:一个服务端 + 一堆客户端工具
  **mysqld**:服务端,常驻后台,占 3306 端口,数据全归它管。
  **mysql**:命令行客户端,敲一句发一句。
  **mysqladmin / mysqldump**:管理工具,改密码、备份都靠它们。
  **装完要做的三件事**:设 root 密码、把 3306 端口确认没被占、
  把 bin 目录加进 PATH(否则命令行找不到 mysql)。

  本沙箱的替代品:SQLite 也是一个真数据库,只是长得不一样
  SQL> SELECT sqlite_version() AS version, sqlite_source_id() AS build
  version     build
  -------------------------------------------------------------------------------------------------
  3.53.1      2026-05-05 10:34:17 c88b22011a54b4f6fbd149e9f8e4de77658ce58143a1af0e3785e4e6475127e9
  (1 行)

  **MySQL 里对应的那句是**
  `SELECT VERSION();`**,本沙箱没有这个函数,所以用 SQLite 自己的版本函数代替。**
  **差别要说清**:MySQL 是「一个服务端管很多库」,SQLite 是「一个文件就是一个库」,没有服务、
  没有端口、没有账号——**装它就是装 Python 本身,零安装。**

  两种装法的取舍
  **要多人同时读写、要跨网络访问、要账号权限**:必须 MySQL 这类服务端数据库。
  **就自己一台机器、数据量不大、想要「拷个文件就走」**:SQLite 够用,而且快。
  **本课所有 MySQL 独有语法都照原样标出来,能等价执行的就在 SQLite 上真跑。**

第一段 import 驱动。 报 ModuleNotFoundError: No module named 'mysql', 这就是「驱动没装」的样子。 第二段查客户端。 shutil.which('mysql') 给 None,说明 PATH 里根本没有 mysql 这个命令。 第三段列清单。 mysqld、mysql、mysqladmin、 mysqldump——一个服务端加三个常用客户端,各管一件事。 第四段看版本。 sqlite_version() 给 3.53.1, MySQL 里对应的是 SELECT VERSION();。两个数不可比,只是都在报版本。 第五段讲差别。 MySQL 是「一个服务端管很多库」, SQLite 是「一个文件就是一个库」——零安装,也零账号。 第六段讲取舍。 多人并发、跨网络、要权限 → 服务端数据库; 单人单机、数据不大、要拷着走 → SQLite 够用。

30 秒实验

  1. mysql --version 有输出,但 mysql -u root -p 报 10061,问题出在哪一头?
  2. (先想再跑)shutil.which('mysql') 返回 None,但 C:\mysql\bin\mysql.exe 存在,为什么?
  3. 把 3306 改成 3307,客户端要跟着改哪个参数?

常见误区

  1. 安装向导走完就当装好了。 不验那三句,端口没起、PATH 没配,一样用不了。
  2. 把「连不上」一律当密码错。 10061 是连不上服务端,1045 才是账号密码不对, 两个错误码指两个方向。
  3. 长期留着 --skip-grant-tables。 那是应急后门,留着等于谁都能进。
自测三问(点开对答案) 1. MySQL 装完,服务端和客户端分别是什么? —— 服务端是 mysqld,常驻后台占 3306 端口;客户端是 mysql 命令行和各类图形工具,自己不存数据。 2. 报 10061 和报 1045 分别说明什么? —— 10061 是连不上服务端(服务没起或端口不对);1045 是连上了但账号密码被拒。 3. 本沙箱为什么改用 SQLite? —— 沙箱不允许装系统服务、不开放端口,没有 MySQL 服务端也没有驱动; SQLite 是 Python 自带的真引擎,SQL 能真执行。

服务端装好了,但没人愿意天天在命令行里敲 SQL。 下一章装图形客户端:Navicat。

相关笔记