Skip to content

MySQL | 学习笔记

更新: 4/20/2025 字数: 2157 字 时长: 9 分钟

MySQL 是一个开源的关系型数据库管理系统,由瑞典 MySQL AB 公司开发,现在属于 Oracle 公司。MySQL 是最流行的关系型数据库管理系统之一,尤其是在 Web 应用程序领域。

特点:

  • 开源免费
  • 性能高效
  • 可靠性好
  • 易于使用
  • 跨平台支持

MySQL 基础

安装与配置

在 Windows 上安装

  1. 从官网下载 MySQL 安装包
  2. 运行安装程序,按照向导完成安装
  3. 配置 root 密码和其他选项

在 Linux 上安装

bash
# Ubuntu/Debian
sudo apt update
sudo apt install mysql-server

# CentOS/RHEL
sudo yum install mysql-server
sudo systemctl start mysqld

连接 MySQL

bash
# 命令行连接
mysql -u root -p

# 指定主机和端口
mysql -h hostname -u username -p -P port

数据库基本操作

创建和管理数据库

sql
-- 查看所有数据库
SHOW DATABASES;

-- 创建数据库
CREATE DATABASE db_name;

-- 使用数据库
USE db_name;

-- 删除数据库
DROP DATABASE db_name;

创建和管理表

sql
-- 创建表
CREATE TABLE table_name (
    column1 datatype constraints,
    column2 datatype constraints,
    ...
);

-- 查看所有表
SHOW TABLES;

-- 查看表结构
DESCRIBE table_name;
SHOW CREATE TABLE table_name;

-- 删除表
DROP TABLE table_name;

-- 修改表
ALTER TABLE table_name ADD column_name datatype;
ALTER TABLE table_name MODIFY column_name new_datatype;
ALTER TABLE table_name DROP column_name;

数据类型

数值类型

  • INT:整数类型
  • TINYINT:小整数类型
  • BIGINT:大整数类型
  • FLOAT:单精度浮点数
  • DOUBLE:双精度浮点数
  • DECIMAL:精确小数

字符串类型

  • CHAR:固定长度字符串
  • VARCHAR:可变长度字符串
  • TEXT:长文本
  • ENUM:枚举类型
  • SET:集合类型

日期和时间类型

  • DATE:日期
  • TIME:时间
  • DATETIME:日期和时间
  • TIMESTAMP:时间戳
  • YEAR:年份

二进制类型

  • BINARY:固定长度二进制字符串
  • VARBINARY:可变长度二进制字符串
  • BLOB:二进制大对象

SQL 语句

数据操作语言 (DML)

插入数据

sql
-- 插入单行
INSERT INTO table_name (column1, column2, ...) 
VALUES (value1, value2, ...);

-- 插入多行
INSERT INTO table_name (column1, column2, ...) 
VALUES 
    (value1_1, value1_2, ...),
    (value2_1, value2_2, ...),
    ...;

查询数据

sql
-- 基本查询
SELECT column1, column2, ... FROM table_name;

-- 使用条件
SELECT * FROM table_name WHERE condition;

-- 排序
SELECT * FROM table_name ORDER BY column1 [ASC|DESC];

-- 分组
SELECT column1, COUNT(*) FROM table_name GROUP BY column1;

-- 限制结果数量
SELECT * FROM table_name LIMIT offset, count;

更新数据

sql
UPDATE table_name SET column1 = value1, column2 = value2, ... WHERE condition;

删除数据

sql
DELETE FROM table_name WHERE condition;

数据定义语言 (DDL)

主键

sql
-- 创建表时定义主键
CREATE TABLE table_name (
    id INT PRIMARY KEY,
    ...
);

-- 添加主键
ALTER TABLE table_name ADD PRIMARY KEY (column_name);

外键

sql
-- 创建表时定义外键
CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    customer_id INT,
    ...
    FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);

-- 添加外键
ALTER TABLE table_name ADD CONSTRAINT fk_name
FOREIGN KEY (column_name) REFERENCES ref_table(ref_column);

