IT策士 10余年一线大厂经验,专注 IT 思维、架构、职场进阶。我会在各个平台持续发布最新文章,助你少走弯路。
1. 为什么需要数据库?
在软件开发中,数据是核心资产。最早的程序把数据直接写在文件里,但随着系统越来越复杂,文件存储暴露出三大问题:
-
并发冲突:多个用户同时修改同一份文件,数据容易损坏
-
查询低效:从几万行里找出满足条件的记录,只能全文件扫描
-
一致性难保证:转账操作"扣钱"和"加钱"两步可能只执行了一半
数据库正是为了解决这些痛点而诞生的。它提供了一套可靠、高效、安全的数据管理方案。
2. 关系型数据库的核心概念
关系型数据库(RDBMS)把数据组织成表(Table) ,表由**行(Row)和列(Column)**构成,就像 Excel 表格一样。
-
行代表一个实体,比如"一个学生"
-
列代表实体的属性,比如"姓名"、"年龄"
-
主键(Primary Key):唯一标识一行数据,比如"学号"
-
SQL(Structured Query Language):操作数据库的统一语言,无论底层是哪种数据库,SQL 都大致相同
关系型数据库通过关系来连接不同的表。例如"学生表"和"成绩表"可以通过"学号"关联,查询出"张三的所有成绩"。这种模型理论扎实、应用广泛,是目前最主流的数据库类型。
3. MySQL 是什么?为什么选择它?
MySQL 是目前最受欢迎的开源关系型数据库之一。它最初由瑞典的 MySQL AB 公司开发,后来被 Sun、Oracle 相继收购。尽管归属于 Oracle,MySQL 社区版仍然免费、开源,拥有庞大的用户群体。
MySQL 的突出优势
-
开源免费:社区版自由使用,降低企业成本
-
性能强劲:插件式存储引擎架构,InnoDB 引擎支持事务、行级锁,适合高并发 OLTP 场景
-
简单易用:安装轻量,学习曲线平缓,5 分钟即可上手
-
生态完善:丰富的监控、备份、高可用工具(如 XtraBackup、Orchestrator、ProxySQL)
-
云原生友好:各大云厂商均提供托管 MySQL 服务(RDS),自动运维
版本演变与选择
MySQL 5.7 是上一个长期稳定版,至今仍有大量项目使用。MySQL 8.0 是目前的主流版本,带来了众多关键改进:
-
窗口函数、CTE(公用表表达式)让复杂查询更简单
-
原子 DDL、降序索引增强
-
JSON 数据类型与函数大幅完善
-
默认字符集变为 utf8mb4,彻底告别表情符号乱码
本系列文章均基于 MySQL 8.0 展开。如果你还在用 5.7,建议尽早升级,体验现代 SQL 的开发效率。
4. 环境搭建:5 分钟拥有自己的 MySQL
我们将使用 Docker 来快速安装 MySQL 8.0,避免系统环境污染。如果你还没安装 Docker,请先访问 docker.com 下载对应的桌面版本。
步骤 1:拉取并启动 MySQL 容器
打开终端,执行以下命令:
bash
docker run -d \
--name mysql8 \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=MyNewPass123! \
mysql:8.0
预期输出 :Docker 会打印一个长字符串(容器 ID),表示启动成功。你可以用 docker ps 查看运行中的容器。
动手试试
如果你不想用 Docker,也可以直接去 MySQL 官网 下载安装包。安装后记得将 MySQL 的
bin目录加入系统 PATH。
步骤 2:使用命令行客户端连接
容器启动后,进入容器内部使用 mysql 客户端:
bash
docker exec -it mysql8 mysql -uroot -pMyNewPass123!
预期输出:
bash
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.0.35 MySQL Community Server - GPL
...
mysql>
出现 mysql> 提示符,说明连接成功!
执行第一条 SQL 语句,查看数据库列表:
预期输出:
bash
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
这四个库是 MySQL 的系统库,用来存储元数据、权限、监控指标等,千万不要删除它们。
5. Python 连接 MySQL:让代码与数据库对话
接下来,我们用 Python 来操作 MySQL,打通"编程语言 ↔ 数据库"的链路。
安装 Python 连接器
我们选择官方推荐的 mysql-connector-python 驱动,它是纯 Python 实现,无需额外安装 C 依赖。
bash
pip install mysql-connector-python
预期输出:
bash
Collecting mysql-connector-python
Downloading mysql_connector_python-8.3.0-cp310-cp310-manylinux_2_17_x86_64.whl ...
Installing collected packages: mysql-connector-python
Successfully installed mysql-connector-python-8.3.0
建立连接并执行第一个查询
创建文件 01_first_connection.py:
bash
import mysql.connector
# 1. 建立连接
conn = mysql.connector.connect(
host="127.0.0.1",
port=3306,
user="root",
password="MyNewPass123!",
database="mysql" # 先连接系统库
)
# 2. 创建游标
cursor = conn.cursor()
# 3. 执行查询
cursor.execute("SELECT host, user FROM user LIMIT 5")
# 4. 获取结果
for row in cursor.fetchall():
print(row)
# 5. 关闭资源
cursor.close()
conn.close()
运行代码:
bash
python 01_first_connection.py
预期输出(结果可能略有差异):
bash
('%', 'root')
('localhost', 'mysql.infoschema')
('localhost', 'mysql.session')
('localhost', 'mysql.sys')
('localhost', 'root')
这段代码演示了数据库操作的五个标准步骤:连接 → 游标 → 执行 → 取结果 → 关闭。
处理连接异常(最佳实践)
生产环境中网络抖动或密码错误很常见,必须捕获异常:
bash
import mysql.connector
from mysql.connector import Error
config = {
"host": "127.0.0.1",
"port": 3306,
"user": "root",
"password": "MyNewPass123!",
"database": "mysql"
}
try:
conn = mysql.connector.connect(**config)
if conn.is_connected():
print("✅ 连接成功")
cursor = conn.cursor()
cursor.execute("SELECT VERSION()")
version = cursor.fetchone()
print(f"MySQL 版本: {version[0]}")
except Error as e:
print(f"❌ 连接失败: {e}")
finally:
if conn.is_connected():
cursor.close()
conn.close()
print("连接已关闭")
预期输出:
bash
✅ 连接成功
MySQL 版本: 8.0.35
连接已关闭
常见误区
很多新手会把数据库密码硬编码在代码里,甚至提交到 Git。开发时可以使用环境变量
os.getenv("MYSQL_PASSWORD")来管理敏感信息,后续文章会详细介绍。
6. 创建第一个业务数据库和表
现在我们脱离系统库,创建属于自己的数据库,并用 Python 管理。
创建数据库和表
bash
import mysql.connector
conn = mysql.connector.connect(
host="127.0.0.1",
port=3306,
user="root",
password="MyNewPass123!"
)
cursor = conn.cursor()
# 创建数据库
cursor.execute("CREATE DATABASE IF NOT EXISTS myblog DEFAULT CHARSET utf8mb4")
# 切换到该数据库
cursor.execute("USE myblog")
# 创建用户表
create_table_sql = """
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
email VARCHAR(100) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
"""
cursor.execute(create_table_sql)
print("数据库和表创建成功!")
cursor.close()
conn.close()
预期输出:
插入和查询数据
bash
import mysql.connector
conn = mysql.connector.connect(
host="127.0.0.1",
port=3306,
user="root",
password="MyNewPass123!",
database="myblog"
)
cursor = conn.cursor()
# 插入新用户
insert_sql = "INSERT INTO users (username, email) VALUES (%s, %s)"
users = [
("alice", "alice@example.com"),
("bob", "bob@example.com"),
("charlie", "charlie@example.com")
]
cursor.executemany(insert_sql, users)
conn.commit() # 提交事务
print(f"插入了 {cursor.rowcount} 条记录")
# 查询所有用户
cursor.execute("SELECT id, username, email, created_at FROM users")
print("\n用户列表:")
for row in cursor.fetchall():
print(row)
cursor.close()
conn.close()
预期输出:
bash
插入了 3 条记录
用户列表:
(1, 'alice', 'alice@example.com', datetime.datetime(2025, 1, 15, 12, 0, 1))
(2, 'bob', 'bob@example.com', datetime.datetime(2025, 1, 15, 12, 0, 1))
(3, 'charlie', 'charlie@example.com', datetime.datetime(2025, 1, 15, 12, 0, 1))
这里有几个关键点:
-
参数化查询 :
%s是占位符,而不是 Python 的字符串格式化%。这样可以防止 SQL 注入,并处理不同数据类型的转义。 -
事务提交 :INSERT、UPDATE、DELETE 操作后,必须调用
conn.commit()才会持久化,否则关闭连接时自动回滚。 -
executemany:批量插入远比循环单条插入高效,能大幅减少网络交互次数。
7. MySQL 架构初览(文字流程图)
理解 MySQL 的宏观架构,能帮助你在后面的学习中明白每一步优化是作用在哪个层面。
bash
客户端 (Python / Java / CLI)
↓
连接/线程处理层 ← 连接池管理、认证授权
↓
查询缓存 (8.0 已移除)
↓
解析器 → 生成解析树
↓
优化器 → 选择索引、重写查询、决定 JOIN 顺序
↓
执行器 → 调用存储引擎接口
↓
存储引擎层 (InnoDB / MyISAM / Memory ...)
↓
磁盘 (数据文件、日志文件)
-
连接层:负责与客户端通信,每个连接对应一个线程。
-
服务层:SQL 的核心大脑,包括解析、优化、执行计划生成。
-
引擎层:负责数据的实际存储和读取,插件式设计使 MySQL 可以灵活切换存储方式。InnoDB 是默认引擎,支持事务。
思考 :为什么我们写的 SQL 相同,执行时间有时差别巨大?
因为优化器在不同的数据量、索引条件下会选择不同的执行路径。理解优化器的工作原理,是 SQL 调优的关键,本系列后续章节会深度展开。
8. 动手试试:修改条件,观察变化
现在请你在上面的插入代码基础上,完成以下练习:
-
插入一个 username 为 "alice" 的用户 。
运行程序,观察会输出什么?为什么会这样?
提示:用户名设置了 UNIQUE 约束。
-
修改 SELECT 语句,只查询 email 以 "@example.com" 结尾的用户,并按 id 降序排列 。
预期输出应该显示 3 条记录,顺序为 charlie → bob → alice。
-
使用
cursor.execute("SELECT VERSION()")查看 MySQL 版本号,确认你安装的是 8.0 系列。
如果你还没搭建好环境,现在是动手的最佳时机。这个环境将贯穿整个系列教程。
今天我们迈出了 MySQL 学习的第一步,从"数据库为何存在"开始,了解了关系型模型、MySQL 的定位与优势,并通过 Docker 快速搭建了实验环境,最后用 Python 完成了连接、建库、建表、增删查的全流程。下一篇文章我们将深入 库和表 的设计,学习数据类型、约束与字符集的底层细节。
想了解更多还可以去各个平台搜索「IT策士」,一起升级 IT 思维 !