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

夏商集团库存查询系统需支持“查询某商品在多个仓库的库存总和”等复杂查询,请设计数据库优化方案提升性能。

夏商集团未指定具体岗位难度:困难

答案

1) 【一句话结论】:为支持“查询某商品在多个仓库的库存总和”的复杂查询,应通过设计多对多关联的中间表(如商品-仓库-库存表),并构建针对仓库ID和商品ID的组合索引,结合聚合函数优化查询性能,必要时可考虑物化视图预计算结果以提升高频查询效率。

2) 【原理/概念讲解】:首先,商品与仓库是多对多关系(一个商品存在于多个仓库,一个仓库存储多个商品),因此需建立中间表(如商品仓库库存表,字段:商品ID、仓库ID、库存数量)。查询“某商品在多个仓库的库存总和”本质是按商品ID分组,对库存数量求和。数据库优化核心是:① 表结构设计:明确多对多关系,避免冗余;② 索引优化:在商品仓库库存表的仓库ID和商品ID上建组合索引(如仓库ID + 商品ID),因为查询时需要按商品ID分组,而仓库ID用于过滤或分组;③ 聚合优化:使用SUM(库存数量)聚合函数,数据库优化器会尝试使用索引覆盖查询(如果索引包含所有字段)。类比:就像班级(仓库)和学生(商品)的关系,一个学生(商品)属于多个班级(仓库),需要记录每个学生每个班级的学分(库存),查询某个学生的总学分(库存总和),需要按学生分组求和,索引按班级和学生排序,快速定位数据。

3) 【对比与适用场景】:

优化方法定义特性使用场景注意点
组合索引(直接查询)在中间表仓库ID和商品ID上建组合索引查询时直接通过索引定位数据,无需全表扫描高频查询商品库存总和,且数据量适中(如百万级)需确保查询条件匹配索引列,避免索引失效
物化视图(预计算)创建物化视图存储每个商品的总库存(如商品总库存视图,字段:商品ID、总库存)预先计算并存储聚合结果,查询时直接读取视图高频查询且允许一定延迟(如每小时/天刷新),减少实时计算压力需定期刷新(如触发器或任务),否则数据可能过时
分区表(按仓库或商品分区)将中间表按仓库ID或商品ID分区(如范围分区、列表分区)查询时仅扫描相关分区,减少I/O仓库或商品数量极大(如千万级),查询时仅处理部分分区分区键选择需合理,避免跨分区查询

4) 【示例】:

  • 表结构:
    CREATE TABLE 商品表 (
      商品ID INT PRIMARY KEY,
      商品名称 VARCHAR(50)
    );
    CREATE TABLE 仓库表 (
      仓库ID INT PRIMARY KEY,
      仓库名称 VARCHAR(50)
    );
    CREATE TABLE 商品仓库库存 (
      商品ID INT,
      仓库ID INT,
      库存数量 INT,
      PRIMARY KEY (商品ID, 仓库ID),
      FOREIGN KEY (商品ID) REFERENCES 商品表(商品ID),
      FOREIGN KEY (仓库ID) REFERENCES 仓库表(仓库ID)
    );
    
  • 索引:
    CREATE INDEX idx_仓库ID_商品ID ON 商品仓库库存(仓库ID, 商品ID);
    
  • 查询语句:
    SELECT 商品ID, 商品名称, SUM(库存数量) AS 总库存
    FROM 商品仓库库存
    JOIN 商品表 ON 商品仓库库存.商品ID = 商品表.商品ID
    GROUP BY 商品ID, 商品名称;
    
  • 物化视图示例(若使用物化视图):
    CREATE MATERIALIZED VIEW 商品总库存视图 AS
    SELECT 商品ID, 商品名称, SUM(库存数量) AS 总库存
    FROM 商品仓库库存
    JOIN 商品表 ON 商品仓库库存.商品ID = 商品表.商品ID
    GROUP BY 商品ID, 商品名称;
    -- 定期刷新(如每天凌晨)
    REFRESH MATERIALIZED VIEW 商品总库存视图;
    

5) 【面试口播版答案】:
“面试官您好,针对夏商集团库存查询系统需要支持‘查询某商品在多个仓库的库存总和’的复杂查询,我的核心思路是通过设计多对多关联的中间表,并优化索引和聚合查询。首先,商品与仓库是多对多关系,所以需要建立中间表(比如商品仓库库存表,包含商品ID、仓库ID和库存数量),这样能明确记录每个商品在每个仓库的库存。然后,在中间表上为仓库ID和商品ID建组合索引,因为查询时需要按商品ID分组求和,这个索引能快速定位数据,避免全表扫描。查询语句就是按商品ID分组,用SUM聚合库存数量。如果高频查询,还可以考虑创建物化视图预计算结果,减少实时计算压力,但需要定期刷新保证数据实时性。这样既能提升查询性能,又能满足业务需求。”

6) 【追问清单】:

  • 问题1:如果查询需要按仓库分组(比如查询每个仓库的总库存),如何优化?
    回答要点:同样需要建组合索引,但索引顺序调整为商品ID + 仓库ID,查询时按仓库ID分组求和,或者对仓库表和中间表进行JOIN后聚合。
  • 问题2:物化视图的刷新频率如何选择?会不会影响实时性?
    回答要点:刷新频率需根据业务需求平衡,比如高频查询(如每分钟)用实时计算,低频查询(如每小时)用物化视图,或者采用增量刷新(只更新变化的数据)。
  • 问题3:如果数据量极大(如商品和仓库数量都达到千万级),分区表是否更合适?
    回答要点:可以按仓库ID或商品ID分区,比如范围分区(按仓库ID范围划分),查询时仅扫描相关分区,减少I/O,但需合理设计分区键,避免跨分区查询。
  • 问题4:并发写入时,索引和物化视图的维护是否会影响性能?
    回答要点:索引维护是自动的,写入时数据库会更新索引;物化视图的刷新可以采用异步方式(如触发器在写入后更新),或者使用数据库的物化视图刷新机制(如Oracle的DBMS_MVIEW.REFRESH),减少对主查询的影响。
  • 问题5:如果查询需要加入时间维度(比如查询某时间段内的库存总和),如何优化?
    回答要点:在中间表增加时间字段(如更新时间),并按时间分区,或者建时间索引,查询时按时间范围过滤后聚合,同时考虑索引覆盖(包含时间字段)。

7) 【常见坑/雷区】:

  • 忽略多对多关系,直接在商品表和仓库表上建外键:会导致查询时需要JOIN后聚合,性能差,因为JOIN操作会扫描大量数据。
  • 未建组合索引:直接按商品ID分组求和,数据库可能全表扫描,性能低。
  • 物化视图刷新频率不当:如果刷新太慢,数据过时;如果刷新太快,增加系统负载。
  • 分区键选择不合理:比如按商品ID分区,但查询时按仓库ID分组,会导致跨分区查询,性能下降。
  • 索引列顺序错误:比如建索引为商品ID,但查询时按仓库ID分组,索引无法有效利用,导致全表扫描。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1