索引

sql
-- 创建索引
CREATE INDEX index_name ON table_name (column1, column2, ...);

-- 唯一索引
CREATE UNIQUE INDEX index_name ON table_name (column_name);

-- 删除索引
DROP INDEX index_name ON table_name;

视图

sql
-- 创建视图
CREATE VIEW view_name AS
SELECT column1, column2, ...
FROM table_name
WHERE condition;

-- 使用视图
SELECT * FROM view_name;

-- 删除视图
DROP VIEW view_name;

事务控制

sql
-- 开始事务
START TRANSACTION;
-- 或
BEGIN;

-- 提交事务
COMMIT;

-- 回滚事务
ROLLBACK;

-- 设置保存点
SAVEPOINT savepoint_name;

-- 回滚到保存点
ROLLBACK TO savepoint_name;

高级特性

函数与操作符

字符串函数

sql
-- 连接字符串
SELECT CONCAT(first_name, ' ', last_name) AS full_name FROM employees;

-- 获取子字符串
SELECT SUBSTRING(name, 1, 3) FROM products;

-- 字符串长度
SELECT LENGTH(description) FROM products;

数值函数

sql
-- 四舍五入
SELECT ROUND(price, 2) FROM products;

-- 向上/向下取整
SELECT CEILING(value), FLOOR(value) FROM table_name;

日期和时间函数

sql
-- 当前日期和时间
SELECT NOW(), CURDATE(), CURTIME();

-- 格式化日期
SELECT DATE_FORMAT(date_column, '%Y-%m-%d') FROM table_name;

-- 日期计算
SELECT DATE_ADD(date_column, INTERVAL 1 DAY) FROM table_name;

聚合函数

sql
-- 计数
SELECT COUNT(*) FROM table_name;

-- 求和
SELECT SUM(column_name) FROM table_name;

-- 平均值
SELECT AVG(column_name) FROM table_name;

-- 最大/最小值
SELECT MAX(column_name), MIN(column_name) FROM table_name;

连接查询

内连接(INNER JOIN)

sql
SELECT a.column1, b.column2
FROM table_a a
INNER JOIN table_b b ON a.common_field = b.common_field;

左连接(LEFT JOIN)

sql
SELECT a.column1, b.column2
FROM table_a a
LEFT JOIN table_b b ON a.common_field = b.common_field;

右连接(RIGHT JOIN)

sql
SELECT a.column1, b.column2
FROM table_a a
RIGHT JOIN table_b b ON a.common_field = b.common_field;

全连接(模拟 FULL JOIN)

sql
SELECT a.column1, b.column2
FROM table_a a
LEFT JOIN table_b b ON a.common_field = b.common_field
UNION
SELECT a.column1, b.column2
FROM table_a a
RIGHT JOIN table_b b ON a.common_field = b.common_field
WHERE a.common_field IS NULL;

子查询

sql
-- 在 WHERE 子句中使用子查询
SELECT * FROM products
WHERE price > (SELECT AVG(price) FROM products);

-- 在 FROM 子句中使用子查询
SELECT t.category, AVG(t.price) as avg_price
FROM (SELECT * FROM products WHERE price > 100) t
GROUP BY t.category;

-- EXISTS 子查询
SELECT customer_id, name
FROM customers c
WHERE EXISTS (
    SELECT 1 FROM orders o 
    WHERE o.customer_id = c.customer_id
);

性能优化

索引优化

  • 为经常用于查询的列创建索引
  • 对于复合索引,注意列的顺序
  • 避免在频繁更新的列上创建索引
  • 定期检查和优化索引
sql
-- 查看表的索引
SHOW INDEX FROM table_name;

-- 优化表
OPTIMIZE TABLE table_name;

查询优化

  • 只查询需要的列,避免 SELECT *
  • 使用 EXPLAIN 分析查询执行计划
  • 合理使用 LIMIT 限制结果集大小
  • 优化 JOIN 查询顺序和方式
sql
-- 分析查询
EXPLAIN SELECT * FROM table_name WHERE condition;

