夜雨聆风学习资料网

ARTICLE · 986550

数据基建不是 Excel 换皮:四个让数据库真正值钱的设计思维

数据基建不是 Excel 换皮:四个让数据库真正值钱的设计思维

公众号「爱折腾的电力交易」· 🅰 AI 自动化系列(知乎同步)· 第 5 篇 · 2026-08-31

上一篇结尾我挖了个坑:为什么说"数据基建不是 Excel 换皮"。

因为我见过太多人(包括半年前的我)迁移完数据库,就以为基建做完了。结果呢?数据库里躺着一张巨型宽表,和 Excel 一样谁都不敢动;数据照样重复、照样对不上、照样靠人肉核对。换了壳,没换命。

Excel 换皮和真正的数据基建,差的不是工具,是四个设计思维。

一、真相源思维:一个数,只有一个地方是对的

先讲个我上周刚踩的坑。

我们的申报系统里有个"申报电量"数。这个数在两个入口能被看到:一个后台管理页,一个对外展示页。某天早上,操作员确认了一个电量数,系统也存了。结果下午打开对外页面——数不对,还是确认前的旧预测值。

排查下来两层原因,都特别典型:

· 后台生成方案的脚本在操作员确认之前就跑过了,存的是旧预测。确认动作发生之后,没人重新生成——旧结果赖在库里没被刷新。

· 对外页面更绝:它不信库里的数,现场重新算了一遍预测。它不知道"确认值"的存在,于是把老板已经拍板的数覆盖成了一个自作聪明的估算。

两层 bug,指向同一个病根:同一个数,有好几个"权威来源"。

修复思路不是打补丁,是立规矩:

一个数,只有一个权威来源(Single Source of Truth)。其他所有地方只能引用它,不能复制它、更不能自己重新算一遍。

确认值存在哪、谁优先、预测什么时候算——全部写死成一条读取逻辑,所有入口共用。修完之后,两个页面永远显示同一个数,因为它们读的是同一行代码查的同一行数据。

Excel 时代这个问题无解:一个数复制到十张表里,改了源头忘了下游,三个月后没人知道哪个是对的。数据库时代的第一课就是:别让数据有第二个家。

二、分库思维:事实、预测、交易,天生不能住一起

迁移那篇提过一句"实际数据、预测数据、交易记录各一个库",这篇展开讲为什么——因为这三类数据的"脾气"完全不同:

实际数据 = 事实:历史永不改变,正确姿势是只追加。混进去的下场:被预测污染。

预测数据 = 观点:天天变,正确姿势是覆盖 + 留版本。混进去的下场:把事实冲掉。

交易记录 = 行为:做过就是做过,永不改变,只追加。混进去的下场:对不上账。

分库不是洁癖,是防止三种脾气互杀:

预测必须版本化。我每天对同一时段做预测,今天的预测和明天的预测不一样——这很正常,但如果你只存"最新值",就永远无法回答"昨天的预测到底准不准"。我的做法是每次预测存成带时间戳的快照,复盘时才能对着旧版本算误差。

事实数据不可覆盖。实际出清价、实际出力,落库之后就是历史事实。任何脚本都只有 INSERT 权限,没有 UPDATE 权限。谁想"修正"历史?先写说明,留痕,再动。

交易记录只追加。做过的交易是审计依据,错了也是历史的一部分,修正用冲正记录,不用删改。

反过来想:如果三者混在一个库一张表里会发生什么?预测刷新的时候顺手把实际值覆盖了——这种事故一旦发生,你的所有历史分析全部作废,而且你都不知道从哪天开始作废的。

三、约束思维:让数据库替你挡错,而不是靠人眼

Excel 防错靠什么?靠小心。粘贴之前看一眼,发出去之前对一遍。人眼是最贵的校验器,而且是最不可靠的。

数据库的约束(constraint)是真正意义上的物理防线。核心就一条:

CREATE UNIQUE INDEX idx_price ON da(trade_date, slot);

唯一键 = 数据的身份证。同一个交易日、同一个时点,物理上不允许出现两条记录。

这个约束建好之后,一类事故直接灭绝:重复入库。脚本重跑、人工误触发、网络重传——不管上游怎么折腾,重复数据在数据库门口就被拦下,报错给你看,而不是安安静静躺三个月等你画图时发现曲线整体翻倍。

我的铁律:每个表建表第一天就定好唯一键。业务身份是什么,唯一键就是什么。价格表是"日期+时点",气象表是"站点+日期+时点",预测表是"目标时段+预测版本"。

有人会说:约束挡住重跑,那我重跑不就失败了?这就引出第四个思维——

四、幂等思维:跑十遍,等于跑一遍

幂等(idempotent):同一个操作执行一次和执行 N 次,结果完全一样。

为什么这件事值钱?因为一切自动化的前提是幂等。

我的调度器每天自动跑十来个步骤:下载数据、入库、跑预测、生成方案。网络抖一下,某步失败了,我重跑这一步——如果入库是"追加"逻辑,重跑一次数据就翻倍;如果整个链路重跑,数据就翻好几倍。

所以我的所有入库脚本都用同一个套路——upsert:

INSERT INTO da(trade_date, slot, price) VALUES ('2026-08-27', 96, 359.7) ON CONFLICT(trade_date, slot) DO UPDATE SET price = excluded.price;

有就更新,没有就插入。重跑一百遍,库里还是那份数据。

这个思维配合前面的唯一键约束,才敢放心做一件事:无人值守。脚本半夜失败,我早上补跑就行,不用提心吊胆检查"这次重跑会不会把数据弄脏"。Excel 时代你敢让任何流程自动重跑吗?不敢,因为每跑一遍,结果都可能不一样。

换皮和基建的分界线

数的来源:换皮=复制到多处靠人对;基建=单一真相源,处处引用

存储结构:换皮=一张大表走天下;基建=按数据脾气分库分表

防错:换皮=靠人眼校验;基建=靠约束物理拦截

重跑:换皮=越跑越脏;基建=幂等,随便跑

自动化:换皮=不敢;基建=敢

判断你的数据库是基建还是换皮,就看这五行。一行都没做到,那它只是个不会蓝屏的 Excel。

做到五行之后呢?下一个问题来了:你一个人守着这套基建没问题,同事要看数、要改数、要借数的时候怎么办?下一篇聊:团队协作——怎么让同事不搞乱你的表。

🅰 AI 自动化系列已发 5 篇:①从 Excel 地狱到自动化 → ②月度电量预估 → ③版本地狱自救 → ④迁移到数据库 → ⑤本篇。关注「爱折腾的电力交易」,交易干货持续更新。本文为个人交易笔记与技术分享,不构成任何交易建议。

相关学习资料