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 容器
打开终端,执行以下命令:
dockerrun-d\--namemysql8\-p3306:3306\-eMYSQL_ROOT_PASSWORD=MyNewPass123!\mysql:8.0预期输出:Docker 会打印一个长字符串(容器 ID),表示启动成功。你可以用docker ps查看运行中的容器。
动手试试
如果你不想用 Docker,也可以直接去 MySQL 官网 下载安装包。安装后记得将 MySQL 的bin目录加入系统 PATH。
步骤 2:使用命令行客户端连接
容器启动后,进入容器内部使用mysql客户端:
dockerexec-itmysql8 mysql-uroot-pMyNewPass123!预期输出:
mysql:[Warning]Using a password on thecommandline interface can be insecure. Welcome to the MySQL monitor. Commands end with;or\g. Your MySQL connectionidis9Server version:8.0.35 MySQL Community Server - GPL... mysql>出现mysql>提示符,说明连接成功!
执行第一条 SQL 语句,查看数据库列表:
预期输出:
+--------------------+|Database|+--------------------+|information_schema||mysql||performance_schema||sys|+--------------------+4rowsinset(0.00sec)这四个库是 MySQL 的系统库,用来存储元数据、权限、监控指标等,千万不要删除它们。
5. Python 连接 MySQL:让代码与数据库对话
接下来,我们用 Python 来操作 MySQL,打通“编程语言 ↔ 数据库”的链路。
安装 Python 连接器
我们选择官方推荐的mysql-connector-python驱动,它是纯 Python 实现,无需额外安装 C 依赖。
pipinstallmysql-connector-python预期输出:
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:
importmysql.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. 获取结果forrowincursor.fetchall(): print(row)# 5. 关闭资源cursor.close()conn.close()运行代码:
python 01_first_connection.py预期输出(结果可能略有差异):
('%','root')('localhost','mysql.infoschema')('localhost','mysql.session')('localhost','mysql.sys')('localhost','root')这段代码演示了数据库操作的五个标准步骤:连接 → 游标 → 执行 → 取结果 → 关闭。
处理连接异常(最佳实践)
生产环境中网络抖动或密码错误很常见,必须捕获异常:
importmysql.connector from mysql.connectorimportError config={"host":"127.0.0.1","port":3306,"user":"root","password":"MyNewPass123!","database":"mysql"}try: conn=mysql.connector.connect(**config)ifconn.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:ifconn.is_connected(): cursor.close()conn.close()print("连接已关闭")预期输出:
✅ 连接成功 MySQL 版本:8.0.35 连接已关闭常见误区
很多新手会把数据库密码硬编码在代码里,甚至提交到 Git。开发时可以使用环境变量os.getenv("MYSQL_PASSWORD")来管理敏感信息,后续文章会详细介绍。
6. 创建第一个业务数据库和表
现在我们脱离系统库,创建属于自己的数据库,并用 Python 管理。
创建数据库和表
importmysql.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 EXISTSusers(idINT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50)NOT NULL UNIQUE, email VARCHAR(100)NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)ENGINE=InnoDB DEFAULTCHARSET=utf8mb4""" cursor.execute(create_table_sql)print("数据库和表创建成功!")cursor.close()conn.close()预期输出:
插入和查询数据
importmysql.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用户列表:")forrowincursor.fetchall(): print(row)cursor.close()conn.close()预期输出:
插入了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 的宏观架构,能帮助你在后面的学习中明白每一步优化是作用在哪个层面。
客户端(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 思维 !