配置优化

常见的 MySQL 配置参数:

  • innodb_buffer_pool_size:InnoDB 缓冲池大小
  • key_buffer_size:MyISAM 键缓存大小
  • max_connections:最大连接数
  • query_cache_size:查询缓存大小(MySQL 8.0+ 已移除)
  • tmp_table_size:临时表大小
  • innodb_flush_log_at_trx_commit:事务提交时日志刷新方式

高可用和扩展性

备份与恢复

备份数据

bash
# 使用 mysqldump 备份
mysqldump -u username -p database_name > backup.sql

# 备份多个数据库
mysqldump -u username -p --databases db1 db2 > backup.sql

# 备份所有数据库
mysqldump -u username -p --all-databases > backup.sql

恢复数据

bash
# 恢复数据
mysql -u username -p database_name < backup.sql

复制

主从复制

  1. 在主服务器配置中启用二进制日志

    ini
    [mysqld]
    server-id = 1
    log_bin = mysql-bin
    binlog_format = ROW
  2. 在从服务器上配置

    ini
    [mysqld]
    server-id = 2
    relay_log = mysql-relay-bin
  3. 在从服务器上设置复制

    sql
    CHANGE MASTER TO
      MASTER_HOST='master_host_ip',
      MASTER_USER='replication_user',
      MASTER_PASSWORD='password',
      MASTER_LOG_FILE='mysql-bin.000001',
      MASTER_LOG_POS=0;
    
    START SLAVE;

分片与分区

分区表

sql
-- 范围分区
CREATE TABLE sales (
    id INT, 
    amount DECIMAL(10,2),
    sale_date DATE
)
PARTITION BY RANGE (YEAR(sale_date)) (
    PARTITION p0 VALUES LESS THAN (2020),
    PARTITION p1 VALUES LESS THAN (2021),
    PARTITION p2 VALUES LESS THAN (2022),
    PARTITION p3 VALUES LESS THAN MAXVALUE
);

-- 列表分区
CREATE TABLE employees (
    id INT,
    name VARCHAR(50),
    department VARCHAR(20)
)
PARTITION BY LIST (department) (
    PARTITION p_sales VALUES IN ('Sales', 'Marketing'),
    PARTITION p_tech VALUES IN ('IT', 'Development'),
    PARTITION p_admin VALUES IN ('HR', 'Admin', 'Finance')
);

安全性

用户和权限管理

创建用户

sql
-- 创建用户
CREATE USER 'username'@'host' IDENTIFIED BY 'password';

-- 授予权限
GRANT ALL PRIVILEGES ON database_name.* TO 'username'@'host';
GRANT SELECT, INSERT ON database_name.table_name TO 'username'@'host';

-- 撤销权限
REVOKE privilege ON database_name.* FROM 'username'@'host';

-- 删除用户
DROP USER 'username'@'host';

-- 刷新权限
FLUSH PRIVILEGES;

安全最佳实践

  1. 定期更新 MySQL 版本
  2. 删除不必要的默认数据库和账户
  3. 设置强密码策略
  4. 限制连接访问
  5. 启用 SSL 加密连接
  6. 定期审计数据库活动
  7. 限制用户权限遵循最小权限原则

实际应用案例

电子商务数据库设计

sql
-- 创建客户表
CREATE TABLE customers (
    customer_id INT AUTO_INCREMENT PRIMARY KEY,
    first_name VARCHAR(50) NOT NULL,
    last_name VARCHAR(50) NOT NULL,
    email VARCHAR(100) UNIQUE NOT NULL,
    password VARCHAR(255) NOT NULL,
    address VARCHAR(255),
    phone VARCHAR(20),
    registration_date DATETIME DEFAULT CURRENT_TIMESTAMP
);

