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

在能源贸易业务中,需要存储海量的能源价格、交易量、库存等时序数据。假设每日数据量约10亿条,且要求支持秒级查询(如按时间范围查询某品种能源价格走势)。请设计一个数据库方案,并说明如何优化查询性能和保证数据一致性。

南光(集团)有限公司能源工程类难度:困难

答案

1) 【一句话结论】采用**时序数据库(TimescaleDB)+ 传统关系型数据库(MySQL)**的混合方案,核心时序数据按天分片存储,结合小时级预聚合表和Redis缓存热门查询,元数据通过CDC同步保证强一致性,并通过分片、预聚合、缓存优化实现秒级查询,同时明确数据一致性边界(库存数据允许1秒内延迟,元数据强一致)。

2) 【原理/概念讲解】
能源贸易的时序数据(价格、交易量、库存)核心是时间序列,查询多为时间范围聚合(如按小时查询价格走势)。传统关系型数据库(如MySQL)处理时间范围查询时,需复杂SQL(如窗口函数)且效率低;时序数据库(如TimescaleDB)专为时间序列设计,支持时间索引(快速定位时间窗口)、预聚合(提前计算统计量,如小时级平均价格),并按时间分片(如按天)实现水平扩展。预聚合表用于存储汇总数据(如按小时汇总价格、交易量),查询时优先从汇总表获取,减少实时表压力;Redis缓存热门时间范围查询(如最近1小时价格走势),设置动态TTL(根据访问热度调整,热门数据延长TTL),提升缓存命中率。元数据(品种、市场信息)存MySQL,通过CDC(如Debezium)同步,保证强一致性。类比:时序数据像按时间顺序排列的“流水线产品”,时序数据库是“时间切片仓库”,能快速按窗口取数据;关系型数据库是“产品说明书库”,管理规格,两者结合高效存储与查询。

3) 【对比与适用场景】

特性时序数据库(TimescaleDB)传统关系型数据库(MySQL)
定义专为时间序列设计,支持时间索引、预聚合、自动分片通用关系型数据库,支持复杂事务、ACID
查询性能优化时间范围查询,秒级聚合(时间索引+预聚合)处理时间范围查询效率低,需复杂SQL(如窗口函数)
数据一致性最终一致性(允许1-2秒延迟,适合时序场景)强一致性(事务,但时序查询慢)
适用场景实时监控、价格走势、库存变化(秒级查询)元数据管理(品种信息、用户权限、交易规则)
注意点分片后查询需路由,预聚合需定期更新关联时序数据时需JOIN,影响性能

4) 【示例】

  • 时序数据库(TimescaleDB)分片存储:按天分片,创建分片表(如存储2023-10-27数据)。

    CREATE DATABASE energy_market;
    CREATE TABLE price_data (
      time TIMETZ NOT NULL,
      product VARCHAR(50),
      market VARCHAR(50),
      price DECIMAL(10,2),
      volume BIGINT,
      inventory BIGINT,
      PRIMARY KEY (time, product, market)
    ) WITH (timescaledb.compress = true, timescaledb.table_name = 'price_data_day_20231027');
    INSERT INTO price_data (time, product, market, price, volume, inventory) VALUES ('2023-10-27 10:00:00+08', 'oil', 'shanghai', 60.5, 1000000, 5000000);
    
  • 预聚合表(按小时汇总):

    CREATE TABLE price_data_hourly (
      bucket TIMETZ NOT NULL,
      product VARCHAR(50),
      market VARCHAR(50),
      avg_price DECIMAL(10,2),
      total_volume BIGINT,
      PRIMARY KEY (bucket, product, market)
    ) AS
    SELECT time_bucket('1 hour', time) as bucket,
           product,
           market,
           AVG(price) as avg_price,
           SUM(volume) as total_volume
    FROM price_data
    GROUP BY bucket, product, market;
    
  • Redis缓存热门查询:

    SET price_trend_oil_shanghai_20231027_10_00_00 '{"time": "2023-10-27 09:00:00-10:00:00", "data": [{"time": "09:00", "price": 60.2}, ...]}' EX 300
    
  • MySQL存储元数据:

    CREATE TABLE product_info (
      product_id INT PRIMARY KEY,
      product_name VARCHAR(100),
      unit VARCHAR(20)
    );
    INSERT INTO product_info (product_id, product_name, unit) VALUES (1, '原油', '桶');
    
  • CDC同步:通过Debezium将时序数据写入MySQL,保证元数据一致性。

5) 【面试口播版答案】
面试官您好,针对海量时序数据的秒级查询需求,我建议采用混合数据库方案:核心时序数据用TimescaleDB按天分片存储,利用其时间索引和预聚合能力;元数据(品种、市场)存MySQL,通过CDC保证强一致;创建小时级预聚合表,查询时优先从汇总表获取;用Redis缓存热门时间范围查询(如最近1小时价格走势),设置动态TTL。这样既能实现秒级查询,又能管理元数据,同时通过分片、预聚合、缓存优化性能,并明确数据一致性边界(库存数据允许1秒内延迟,元数据强一致)。

6) 【追问清单】

  1. 如何处理每日10亿条数据的分片与扩展?

    • 回答:按天分片,每个分片存储约27.4M条数据(10亿/365),TimescaleDB支持自动分片,水平扩展时增加分片节点,保持单表性能。
  2. 数据一致性如何保证?

    • 回答:时序数据采用最终一致性(允许1-2秒延迟,适合时序场景),元数据通过MySQL事务和CDC同步保证强一致性。
  3. 如何优化秒级查询?

    • 回答:使用时间索引、预聚合(按小时聚合)、Redis缓存热门查询结果(如最近1小时价格走势),多级缓存(缓存+预聚合+实时表)。
  4. 预聚合表如何更新?

    • 回答:通过定时任务(如每小时cron job)或事件驱动(Kafka消费时序数据后触发),确保汇总表数据及时刷新。

7) 【常见坑/雷区】

  1. 分片策略错误(如按品种分片),导致查询时跨分片性能下降,应按时间范围分片。
  2. 预聚合更新不及时,导致汇总表数据滞后,影响查询准确性。
  3. 缓存仅缓存冷数据,导致命中率低,应缓存热门时间范围查询。
  4. 未明确数据一致性边界(如库存数据是否允许延迟),应说明延迟容忍的边界条件(如1秒内可接受)。
  5. 忽略时序与元数据的一致性边界(如时序数据更新后元数据未同步),导致系统不一致。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1