Files
chill_notes/数据库知识库/数据库基础知识.md
2026-04-21 11:25:16 +08:00

5.0 KiB
Executable File
Raw Blame History

title, tags, created
title tags created
数据库知识库
数据库
SQL
PostgreSQL
MySQL
数据库设计
2026-04-21

数据库知识库

SQL 核心语句分类

DDL数据定义

-- 创建表
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    username VARCHAR(50) UNIQUE NOT NULL,
    email VARCHAR(100),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 修改表结构
ALTER TABLE users ADD COLUMN phone VARCHAR(20);
ALTER TABLE users DROP COLUMN phone;

-- 删除表
DROP TABLE users;

DML数据操作

-- 插入
INSERT INTO users (username, email) VALUES ('张三', 'zhang@example.com');

-- 更新
UPDATE users SET email = 'new@example.com' WHERE username = '张三';

-- 删除
DELETE FROM users WHERE id = 1;

-- 查询
SELECT u.username, o.order_id
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.created_at > '2024-01-01'
ORDER BY u.created_at DESC
LIMIT 10;

索引设计

何时创建索引

场景 建议
主键 自动创建,无需手动添加
外键 建议创建,加速 JOIN
频繁查询的 WHERE 条件 必须创建
参与 ORDER BY 的列 考虑创建
低选择性的列(如性别) 不建议创建

索引类型

-- 单列索引
CREATE INDEX idx_users_email ON users(email);

-- 复合索引(注意列顺序)
CREATE INDEX idx_orders_user_date ON orders(user_id, created_at);

-- 唯一索引
CREATE UNIQUE INDEX idx_users_username ON users(username);

-- 表达式索引
CREATE INDEX idx_users_email_lower ON users(LOWER(email));

-- 查看索引
\d+ users

JOIN 详解

-- INNER JOIN只保留两边都有的记录
SELECT * FROM A INNER JOIN B ON A.id = B.a_id;

-- LEFT JOIN以 A 为准B 没有的为 NULL
SELECT * FROM A LEFT JOIN B ON A.id = B.a_id;

-- RIGHT JOIN以 B 为准A 没有的为 NULL
SELECT * FROM A RIGHT JOIN B ON A.id = B.a_id;

-- 多表 JOIN
SELECT u.name, o.total, p.product_name
FROM users u
INNER JOIN orders o ON u.id = o.user_id
INNER JOIN products p ON o.product_id = p.id;

事务与隔离级别

-- 开启事务
BEGIN;

-- 或
START TRANSACTION;

-- 提交
COMMIT;

-- 回滚
ROLLBACK;

-- 设置隔离级别
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
隔离级别 脏读 非重复读 幻读
READ UNCOMMITTED 可能 可能 可能
READ COMMITTED 不可能 可能 可能
REPEATABLE READ 不可能 不可能 可能MySQL不可能
SERIALIZABLE 不可能 不可能 不可能

慢查询优化

-- 开启查询分析
EXPLAIN ANALYZE
SELECT * FROM orders
WHERE user_id = 123
AND created_at > '2024-01-01';

-- 查看慢查询日志PostgreSQL
SHOW log_min_duration_statement;
SHOW log_min_duration_statement = 1000;  -- 记录超过1秒的查询

-- 查看当前正在执行的查询
SELECT pid, now() - query_start AS duration, query
FROM pg_stat_activity
WHERE state = 'active'
ORDER BY duration DESC;

数据库设计范式

范式 要求 示例
1NF 原子性,每列不可再分 地址拆分为省/市/区
2NF 消除部分依赖(复合主键时) 订单明细需包含完整主键
3NF 消除传递依赖 员工表不直接存部门名而存部门ID

PostgreSQL 常用命令

# 连接数据库
psql -U postgres -d mydb

# 常用元命令
\l          -- 列出所有数据库
\d          -- 列出当前库所有表
\d users    -- 查看 users 表结构
\du         -- 列出所有用户
\di         -- 列出所有索引
\dt         -- 列出所有表

# 备份与恢复
pg_dump -U postgres mydb > backup.sql
psql -U postgres mydb < backup.sql

MySQL 常用命令

# 连接数据库
mysql -u root -p mydb

# 常用命令
SHOW DATABASES;
SHOW TABLES;
DESC users;
SHOW CREATE TABLE users\G

# 备份与恢复
mysqldump -u root -p mydb > backup.sql
mysql -u root -p mydb < backup.sql

ORM 最佳实践

# SQLAlchemy 示例Python
from sqlalchemy import create_engine, Column, Integer, String, DateTime
from sqlalchemy.orm import declarative_base, sessionmaker
from datetime import datetime

Base = declarative_base()

class User(Base):
    __tablename__ = 'users'
    
    id = Column(Integer, primary_key=True)
    username = Column(String(50), unique=True, nullable=False)
    email = Column(String(100))
    created_at = Column(DateTime, default=datetime.utcnow)

# 安全的参数化查询(防止 SQL 注入!)
session.query(User).filter(User.username == username)  # ✅ 安全
# 不要这样做!❌
# session.execute(f"SELECT * FROM users WHERE username = '{username}'")

常见问题

问题 原因 解决方案
连接超时 防火墙/端口未开 检查 pg_hba.conf / mysql user 表
字符乱码 编码不一致 指定 UTF8MB4 编码连接
主从延迟 从机复制慢 读从机、写主机
死锁 并发更新同一行 调整事务顺序、使用锁