未记录事实核验 · 状态:维护中
记录仅说明核验时间与维护状态,不保证适用于所有环境;使用前请留意正文中的版本、适用条件与风险提示。
warning 适用范围与待维护事项
本文用于代码版本控制概念入门,不是生产发布或数据恢复操作指南。开篇“2023 年某公司小王”及“少了好几百万”没有可核实来源,应仅作为保留原稿情节与数字的教学假设,不作真实事故证据。完整本地历史以普通完整克隆为前提,浅克隆不适用;Git 的快照是逻辑模型,底层仍可能采用差异压缩。Git 回退代码不会自动撤销数据库变更,分析与模型复现还依赖数据、依赖版本和运行环境。
版本控制概念 - 为什么数据从业者必须用 Git
abstract 本章概要
- 理解版本控制解决的核心问题
- 了解 Git 与 SVN 的根本区别
- 认识数据项目中版本管理的真实痛点
- 建立"快照"和"历史"的基本思维模型
一个教学假设故事(原稿情节未核实)
以下将原稿未核实的情节作为教学假设,年份、人物和损失数字均不代表已核实事实:假设在 2023 年,某公司数据团队的 ETL 工程师小王,负责维护一套订单数据清洗脚本。
某天接到需求,要给 VIP 用户的订单金额打 9 折。他改了脚本,上线测试。没问题,发布。
三天后,财务发现对账数字不对,少了好几百万。
排查发现:小王改脚本时,不小心把一行过滤逻辑给注释掉了,导致部分无效订单也进了统计。
最大的问题是:他已经找不回改之前的代码了。备份文件夹里有五六个版本,每个都叫 etl_orders_final.py、etl_orders_final_v2.py,但哪个是"改之前"的那个,没人说得清。
这个教学假设用来说明缺乏版本记录可能造成的排查困难,不代表此类事件的实际发生频率。
什么是版本控制
版本控制(Version Control)是一种记录文件变化历史的系统,使你可以查看特定版本的文件内容,比较不同时间点的差异,以及在需要时恢复到已记录且仍可访问的历史状态。
简单说:版本控制就是给你的代码拍照片,建相册。
每次你做了有意义的修改,就按一次快门(commit),系统记录下此刻代码的状态。以后任何时候,你都能翻回到这张"照片"的时刻。
时间线 ──────────────────────────────────────────►
v1.0 v1.1 v1.2 v1.3
│ │ │ │
●────────────●────────────●─────────────●
初始版本 添加VIP折扣 修复过滤bug 优化性能
没有版本控制,数据工作有多痛
痛点一:手动备份地狱
orders_etl.py
orders_etl_v2.py
orders_etl_v2_final.py
orders_etl_v2_final_修改.py
orders_etl_v2_final_修改_确认.py
orders_etl_备份20240315.py
orders_etl_上线前备份.py
这个目录你一定见过。它有几个致命问题:
- 不知道每个版本改了什么
- 不知道哪个是真正在用的
- 存储浪费(每个文件都是全量备份)
- 时间久了没人敢删
痛点二:协作就是噩梦
小李在改 dim_user.sql 的用户分层逻辑,小张同时也在改这个文件优化 JOIN 性能。
两个人改完,怎么合并?
- 用邮件互相发文件?丢修改
- 共享网盘?会互相覆盖
- 用企业微信发来发去?版本完全乱掉
痛点三:出了问题无法追责也无法回滚
生产环境出了数据质量问题:
- 谁改的这行代码?
- 什么时候改的?
- 改之前是什么逻辑?
- 怎么快速回到改之前的状态?
没有版本控制,这四个问题没有一个能快速回答。
痛点四:无法并行开发
数据仓库上新功能时,需要同时:
- 修复生产 bug(紧急)
- 开发新的指标逻辑(需要两周)
- 优化现有 SQL 性能(实验性)
没有分支机制,这三件事根本没法同时进行,只能排队做。
Git 是什么
Git 是广泛使用的分布式版本控制系统,由 Linux 内核的创始人 Linus Torvalds 于 2005 年开发。
note Git 的三个关键特性
- 分布式:普通完整克隆通常包含所获取分支的完整版本历史,本地查看历史和提交不依赖中央服务器;浅克隆不包含完整历史
- 快照模型:逻辑上记录每次提交时已跟踪文件的状态,而非仅记录修改指令;底层存储仍可能采用差异压缩
- 轻量分支:创建分支几乎是零成本的,鼓励多分支工作流
Git 的工作区域模型
工作区 暂存区 本地仓库 远程仓库
(Working Dir) (Staging Area) (Local Repo) (Remote Repo)
│ │ │ │
│ git add ──► │ git commit ──► │ git push ──► │
│ │ │ │
│ ◄── git checkout ──────────────── │ ◄── git pull ──│
这个模型是理解 Git 的关键。先不用完全搞懂,学到 03-Git基础操作 时会有深入讲解。
Git vs SVN:一个根本性的区别
如果你所在的团队使用 SVN(Subversion),有必要了解它与 Git 的差异;本文不据此判断具体行业的采用比例。
| 对比维度 | SVN(集中式) | Git(分布式) |
|---|---|---|
| 存储架构 | 版本历史由中央仓库管理 | 普通完整克隆包含所获取分支的完整历史,浅克隆除外 |
| 网络依赖 | 大多数操作需要联网 | 大多数操作可以离线 |
| 分支成本 | 通常以仓库内的廉价目录拷贝实现,不复制全部文件内容 | 分支是引用,创建成本很低 |
| 分支策略 | 支持分支,使用频率和合并流程取决于团队 | 轻量分支常用于并行开发工作流 |
| 历史回溯 | 可以,但需要服务器 | 本地即可,速度极快 |
| 灾难恢复 | 中央服务器故障可能中断服务,能否恢复取决于仓库备份等措施 | 完整克隆可恢复其包含的提交历史,但不一定包含服务器配置、权限及外部资产 |
| 学习曲线 | 相对平缓 | 初期陡峭,熟练后更强大 |
| 适用判断 | 是否保留取决于现有系统与协作需求 | 是否采用取决于团队工作流与迁移成本 |
tip 如果你现在还在用 SVN
SVN 支持分支,仓库内创建分支通常也是廉价拷贝,不能理解为“只有主干,分支很贵”。Git 的分支是轻量引用,本地提交和分支工作流更灵活;选择工作流时仍需考虑合并、评审和发布规则。
Git 如何存储数据
理解这个会让你更不容易犯错。
SVN 的方式:集中管理版本
以下保留差异存储的简化示意,用于帮助理解,不代表 SVN 所有存储后端的具体实现,也不能据此推断其历史恢复性能。
版本1: 完整文件 [A, B, C]
版本2: 在版本1基础上改了A → [ΔA, B, C]
版本3: 在版本2基础上改了C → [ΔA, B, ΔC]
恢复到版本3 = 版本1 + ΔA + ΔC(需要计算)
Git 的方式:记录快照
版本1: [A1, B1, C1] (完整快照,未改变的文件指向同一个对象)
版本2: [A2, B1, C1] (A改了,用A2;B和C没变,复用之前的对象)
版本3: [A2, B1, C2] (C改了,用C2;A和B没变,复用)
Git 用这种方式实现了:
- 按提交访问已记录的快照(逻辑上不必逐次重放修改;底层仍可能解压或还原差异,速度取决于仓库规模和存储布局)
- 存储高效(相同内容只存一份,用哈希去重)
- 内容变化可由哈希标识反映(提交内容改变会产生不同的对象标识,但分支引用和历史仍可被重写或删除,不能据此保证历史不可篡改)
三个关键概念
在正式开始操作之前,把这三个概念搞清楚,后续学习会顺畅很多。
概念一:仓库(Repository / Repo)
仓库就是一个被 Git 管理的目录。这个目录里有你的代码文件,还有一个隐藏的 .git 文件夹(Git 用来存储所有版本信息的地方)。
my_data_project/
├── .git/ ← Git 的"大脑",里面是所有历史
├── sql/
│ └── orders.sql
└── scripts/
└── etl.py
warning 不要手动修改 .git 目录
.git 文件夹是 Git 的核心数据存储,除非你知道自己在做什么,否则永远不要手动改这里的任何东西。误操作可能导致整个仓库损坏。
概念二:提交(Commit)
提交是版本历史中的一个节点,代表某一时刻代码的完整快照。每次提交都有:
- 一个内容寻址的对象标识(常见仓库使用 SHA-1,也支持 SHA-256;
a3f8b2c是缩写示例,缩写需在当前仓库中足以区分对象) - 提交人信息
- 提交时间
- 提交说明(你写的 commit message)
- 零个或多个父提交引用(初始提交没有父提交,普通提交通常有一个,合并提交可有多个)
概念三:分支(Branch)
分支是指向某个提交的可移动指针。创建分支不复制代码,只是新增一个指针。
main ───●────●────●────●
↑
feature/vip-discount
(从这里分叉出去)
│
●────●
(新功能的独立开发)
数据项目的版本管理策略思考
不同类型的数据工作,Git 的使用侧重点不同:
| 工作类型 | 核心场景 | Git 价值 |
|---|---|---|
| 数据分析师 | Jupyter Notebook、分析脚本、SQL 查询 | 复现分析结果、回溯历史版本 |
| 数据开发工程师 | ETL 脚本、数据管道、调度配置 | 协作开发、变更管理、回滚 |
| 数据架构师 | 建表脚本、数据模型、架构文档 | 方案演进历史、评审记录 |
| 数据科学家 | 模型训练代码、特征工程、实验配置 | 实验追踪、模型复现 |
具体的数据项目实践,参见 08-数据项目Git实践。
小结
| 核心概念 | 一句话理解 |
|---|---|
| 版本控制 | 给代码建时光机 |
| Git | 分布式版本控制,普通完整克隆可在本地保有所获取分支的完整历史 |
| 仓库(Repo) | 被 Git 管理的项目目录 |
| 提交(Commit) | 代码历史上的一个存档点 |
| 分支(Branch) | 并行开发的独立空间 |
| Git vs SVN | Git 分布式+引用式分支,SVN 集中式+廉价目录拷贝式分支 |
掌握检查
- [ ] 能用一句话解释版本控制解决了什么问题,不用"改来改去"之类的模糊表述
- [ ] 能解释 Git 的逻辑快照模型与 SVN 的集中式版本管理,并知道不能仅凭快照或差异示意推断历史恢复性能
- [ ] 知道
.git文件夹存放什么,以及为什么不能手动修改它 - [ ] 能区分"工作区""暂存区""仓库"三个概念,并说出数据流向(改了文件 → add → commit)
- [ ] 知道 Git 的分布式特性意味着什么:普通完整克隆可在本地保有所获取分支的完整历史,断网也能查看已有日志和回退到已有提交;浅克隆的历史范围有限
下一步:Git安装与配置 - 把 Git 装好,连上 GitHub,准备开始实操。