【计算机基础】数据库系列(一)
1. SQL与NoSQL:如何选择适合的数据库?
1.1 数据模型的根本差异
SQL(关系型数据库) 采用固定的表结构,数据通过外键关联,结构严谨,适合处理结构化数据。
NoSQL(非关系型数据库) 提供更灵活的数据模型,支持键值对、文档、列族、图等多种形式,适合处理结构不固定或多变的数据。
1.2 扩展方式的区别
SQL数据库 主要采用垂直扩展(Scale-Up),通过提升单台服务器性能来应对增长。
NoSQL数据库 专为水平扩展(Scale-Out)设计,通过增加服务器节点分担负载,适合海量数据和高并发场景。
1.3 一致性处理机制
SQL 通过ACID事务保证强一致性:
原子性(Atomicity)
一致性(Consistency)
隔离性(Isolation)
持久性(Durability)
NoSQL 遵循BASE原则,保证最终一致性:
基本可用(Basically Available)
软状态(Soft State)
最终一致性(Eventual Consistency)
1.4 实际项目中的选择策略
选择SQL的情况:复杂关联查询、高事务一致性要求、数据结构相对稳定。
选择NoSQL的情况:海量数据处理、数据结构频繁变化、高并发读写。
混合架构:现代系统常结合两者优势,形成互补架构。
2. 数据库设计:三大范式详解
2.1 范式定义与目的
第一范式(1NF):字段必须是不可再分的原子值。
第二范式(2NF):消除非主属性对主键的部分函数依赖(所有非主键字段必须完全依赖于整个主键)。
第三范式(3NF):消除传递依赖(非主键字段之间不能有依赖关系)。
2.2 范式的实际应用
范式的核心目的是减少数据冗余、提高数据一致性,确保数据操作安全可靠。但在实际业务中,并不总是追求最高范式,有时会故意进行反范式化设计,以空间换时间,优化查询性能。
3. MySQL实战技巧
3.1 连表查询方式
内连接(INNER JOIN):显示左右表中匹配成功的行。
左外连接(LEFT JOIN):返回左表所有行,右表无匹配显示NULL。
右外连接(RIGHT JOIN):返回右表所有行,左表无匹配显示NULL。
全连接(FULL JOIN):MySQL不支持,可通过LEFT JOIN + UNION + RIGHT JOIN实现。
3.2 避免重复插入数据
使用UNIQUE约束。
INSERT ... ON DUPLICATE KEY UPDATE:更新现有记录。
INSERT IGNORE:忽略重复插入错误。
3.3 IP地址存储方案
IPv4地址是32位数字,存储方式:
字符串存储:直观易读
整数存储:节省空间,查询效率高
4. 事务与并发控制
4.1 事务特性及实现机制
原子性:通过Undo Log实现,事务失败时回滚。
一致性:由其他三个特性共同保障,通过完整性约束检查实现。
隔离性:通过锁机制和MVCC实现,保证事务独立运行。
持久性:通过Redo Log实现,故障后能恢复数据。
4.2 常见并发问题
脏读:读到其他事务未提交的数据。
不可重复读:同一事务内多次读取同一数据结果不同。
幻读:同一事务内多次查询返回记录数不同。
4.3 解决方案
锁机制:共享锁(读锁)和排他锁(写锁)。
MVCC:多版本并发控制,每个事务看到数据在开始时的版本。
事务隔离级别:读未提交、读已提交、可重复读、串行化。
5. MySQL主从复制
5.1 工作原理
MySQL主从复制是基于日志的异步数据同步过程:
主库处理:
数据修改操作按顺序记录到二进制日志。
启动Binlog Dump Thread负责日志传输。
从库处理:
I/O Thread:连接主库,请求新的二进制日志事件,写入本地中继日志。
SQL Thread:读取中继日志,解析并执行SQL命令,保持数据一致。
中继日志的关键作用:解耦拉取日志和应用日志,实现异步操作,提升复制容错性。
5.2 数据一致性问题
异步复制的风险:
主库提交事务后立即返回客户端成功,不等待从库同步。
主库故障时,已提交但未同步的数据可能丢失,导致主从数据不一致。
5.3 解决方案:半同步复制
主库提交事务时,至少等待一个从库成功接收并写入中继日志。
确保数据在主库和至少一个从库上同时存在。
以性能(增加写延迟)换取数据一致性。
5.4 应用场景
读写分离:主库处理写操作,从库分担读负载。
高可用与故障切换:配合Keepalived、MHA等工具实现自动故障转移。
数据分析:在从库运行重型统计任务,不影响主库性能。
零停机维护:通过主从切换实现平滑升级。
6. 数据库用户权限管理实践
6.1 核心原则:最小权限原则
每个用户或应用程序只能被授予完成其任务所必需的最小权限。
6.2 权限管理架构
用户(User):登录数据库的身份(如app_user、report_user)
权限(Privilege):对数据库对象的操作权限(SELECT、INSERT、UPDATE等)
角色(Role):一组权限的集合(如read_only_role、data_writer_role)
优势:
易于管理:修改角色权限即可影响所有相关用户。
减少错误:避免权限分配遗漏或重复。
职责清晰:每个角色职责明确。
6.3 具体实践步骤
规划与创建角色:根据业务需求定义角色。
授予精细化权限:为角色分配最小必要权限。
创建用户并分配角色:用户通过角色获得权限。
6.4 行级权限控制
场景:用户只能查询某张表中"部门"为"销售部"的数据。
解决方案:使用视图暴露特定数据。
CREATE VIEW sales_department_view AS
SELECT * FROM employee WHERE department = '销售部';GRANT SELECT ON sales_department_view TO limited_user;
7. 备份恢复策略
7.1 日志文件
Undo Log:保证事务原子性
Redo Log:保证事务持久性
Binlog:用于系统备份和主从复制
Relay Log:主从复制中的中继日志
慢查询日志:记录执行时间长的SQL
7.2 备份类型选择
逻辑备份:使用mysqldump命令生成SQL文件,恢复时用mysql命令导入。
物理备份:直接复制数据文件,速度更快。
热备份 vs 冷备份:
热备份:数据库在线,业务基本不受影响。
冷备份:需要停止服务,保证数据完全一致。
7.3 大库备份方案
对于几十GB的大库,推荐使用Percona XtraBackup:
直接复制物理数据文件,速度极快
实现真正热备,监控redo log捕获增量变化
恢复时只需拷贝文件,比执行SQL快数个数量级
8. 慢查询优化全流程
8.1 发现与定位慢SQL
开启慢查询日志:设置long_query_time阈值(如2秒)。
定期分析日志:监控性能瓶颈SQL。
使用EXPLAIN分析:查看执行计划,定位问题。
8.2 执行计划解读要点
重点关注以下字段:
type:访问表的方式(效率:system > const > eq_ref > ref > range > index > ALL)
key:实际使用的索引,NULL表示可能未用索引
rows:预估扫描行数,值过大通常意味着性能问题
8.3 优化策略
索引优化:
为WHERE、JOIN、ORDER BY、GROUP BY涉及列创建合适索引
避免全表扫描
SQL语句优化:
减少不必要的列查询;
优化复杂子查询,改写为JOIN;
避免WHERE子句中对字段进行函数操作。
架构层面优化:
大数据量表使用分表策略;
引入缓存(如Redis)处理统计类查询;
读写分离分担负载。
8.4 验证与测试
优化后必须:
使用EXPLAIN验证执行计划改进;
在预发布环境充分测试;
确保优化有效且未引入新问题。