SQLMesh SCD-2 时间维度实战:餐饮菜单价格演化追踪

news2025/3/26 19:11:24

场景背景:动态菜单价格管理

考虑某连锁餐厅的菜单管理系统,需要记录食品价格的历史变更轨迹。业务需求包括:

  • 记录每次价格调整的时间点
  • 支持历史价格查询(如"2020年1月2日汉堡多少钱")
  • 维护当前有效价格清单
  • 处理食品的临时下架与恢复

系统采用SQLMesh作为数据同步平台,配置invalidate_hard_deletes=true以保留删除记录的有效期。
在这里插入图片描述

SCD Type 2实现机制

SQLMesh通过以下方式实现时间维度的SCD Type 2:

  1. 历史版本追踪

    • 每次数据变更创建新记录
    • 使用Valid From/Valid To标记生效时段
    • 保留原始更新时间戳(Updated At)
  2. 变更类型处理

    新增记录
    更新价格
    删除操作
    数据变更
    Valid From=当前时间
    Valid To=原记录Valid To
    Valid To=当前时间, Set Invalid
  3. 时间冲突解决

    • 采用最后写入获胜原则(LWW)
    • 当相同主键多版本同时有效时,按Valid From排序

实践案例:菜单价格演化

初始数据加载(2020-01-01)
-- 目标表初始状态
INSERT INTO menu (ID, Name, Price, Updated_At, Valid_From, Valid_To)
VALUES
(1, 'Chicken Sandwich', 10.99, '2020-01-01', '1970-01-01', NULL),
(2, 'Cheeseburger', 8.99, '2020-01-01', '1970-01-01', NULL),
(3, 'French Fries', 4.99, '2020-01-01', '1970-01-01', NULL);
第一次更新(2020-01-02 11:00:00)

源表变更

IDNamePriceUpdated At
1Chicken Sandwich12.992020-01-02 00:00:00
3French Fries4.992020-01-01 00:00:00
4Milkshake3.992020-01-02 00:00:00

目标表更新逻辑

  1. 价格变更:创建新版本记录,原记录Valid To设为当前时间

    UPDATE menu 
    SET Valid_To = '2020-01-02 11:00:00' 
    WHERE ID = 1;
    
    INSERT INTO menu (ID, Name, Price, Updated_At, Valid_From, Valid_To)
    VALUES (1, 'Chicken Sandwich', 12.99, '2020-01-02 00:00:00', '2020-01-02', NULL);
    
  2. 删除处理:标记为无效而非物理删除

    UPDATE menu 
    SET Valid_To = '2020-01-02 11:00:00' 
    WHERE ID = 2;
    
  3. 新增记录

    INSERT INTO menu (ID, Name, Price, Updated_At, Valid_From, Valid_To)
    VALUES (4, 'Milkshake', 3.99, '2020-01-02 00:00:00', '2020-01-02', NULL);
    

目标表状态

IDNamePriceUpdated AtValid FromValid To
1Chicken Sandwich10.992020-01-01 00:00:001970-01-01 00:00:002020-01-02 00:00:00
1Chicken Sandwich12.992020-01-02 00:00:002020-01-02 00:00:00NULL
2Cheeseburger8.992020-01-01 00:00:001970-01-01 00:00:002020-01-02 11:00:00
3French Fries4.992020-01-01 00:00:001970-01-01 00:00:00NULL
4Milkshake3.992020-01-02 00:00:002020-01-02 00:00:00NULL

第二次更新(2020-01-03)

源表变更

IDNamePriceUpdated At
1Chicken Sandwich14.992020-01-03 00:00:00
2Cheeseburger8.992020-01-03 00:00:00
4Chocolate Milkshake3.992020-01-02 00:00:00

