51mee - AI智能招聘平台Logo
模拟面试题目大全招聘中心会员专区

好未来平台有数百万用户和数十万课程,请设计用户与课程数据的存储方案,考虑数据一致性、扩展性和查询性能。

好未来后端 - C++难度:中等

答案

1) 【一句话结论】
针对好未来数百万用户、数十万课程的场景,采用“分库分表(用户表按ID哈希分库、课程表按ID哈希分表)+ Redis缓存+ 索引优化+ 双一致性模型(关键业务强一致,非关键业务最终一致)”的混合架构,通过水平扩展应对数据增长,缓存提升查询性能,双一致性模型平衡一致性与性能。

2) 【原理/概念讲解】
老师讲解:首先,用户与课程数据量巨大,关系型数据库(如MySQL)适合结构化数据,但单表数据量过大时,需引入分库分表(水平扩展)。分库分表通过哈希算法将数据分散到多个库/表,避免单库负载过高。比如用户表按用户ID哈希分库(如ID % 8,分8库),课程表按课程ID哈希分表(如ID % 16,分16表),每个库/表只存储部分数据,实现水平扩展。然后,针对高频查询(如用户信息、课程详情),引入Redis缓存,减少数据库压力。缓存像“数据中转站”,把热门数据放在缓存,用户访问时直接从缓存获取,避免去数据库。查询性能方面,通过复合索引(如用户表的username索引、课程表的title索引,关联表的user_id+course_id联合索引)优化查询效率,比如查询用户购买课程时,先查缓存,缓存失效再通过分库分表路由到对应库/表。数据一致性方面,采用双一致性模型:关键业务(如支付、订单)需强一致性,通过分布式事务(如Seata两阶段提交)确保数据一致;非关键业务(如用户列表展示)采用最终一致性,通过异步消息队列(如Kafka)传递事件,确保数据最终一致。类比:分库分表像把用户数据分散到不同仓库,每个仓库只存部分用户,避免某个仓库过载;缓存像把热门课程放在货架,用户直接拿,不用去仓库;分布式事务像给关键业务加“锁”,确保操作成功后立即更新数据。

3) 【对比与适用场景】

特性MySQL (关系型)Redis (NoSQL缓存)分库分表策略
定义结构化数据存储,支持ACID事务键值对缓存,高性能读写数据水平拆分(库/表)
数据结构表(如user表:id, username, phone...)键值(如user:1 → 用户信息)库/表拆分
事务支持支持(ACID)不支持(需结合数据库事务)无需事务,通过异步保证最终一致
查询能力复杂查询(JOIN、聚合)简单键值获取分布式查询(分片路由)
扩展性垂直扩展(提升单机性能),分库分表(水平扩展)水平扩展(增加实例)水平扩展,应对数据增长
适用场景用户表、课程表(结构化数据,需事务与复杂查询)热点数据缓存(用户信息、课程详情,减少数据库压力)用户表按ID哈希分库(如用户ID % 8,分8库),课程表按ID哈希分表(如课程ID % 16,分16表)
注意点单表数据量过大时性能下降,需分库分表缓存击穿、雪崩风险,需加互斥锁或预加载热点数据集中(如热门用户/课程),需冷热分离(如用户表按注册时间分表,冷数据归档)

