第11章

🗄️ 数据库架构

深入学习数据库架构设计,包括关系型数据库设计、分库分表、读写分离、主从复制和数据库中间件

学习目标

数据库架构概述

数据库架构是系统架构中的重要组成部分,它决定了数据的存储、访问和管理方式。随着业务规模的增长和数据量的激增,传统的单机数据库已经无法满足高并发、大数据量的需求,因此需要采用更加复杂和高效的数据库架构设计。

核心概念

数据库架构设计需要考虑数据一致性、可用性、分区容错性(CAP定理)、性能、扩展性等多个维度,在不同场景下做出合适的权衡。

数据存储

设计合理的数据模型和存储结构,确保数据的完整性和一致性。

性能优化

通过索引优化、查询优化、缓存策略等手段提升数据库性能。

水平扩展

采用分库分表、读写分离等技术实现数据库的水平扩展。

关系型数据库设计

数据库设计原则

关系型数据库设计遵循一系列规范化原则,确保数据的一致性、完整性和可维护性。

表结构设计

-- 用户表设计示例
CREATE TABLE users (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) NOT NULL UNIQUE,
    email VARCHAR(100) NOT NULL UNIQUE,
    password_hash VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    status TINYINT DEFAULT 1 COMMENT '1:正常 0:禁用',
    INDEX idx_username (username),
    INDEX idx_email (email),
    INDEX idx_created_at (created_at)
);

索引设计策略

数据库分库分表

当单个数据库无法承载业务增长带来的数据量和并发压力时,需要采用分库分表策略来实现水平扩展。

垂直拆分

垂直拆分是按照业务功能将不同的表拆分到不同的数据库中,每个数据库负责特定的业务模块。

用户数据库

存储用户信息、认证数据等用户相关的表。

订单数据库

存储订单信息、支付记录等交易相关的表。

商品数据库

存储商品信息、库存数据等商品相关的表。

水平拆分

水平拆分是将同一个表的数据按照某种规则分散到多个数据库或表中,每个分片存储部分数据。

分片策略

// 哈希分片示例
public class HashShardingStrategy {
    private static final int SHARD_COUNT = 8;
    
    public int getShardIndex(Long userId) {
        return Math.abs(userId.hashCode()) % SHARD_COUNT;
    }
    
    public String getTableName(Long userId) {
        int shardIndex = getShardIndex(userId);
        return "user_" + shardIndex;
    }
}

读写分离

读写分离是一种常见的数据库架构模式,通过将读操作和写操作分离到不同的数据库实例上,提升系统的并发处理能力和查询性能。

架构设计

读写分离架构
  • 主库(Master):处理所有写操作(INSERT、UPDATE、DELETE)
  • 从库(Slave):处理所有读操作(SELECT)
  • 数据同步:主库变更通过binlog同步到从库
  • 负载均衡:多个从库之间进行读负载均衡

实现方案

@Component
public class DataSourceRouter {
    
    @Autowired
    private DataSource masterDataSource;
    
    @Autowired
    private List<DataSource> slaveDataSources;
    
    public DataSource getDataSource(boolean isWrite) {
        if (isWrite) {
            return masterDataSource;
        } else {
            // 从库负载均衡
            int index = ThreadLocalRandom.current().nextInt(slaveDataSources.size());
            return slaveDataSources.get(index);
        }
    }
}

注意事项

主从复制

主从复制是MySQL等关系型数据库提供的数据同步机制,通过将主库的变更操作同步到从库,实现数据的高可用和读写分离。

复制原理

Binlog记录

主库将所有变更操作记录到二进制日志(binlog)中。

日志传输

从库的IO线程从主库读取binlog并写入relay log。

重放执行

从库的SQL线程读取relay log并重放执行。

配置示例

# 主库配置 (my.cnf)
[mysqld]
server-id = 1
log-bin = mysql-bin
binlog-format = ROW
sync_binlog = 1
innodb_flush_log_at_trx_commit = 1

# 从库配置 (my.cnf)
[mysqld]
server-id = 2
relay-log = mysql-relay-bin
read_only = 1

复制模式

数据库中间件

数据库中间件是位于应用程序和数据库之间的软件层,提供数据路由、负载均衡、读写分离、分库分表等功能,简化复杂数据库架构的管理。

主流中间件

ShardingSphere

Apache开源的分布式数据库中间件,支持分库分表、读写分离、分布式事务。

MyCat

基于阿里开源Cobar的数据库分库分表中间件,支持MySQL协议。

Vitess

YouTube开源的MySQL集群系统,提供水平扩展和高可用能力。

ShardingSphere配置示例

# application.yml
spring:
  shardingsphere:
    datasource:
      names: ds0,ds1
      ds0:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://localhost:3306/demo_ds_0
        username: root
        password: root
      ds1:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://localhost:3306/demo_ds_1
        username: root
        password: root
    rules:
      sharding:
        tables:
          t_order:
            actual-data-nodes: ds$->{0..1}.t_order_$->{0..1}
            table-strategy:
              standard:
                sharding-column: order_id
                sharding-algorithm-name: t_order_inline
            database-strategy:
              standard:
                sharding-column: user_id
                sharding-algorithm-name: database_inline
        sharding-algorithms:
          database_inline:
            type: INLINE
            props:
              algorithm-expression: ds$->{user_id % 2}
          t_order_inline:
            type: INLINE
            props:
              algorithm-expression: t_order_$->{order_id % 2}

中间件选择考虑因素

数据库架构最佳实践

设计原则

性能优化

优化策略
  • 索引优化:合理创建和使用索引,避免过度索引
  • 查询优化:优化SQL语句,避免全表扫描
  • 连接池管理:合理配置数据库连接池参数
  • 缓存策略:使用Redis等缓存减少数据库压力
  • 批量操作:使用批量插入、更新减少网络开销

运维管理

上一章:消息队列 返回目录 下一章:云原生架构