面试题答案
一键面试Redis预计算
- 数据获取:
- 定时任务或触发机制从MySQL中提取生成报表所需的基础数据。例如,如果报表是关于每日销售总额,可通过SQL查询获取每天的销售记录数据。
- 使用
SELECT
语句从相关MySQL表中查询数据,如SELECT amount, sale_date FROM sales WHERE sale_date >= CURDATE() - INTERVAL 1 DAY
。
- 预计算逻辑:
- 在Redis中,根据报表需求进行计算。若计算销售总额,可使用Redis的哈希(Hash)结构存储每日销售记录。将每条销售记录的金额累加到对应日期的哈希字段值上。例如,使用
HINCRBY
命令,假设哈希键为sales:daily:total
,字段为日期,值为销售总额,执行HINCRBY sales:daily:total 2023 - 10 - 01 <amount>
,其中<amount>
为从MySQL查询出的销售金额。 - 对于复杂计算,如计算不同地区的销售占比,可先在Redis中通过集合(Set)或哈希结构分别存储各地区的销售数据,再进行比例计算。例如,使用哈希结构存储各地区销售总额,键为
region:sales:total
,字段为地区名称,值为该地区销售总额,通过计算各地区总额与总销售金额的比例得到销售占比。
- 在Redis中,根据报表需求进行计算。若计算销售总额,可使用Redis的哈希(Hash)结构存储每日销售记录。将每条销售记录的金额累加到对应日期的哈希字段值上。例如,使用
- 存储结果:
- 将预计算结果存储在Redis合适的数据结构中。简单的数值结果可使用字符串(String)存储,如每日销售总额可使用
SET daily_sales_total <total_amount>
。 - 复杂的报表数据,如包含多个指标的报表,可使用哈希(Hash)结构,一个键对应整个报表数据,不同字段对应不同指标。例如,报表包含销售总额、订单数量、平均订单金额,可使用
HMSET report:2023 - 10 - 01 total_sales <total_amount> order_count <count> average_order_amount <average>
。
- 将预计算结果存储在Redis合适的数据结构中。简单的数值结果可使用字符串(String)存储,如每日销售总额可使用
与MySQL交互加快报表生成
- 结果写入MySQL:
- 预计算完成后,将Redis中的结果数据定期或按需写入MySQL。对于每日销售总额,可使用
INSERT INTO report_sales (report_date, total_sales) VALUES ('2023 - 10 - 01', <total_amount>) ON DUPLICATE KEY UPDATE total_sales = <total_amount>
,这里<total_amount>
从Redis中获取,通过Redis的GET daily_sales_total
命令获取值并插入MySQL。 - 对于复杂报表数据,可通过构建SQL语句,将哈希结构中的各个字段值对应插入MySQL表的相应列中。例如,对于上述包含多个指标的报表数据,可构建复杂的
INSERT
或UPDATE
语句来更新MySQL报表表。
- 预计算完成后,将Redis中的结果数据定期或按需写入MySQL。对于每日销售总额,可使用
- 报表生成时的数据读取:
- 当生成报表时,优先从MySQL读取预计算结果。若MySQL中不存在最新的预计算数据,再从Redis读取并更新MySQL。例如,在生成报表SQL查询中,直接从存储预计算结果的MySQL表中查询,如
SELECT * FROM report_sales WHERE report_date = '2023 - 10 - 01'
。 - 这样可以充分利用MySQL的查询优化机制,同时利用Redis的高速预计算能力,大大加快报表生成速度。
- 当生成报表时,优先从MySQL读取预计算结果。若MySQL中不存在最新的预计算数据,再从Redis读取并更新MySQL。例如,在生成报表SQL查询中,直接从存储预计算结果的MySQL表中查询,如