4) 【示例】

  • 表结构:

    • 用户表(user):id(主键,哈希分库键)、username(索引)、phone、create_time。
    • 课程表(course):id(主键,哈希分表键)、title(索引)、price、category_id、create_time。
    • 关联表(user_course):user_id(外键,哈希分库键)、course_id(外键,哈希分表键)、purchase_time(索引)。
  • 索引设计:

    • 用户表:id(主键)、username(索引)。
    • 课程表:id(主键)、title(索引)。
    • 关联表:user_id+course_id(联合索引,用于查询用户购买课程)。
  • 缓存策略:

    • 用户信息:user:userId(5分钟TTL)。
    • 课程详情:course:courseId(10分钟TTL)。
    • 用户购买课程列表:user:userId:courses(5分钟TTL)。
  • 分布式查询示例(用户购买课程):
    伪代码:

    def get_user_courses(user_id):
        cache_key = f"user:{user_id}:courses"
        courses = redis.get(cache_key)
        if courses:
            return json.loads(courses)
        
        db_index = user_id % 8  # 用户表分8库
        table_index = course_id % 16  # 课程表分16表
        course_ids = db.query(
            "SELECT course_id FROM user_course WHERE user_id = ? AND db = ? AND table = ?",
            user_id, db_index, table_index
        )
        courses = []
        for cid in course_ids:
            course = db.query(
                "SELECT * FROM course WHERE id = ? AND db = ? AND table = ?",
                cid, course_id % 8, table_index
            )
            courses.append(course)
        
        redis.setex(cache_key, 300, json.dumps(courses), ex=300)
        return courses
    

5) 【面试口播版答案】
好的,面试官。针对好未来数百万用户和数十万课程的数据存储需求,我设计的方案是采用“分库分表+缓存+索引优化+双一致性模型”的混合架构。首先,用户表和课程表属于结构化数据,适合用MySQL,但单表数据量过大时,会引入分库分表策略:用户表按用户ID的哈希值分库(如用户ID % 8,分8个库),课程表按课程ID的哈希值分表(如课程ID % 16,分16个表),实现水平扩展,避免热点数据集中。然后,针对高频查询(如用户信息、课程详情),引入Redis缓存热点数据,减少数据库压力,比如用户信息缓存user:userId,课程详情缓存course:courseId,用户购买课程列表缓存user:userId:courses,通过TTL控制过期。查询性能方面,通过复合索引(如关联表的user_id+course_id联合索引)优化查询,比如查询用户购买课程时,先查缓存,缓存失效再通过分库分表路由到对应库/表,避免全表扫描。数据一致性方面,采用双模型:关键业务(如支付、订单)需强一致性,通过分布式事务(如Seata两阶段提交)确保数据一致;非关键业务(如用户列表展示)采用最终一致性,通过异步消息队列(如Kafka)传递事件,确保数据最终一致。整体方案兼顾了数据一致性、扩展性和查询性能。

6) 【追问清单】

  • 问:分库分表后如何避免热点数据集中?
    回答要点:采用哈希分片(用户ID % 8分库,课程ID % 16分表),同时结合冷热分离(如用户表按注册时间分表,冷数据归档至HBase),避免热点数据集中。
  • 问:缓存击穿或雪崩如何处理?
    回答要点:缓存击穿用互斥锁(如Redis的SETNX),缓存雪崩用随机过期时间或热点数据预加载(系统启动时加载)。
  • 问:关键业务(如支付)如何保证强一致性?
    回答要点:采用分布式事务(如两阶段提交),确保支付成功后立即更新关联表,避免数据不一致。
  • 问:如果用户数据量继续增长,如何进一步扩展?
    回答要点:考虑分表策略(如用户表按时间分表,按注册时间分表),或引入列式数据库(如ClickHouse)处理分析查询。

7) 【常见坑/雷区】

  • 坑1:分库分表策略错误(如按用户ID范围分表),导致热点数据集中。
    雷区:部分库/表负载过高,性能下降,需用哈希分片避免。
  • 坑2:缓存策略不当(如缓存时间设置过长或过短),导致缓存命中率低。
    雷区:缓存时间过长导致数据不一致,过短增加数据库压力,需根据访问频率调整。
  • 坑3:数据一致性模型混淆(非关键业务用强一致性)。
    雷区:非关键业务用最终一致性,关键业务加分布式事务,避免过度复杂化。
  • 坑4:索引设计不合理(如关联表未建联合索引),导致查询效率低。
    雷区:查询多表JOIN时,未建联合索引导致全表扫描,影响性能。
  • 坑5:分库分表后分布式查询逻辑缺失,导致全表扫描。
    雷区:未通过分片键路由,直接查询全表,性能下降,需在SQL中添加分库分表条件。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1