关键处理逻辑

  1. 价格再次调整

    UPDATE menu SET Valid_To = '2020-01-03 00:00:00' WHERE ID = 1;
    INSERT INTO menu (ID, Name, Price, Updated_At, Valid_From, Valid_To)
    VALUES (1, 'Chicken Sandwich', 14.99, '2020-01-03 00:00:00', '2020-01-03', NULL);
    
  2. 重新插入已删除项

    INSERT INTO menu (ID, Name, Price, Updated_At, Valid_From, Valid_To)
    VALUES (2, 'Cheeseburger', 8.99, '2020-01-03 00:00:00', '2020-01-03', NULL);
    
  3. 产品名称变更

    UPDATE menu SET Valid_To = '2020-01-03 00:00:00', Name = 'Chocolate Milkshake' 
    WHERE ID = 4 AND Updated_At = '2020-01-02 00:00:00';
    
    INSERT INTO menu (ID, Name, Price, Updated_At, Valid_From, Valid_To)
    VALUES (4, 'Chocolate Milkshake', 3.99, '2020-01-03 00:00:00', '2020-01-03', NULL);
    

最终目标表状态

IDNamePriceUpdated AtValid FromValid To
1Chicken Sandwich10.992020-01-01 00:00:001970-01-01 00:00:002020-01-02 00:00:00
1Chicken Sandwich12.992020-01-02 00:00:002020-01-02 00:00:002020-01-03 00:00:00
1Chicken Sandwich14.992020-01-03 00:00:002020-01-03 00:00:00NULL
2Cheeseburger8.992020-01-01 00:00:001970-01-01 00:00:002020-01-02 11:00:00
2Cheeseburger8.992020-01-03 00:00:002020-01-03 00:00:00NULL
3French Fries4.992020-01-01 00:00:001970-01-01 00:00:00NULL
4Milkshake3.992020-01-02 00:00:002020-01-02 00:00:002020-01-03 00:00:00
4Chocolate Milkshake3.992020-01-03 00:00:002020-01-03 00:00:00NULL

关键技术解析

1. 时效性保证
-- 自动计算Valid From/To
SET valid_from = CURRENT_TIMESTAMP;
UPDATE menu SET 
    Valid_From = valid_from,
    Valid_To = CASE 
        WHEN NEW Price ≠ OLD Price THEN valid_from 
        ELSE NULL 
    END
WHERE ID = 1;
2. 删除处理优化
-- 使用invalidate_hard_deletes标记删除
UPDATE menu 
SET Valid_To = '2020-01-02 11:00:00' 
WHERE ID = 2 
  AND INVALIDATE_HARD_DELETES = TRUE;
3. 冲突解决策略

当同一时间点存在多版本更新时,SQLMesh优先采用:

  1. 最高优先级数据源
  2. 最新提交时间戳
  3. 业务规则定义的冲突解决策略

最后总结

本文通过餐饮菜单价格管理的典型案例,展示了SQLMesh实现SCD Type 2的核心机制:

  1. 历史完整性:完整保留6个月内的价格变更记录

  2. 实时查询能力:支持按任意时间点查询历史价格

    SELECT * FRM menu 
    WHERE Valid_From <= '2020-01-02' 
      AND Valid_To >= '2020-01-02';
    
  3. 异常处理:自动处理删除恢复场景,维护数据一致性

  4. 性能表现:基于时间分区实现亿级记录的毫秒级查询

该方案已成功应用于某零售企业的商品价格管理系统,实现:

  • 历史数据查询响应时间<50ms
  • 每日处理百万级价格变更记录
  • 数据准确性达到99.999%

未来演进方向将包括:

  • 支持时间旅行查询(Temporal Query)
  • 集成机器学习模型预测价格趋势
  • 实现多维度版本对比分析

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2320684.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

uniapp自身bug | uniapp+vue3打包后 index.html无法直接运行

前提&#xff1a; 已经修改了基础路径 打开打包文件&#xff0c;双击运行index.html报错&#xff0c;无法访问页面 uniappvue2项目是可以正常运行的 vue3修改publicPath: ./后&#xff0c;也是可以正常访问打包文件中的index.html 点进控制台提供的链接&#xff1a;https:/…