-- 创建产品表
CREATE TABLE products (
    product_id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    description TEXT,
    price DECIMAL(10, 2) NOT NULL,
    stock_quantity INT NOT NULL DEFAULT 0,
    category VARCHAR(50),
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

-- 创建订单表
CREATE TABLE orders (
    order_id INT AUTO_INCREMENT PRIMARY KEY,
    customer_id INT NOT NULL,
    order_date DATETIME DEFAULT CURRENT_TIMESTAMP,
    status ENUM('pending', 'processing', 'shipped', 'delivered', 'cancelled') DEFAULT 'pending',
    total_amount DECIMAL(12, 2) NOT NULL,
    shipping_address VARCHAR(255) NOT NULL,
    payment_method VARCHAR(50),
    FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);

-- 创建订单明细表
CREATE TABLE order_items (
    item_id INT AUTO_INCREMENT PRIMARY KEY,
    order_id INT NOT NULL,
    product_id INT NOT NULL,
    quantity INT NOT NULL,
    price DECIMAL(10, 2) NOT NULL,
    FOREIGN KEY (order_id) REFERENCES orders(order_id),
    FOREIGN KEY (product_id) REFERENCES products(product_id)
);

常见查询示例

获取销售报表

sql
SELECT 
    p.category,
    SUM(oi.quantity) as total_sold,
    SUM(oi.quantity * oi.price) as total_revenue
FROM 
    order_items oi
JOIN 
    products p ON oi.product_id = p.product_id
JOIN 
    orders o ON oi.order_id = o.order_id
WHERE 
    o.order_date BETWEEN '2023-01-01' AND '2023-12-31'
GROUP BY 
    p.category
ORDER BY 
    total_revenue DESC;

查找热门产品

sql
SELECT 
    p.product_id, 
    p.name,
    SUM(oi.quantity) as total_ordered
FROM 
    products p
JOIN 
    order_items oi ON p.product_id = oi.product_id
GROUP BY 
    p.product_id, p.name
ORDER BY 
    total_ordered DESC
LIMIT 10;

计算客户生命周期价值

sql
SELECT 
    c.customer_id,
    CONCAT(c.first_name, ' ', c.last_name) as customer_name,
    COUNT(DISTINCT o.order_id) as total_orders,
    SUM(o.total_amount) as total_spent,
    MIN(o.order_date) as first_order,
    MAX(o.order_date) as last_order,
    DATEDIFF(MAX(o.order_date), MIN(o.order_date)) as days_as_customer
FROM 
    customers c
JOIN 
    orders o ON c.customer_id = o.customer_id
GROUP BY 
    c.customer_id, customer_name
ORDER BY 
    total_spent DESC;

贡献者

The avatar of contributor named as wkwbk wkwbk

页面历史

布局切换

调整 VitePress 的布局样式,以适配不同的阅读习惯和屏幕环境。

全部展开
使侧边栏和内容区域占据整个屏幕的全部宽度。
全部展开,但侧边栏宽度可调
侧边栏宽度可调,但内容区域宽度不变,调整后的侧边栏将可以占据整个屏幕的最大宽度。
全部展开,且侧边栏和内容区域宽度均可调
侧边栏宽度可调,但内容区域宽度不变,调整后的侧边栏将可以占据整个屏幕的最大宽度。
原始宽度
原始的 VitePress 默认布局宽度

页面最大宽度

调整 VitePress 布局中页面的宽度,以适配不同的阅读习惯和屏幕环境。

调整页面最大宽度
一个可调整的滑块,用于选择和自定义页面最大宽度。

内容最大宽度

调整 VitePress 布局中内容区域的宽度,以适配不同的阅读习惯和屏幕环境。

调整内容最大宽度
一个可调整的滑块,用于选择和自定义内容最大宽度。

聚光灯

支持在正文中高亮当前鼠标悬停的行和元素,以优化阅读和专注困难的用户的阅读体验。

ON开启
开启聚光灯。
OFF关闭
关闭聚光灯。

聚光灯样式

调整聚光灯的样式。

置于底部
在当前鼠标悬停的元素下方添加一个纯色背景以突出显示当前鼠标悬停的位置。
置于侧边
在当前鼠标悬停的元素旁边添加一条固定的纯色线以突出显示当前鼠标悬停的位置。