概览
MySQL 是全球最流行的开源关系型数据库管理系统(RDBMS),由瑞典 MySQL AB 公司开发,后被 Oracle 收购。它使用标准 SQL 查询语言,以高性能、高可靠性和易用性著称,是 LAMP/LEMP 技术栈的核心组件,广泛用于 Web 应用、电商平台、CMS 系统等。MySQL 支持事务 ACID、存储过程、触发器、视图、分区表等企业级特性,拥有庞大的社区和丰富的第三方工具生态。
MySQL 是全球最流行的开源关系型数据库管理系统(RDBMS),由瑞典 MySQL AB 公司开发,后被 Oracle 收购。它使用标准 SQL 查询语言,以高性能、高可靠性和易用性著称,是 LAMP/LEMP 技术栈的核心组件,广泛用于 Web 应用、电商平台、CMS 系统等。MySQL 支持事务 ACID、存储过程、触发器、视图、分区表等企业级特性,拥有庞大的社区和丰富的第三方工具生态。
sudo apt update
sudo apt install mysql-server -y
sudo systemctl start mysql
sudo systemctl enable mysql
sudo mysql_secure_installation # 设置 root 密码、移除匿名用户等
brew install mysql
brew services start mysql
mysql_secure_installation
# 使用 Choco
choco install mysql
# 或使用 MSI 安装包(官方下载)
# https://dev.mysql.com/downloads/installer/
docker run --name mysql-dev -e MYSQL_ROOT_PASSWORD=root123 \
-p 3306:3306 -d mysql:8.0
mysql -u root -p
# 输入密码后看到 mysql> 提示符即成功
Q: Ubuntu 安装后无法使用 root 登录
sudo mysql # 用系统 root 进入
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '新密码';
FLUSH PRIVILEGES;
Q: 端口 3306 被占用
sudo lsof -i :3306 # 查看占用进程
# 或修改配置文件 /etc/mysql/my.cnf 中的 port
Q: Docker 容器数据持久化
docker run --name mysql-dev \
-v ~/mysql-data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=root123 -p 3306:3306 -d mysql:8.0
通过 MySQL 命令行和 Python 驱动,完成数据库创建、表创建、数据增删改查(CRUD)的完整流程。
确保 MySQL 已安装并运行:
mysql -u root -p
-- 创建数据库
CREATE DATABASE IF NOT EXISTS hello_world CHARACTER SET utf8mb4;
-- 切换到该数据库
USE hello_world;
-- 创建学生表
CREATE TABLE students (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
age INT CHECK(age > 0 AND age < 150),
grade DECIMAL(3,1),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 插入数据
INSERT INTO students (name, age, grade) VALUES
('张三', 20, 88.5),
('李四', 21, 92.0),
('王五', 19, 76.5);
-- 查询
SELECT * FROM students;
SELECT name, grade FROM students WHERE grade >= 80 ORDER BY grade DESC;
-- 更新
UPDATE students SET grade = 90.0 WHERE name = '张三';
-- 删除
DELETE FROM students WHERE name = '王五';
-- 最终结果
SELECT * FROM students;
import mysql.connector
# 连接数据库
conn = mysql.connector.connect(
host="localhost",
user="root",
password="root123",
database="hello_world"
)
cursor = conn.cursor()
# 创建表
cursor.execute("""
CREATE TABLE IF NOT EXISTS students (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
age INT,
grade DECIMAL(3,1)
)
""")
# 批量插入
students = [("赵六", 22, 85.0), ("钱七", 20, 91.5)]
cursor.executemany(
"INSERT INTO students (name, age, grade) VALUES (%s, %s, %s)",
students
)
conn.commit()
# 查询
cursor.execute("SELECT * FROM students WHERE grade >= 85")
for row in cursor.fetchall():
print(f"ID={row[0]}, Name={row[1]}, Grade={row[3]}")
# 清理
cursor.close()
conn.close()
+----+------+------+-------+
| id | name | age | grade |
+----+------+------+-------+
| 1 | 张三 | 20 | 90.0 |
| 2 | 李四 | 21 | 92.0 |
+----+------+------+-------+
ID=1, Name=张三, Grade=90.0
ID=2, Name=李四, Grade=92.0
MySQL 是客户端/服务器架构的关系型数据库管理系统。一台 MySQL 服务器可以管理多个数据库,每个数据库包含多张表。它使用 SQL(Structured Query Language)与客户端通信。
| 类型 | 用途 | 示例 |
|---|---|---|
INT |
整数 | age INT |
VARCHAR(N) |
可变长字符串 | name VARCHAR(100) |
TEXT |
长文本 | content TEXT |
DECIMAL(M,D) |
精确小数 | price DECIMAL(10,2) |
DATE / DATETIME |
日期时间 | created_at DATETIME |
BOOLEAN (TINYINT) |
布尔值 | is_active BOOLEAN |
ENUM |
枚举 | gender ENUM('M','F') |
CREATE DATABASE shop CHARACTER SET utf8mb4;
USE shop;
-- 用户表
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
balance DECIMAL(10,2) DEFAULT 0.00,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 商品表
CREATE TABLE products (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(200) NOT NULL,
price DECIMAL(10,2) NOT NULL,
stock INT DEFAULT 0,
description TEXT
);
-- 订单表
CREATE TABLE orders (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
product_id INT NOT NULL,
quantity INT NOT NULL DEFAULT 1,
total_amount DECIMAL(10,2),
status ENUM('pending','paid','shipped','done') DEFAULT 'pending',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (product_id) REFERENCES products(id)
);
-- === INSERT ===
INSERT INTO users (username, email, password_hash) VALUES
('alice', 'alice@example.com', 'hashed_pwd1'),
('bob', 'bob@example.com', 'hashed_pwd2');
INSERT INTO products (name, price, stock, description) VALUES
('机械键盘', 299.00, 50, 'Cherry MX 青轴'),
('无线鼠标', 89.00, 200, '蓝牙 5.0 静音'),
('27寸显示器', 1999.00, 10, '4K IPS HDR');
-- === SELECT ===
-- 基本查询
SELECT * FROM products WHERE price < 500;
-- 聚合函数
SELECT COUNT(*) AS total_users FROM users;
SELECT AVG(price) AS avg_price FROM products;
-- 排序 + 限制
SELECT name, price FROM products ORDER BY price DESC LIMIT 5;
-- === UPDATE ===
UPDATE products SET stock = stock - 1 WHERE id = 1 AND stock > 0;
-- === DELETE ===
DELETE FROM products WHERE id = 999; -- 删除无效商品
-- 创建一条订单
INSERT INTO orders (user_id, product_id, quantity, total_amount)
VALUES (1, 1, 2, 598.00);
-- INNER JOIN:查看订单详情
SELECT
orders.id AS order_id,
users.username,
products.name AS product_name,
orders.quantity,
orders.total_amount,
orders.status
FROM orders
INNER JOIN users ON orders.user_id = users.id
INNER JOIN products ON orders.product_id = products.id;
-- 为经常查询的列创建索引
CREATE INDEX idx_products_price ON products(price);
CREATE INDEX idx_orders_user_id ON orders(user_id);
CREATE INDEX idx_orders_status ON orders(status);
-- 查看查询是否使用索引
EXPLAIN SELECT * FROM orders WHERE user_id = 1;
SELECT
p.name,
SUM(o.quantity) AS total_sold,
SUM(o.total_amount) AS revenue
FROM orders o
JOIN products p ON o.product_id = p.id
WHERE o.status IN ('paid', 'shipped', 'done')
GROUP BY p.id
ORDER BY total_sold DESC;
password_hash 用 VARCHAR(255) 而非直接在数据库存明文密码?total_amount 而不每次都从 product.price × quantity 计算?INDEX 能加速查询,为什么不能给所有列都加索引?