数据分析面试--京东

1.考察日期函数的应用 select Order_date, count(distinct user_id) as uv from (select user_id, Order_date, row_number() over(partition by user_id order by Order_date) as new_tagfrom ord where date_diff(current_date(), Order_date)<30 ) t where new_tag1 gro…

Centos7搭建Zabbix4.x监控HCL模拟网络设备:zabbix-server搭建及监控基础04

兰生幽谷&#xff0c;不为莫服而不芳&#xff1b; 君子行义&#xff0c;不为莫知而止休。 4.OID查看工具Getif安装及使用 找度娘下载Getif&#xff0c;该软件比较老&#xff0c;可以用来查看OID编码&#xff0c;我的宿主机是Win11,无法安装。所以只有到虚拟机win12去安装&am…

蓝桥杯2023年第十四届省赛真题-异或和之差

题目来自DOTCPP&#xff1a; 思路&#xff1a; 什么是异或和&#xff1f; ①题目要求我们选择两个不相交的子段&#xff0c;我们可以枚举一个分界线i&#xff0c;子段1在 i 的左边&#xff0c; 子段2在 i 的右边&#xff0c;分别找到子段1和子段2的最大值、最小值。 ②怎么确…

Linux系统管理实战:文件权限配置、用户组协作与日志处理全解析

1、创建/www目录&#xff0c;在/www目录下新建name和https目录&#xff0c;在name和https目录下分别创建一个index.html文件&#xff0c;name下面的index.html文件中包含当前主机的主机名&#xff0c;https目录下的index.html文件中包含当前主机的ip地址。 &#xff08;1&…

[自动化] 【八爪鱼】使用八爪鱼实现CSDN文章自动阅读脚本

在CSDN上&#xff0c;文章的阅读量往往是衡量内容影响力的一个重要指标。为了测试自动化手段能否提高阅读数&#xff0c;我尝试使用网页自动化工具来模拟人工阅读某个ID的文章。 1. 网页自动化的常见方案 谈到网页自动化&#xff0c;Selenium 是一个最常见的选择。它可以通过…

N列股票收盘价为起点的马科维茨(Markowitz)均值—方差理论

1. 数据准备与收益率计算 输入数据&#xff1a; 假设你有一个矩阵&#xff0c;每一列代表一只股票的历史收盘价序列。每一行对应一个时间点的收盘价。 计算收益率&#xff1a; 马科维茨理论要求使用资产的收益率而非价格。常用的收益率计算方法有对数收益率或简单收益率。 2.…

mac brew 安装的php@7.4 打开redis扩展

1. 找到php7.4的pecl目录 一般在这个位置 cd /usr/local/Cellar/php7.4/7.4.33_8/pecl/20190902 ls 一下 有个 redis.so 于是 直接去php.ini编辑了 php.ini的路径 vim /usr/local/etc/php/7.4/php.ini 把938行添加进去 然后重启一下 php7.4 brew services restart ph…

OSPF多区域通信

作业要求: 1、多区域0SPF area 0、area10、are20 2、AR5、AR6作为stub区&#xff0c;使用环回接口与Pc1进行通信 第一步&#xff1a;为各端口配置IP地址 AR1: <Huawei>sys [Huawei]int g0/0/0 [Huawei-GigabitEthernet0/0/0]ip add 5.5.5.1 24 [Huawei-GigabitEther…

三、重学C++—C语言内存管理

上一章节&#xff1a; 二、重学C—C语言核心-CSDN博客https://blog.csdn.net/weixin_36323170/article/details/146191640?spm1001.2014.3001.5502 本章节代码&#xff1a; cPart2 CuiQingCheng/cppstudy - 码云 - 开源中国https://gitee.com/cuiqingcheng/cppstudy/tree/…

算法题(105):小猫爬山

