MySQL 系列:第1篇 数据库时代与MySQL

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. 动手试试:修改条件,观察变化

现在请你在上面的插入代码基础上,完成以下练习:

  1. 插入一个 username 为 "alice" 的用户

    运行程序,观察会输出什么?为什么会这样?

    提示:用户名设置了 UNIQUE 约束。

  2. 修改 SELECT 语句,只查询 email 以 "@example.com" 结尾的用户,并按 id 降序排列

    预期输出应该显示 3 条记录,顺序为 charlie → bob → alice。

  3. 使用 cursor.execute("SELECT VERSION()") 查看 MySQL 版本号,确认你安装的是 8.0 系列。

如果你还没搭建好环境,现在是动手的最佳时机。这个环境将贯穿整个系列教程。


今天我们迈出了 MySQL 学习的第一步,从"数据库为何存在"开始,了解了关系型模型、MySQL 的定位与优势,并通过 Docker 快速搭建了实验环境,最后用 Python 完成了连接、建库、建表、增删查的全流程。下一篇文章我们将深入 库和表 的设计,学习数据类型、约束与字符集的底层细节。

想了解更多还可以去各个平台搜索「IT策士」,一起升级 IT 思维 !

相关推荐
ExC1dNtqz1 小时前
Redis 分布式锁进阶第六篇讲解
数据库·redis·分布式
小胖xiaopangss2 小时前
Redis 基础入门与实践指南
数据库·redis·缓存
江畔柳前堤2 小时前
agent面试题
数据库·人工智能·opencv·数据挖掘·语音识别·agent
J.P.August2 小时前
ASM故障组配置实现RAC双活冗余
数据库·oracle
乐兮创想 小林2 小时前
企业官网 i18n 多语言工程实践:URL 策略、hreflang、内容管理与多语言 SEO
数据库·网站建设·企业官网·北京网站建设公司
我爱学习好爱好爱2 小时前
Docker Compose部署SpringBoot2+Vue3+redis项目(Rockylinux9.6):MySQL 主从复制实战
redis·mysql·docker
烁3472 小时前
Oracle学习
数据库·学习·oracle
Bert.Cai2 小时前
Oracle LENGTH函数详解
数据库·oracle