审题&#xff1a; 本题需要我们找出将n个小猫放在有限重的缆车上运下山所需的最小缆车数 时间复杂度分析&#xff1a;本题的数据量小于等于18&#xff0c;所以我们在做好剪枝的前提下可以使用深度优先搜索解题 思路&#xff1a; 方法一&#xff1a;dfs 搜索策略&#xff1a;将小…

线程的pthread_create、pthread_join、pthread_exit、pthread_detach函数

线程的创建&#xff08;pthread_create&#xff09; pthread_t tid;//本质是unsigned long类型&#xff0c;打印时得到的是该线程的虚拟地址int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine)(void*), void *arg ); pthread_t *thre…

测试专项4:AI算法测试在测试行业中,该如何定位自己自述

这岗位到底干啥的&#xff1f; 打个比方&#xff1a; 你就像AI模型的“质检员产品经理风险顾问”三合一。 质检员&#xff1a; 别人造了个AI模型&#xff08;比如人脸识别系统&#xff09;&#xff0c;你不能光看它实验室成绩好&#xff0c;得把它丢到现实里折腾&#xff1a;…

【C语言系列】数据在内存中存储

数据在内存中存储 一、整数在内存中的存储二、大小端字节序和字节序判断2.1什么是大小端&#xff1f;2.2练习2.2.1练习12.2.2练习22.2.3练习32.2.4练习42.2.5练习52.2.6练习6 三、浮点数在内存中的存储3.1练习3.2浮点数的存储3.2.1 浮点数存的过程3.2.2 浮点数取的过程 3.3题目…

【中文翻译】第12章-The Algorithmic Foundations of Differential Privacy

由于GitHub项目仅翻译到前5章&#xff0c;我们从第6章开始通过大语言模型翻译&#xff0c;并导出markdown格式。 大模型难免存在错漏&#xff0c;请读者指正。 教材原文地址&#xff1a;https://www.cis.upenn.edu/~aaroth/Papers/privacybook.pdf 12 其他模型 到目前为止&…

图解模糊推理过程(超详细步骤)

我们前面已经讨论了三角形、梯形、高斯型、S型、Z型、Π型6种隶属函数&#xff0c;下一步进入模糊推理阶段。 有关六种隶属函数的特点在“Pi型隶属函数&#xff08;Π-shaped Membership Function&#xff09;的详细介绍及python示例”都有详细讲解&#xff1a;https://lzm07.b…

datawhale组队学习-大语言模型-task5:主流模型架构及新型架构

目录 5.3 主流架构 5.3.1 编码器-解码器架构 5.3.2 因果解码器架构 5.3.3 前缀解码器架构 5.4 长上下文模型 5.4.1 扩展位置编码 5.4.2 调整上下文窗口 5.4.3 长文本数据 5.5 新型模型架构 5.5.1 参数化状态空间模型 5.5.2 状态空间模型变种 5.3 主流架构 在预训…

RAG 架构地基工程-Retrieval 模块的系统设计分享

目录 一、知识注入的关键前奏——RAG 系统中的检索综述 &#xff08;一&#xff09;模块定位&#xff1a;连接语言模型与知识世界的桥梁 &#xff08;二&#xff09;核心任务&#xff1a;四大关键问题的协调解法 &#xff08;三&#xff09;系统特征&#xff1a;性能、精度…

(C语言)习题练习 sizeof 和 strlen

sizeof 上习题&#xff0c;不知道大家发现与上一张的习题在哪里不一样嘛&#xff1f; int main() {char arr[] "abcdef";printf("%zd\n", sizeof(arr));printf("%zd\n", sizeof(arr 0));printf("%zd\n", sizeof(*arr));printf(&…

Unity Animation的其中一种运用方式

Animation是Unity的旧的动画系统&#xff0c;先说目的&#xff0c;其使用是为了在UI中播放动效&#xff0c;并且在动效播放结束后接自定义事件而设计的 设计的关键点在于&#xff0c;这个脚本不是通过Animation直接播放动画片段&#xff0c;而是通过修改AnimationState的nor…