相信很多人都有过这样的经历:手机里装了四五个健康类App,体重记录在一个App里,跑步数据在运动社区里,体检报告躺在网盘的某个文件夹里,药方和检查单要么拍照积压在图库里,要么夹在纸质病历本里。每次想看某个指标的变化趋势,得先把几个App的数据翻一遍,还经常发现同一时期在两个App里记的数字对不上。
我后来把整套流程都搬进了Obsidian,用纯文本笔记重新搭了一个个人健康管理系统。它不看厂商脸色,不用被某个社区功能绑架,所有数据都是本地Markdown文件,查询、统计、归档都自己说了算。这篇文章就把完整的搭建思路、目录结构、模板代码、踩坑记录一并写出来,给同样想把健康数据握在自己手里的朋友做个参考。
1. 需求盘点:健康管理系统到底要管什么
1.1 信息分散,才是真正的痛点
做系统之前,我列过一个需求清单,发现健康管理这件事本身并不复杂,复杂的是数据散落得太厉害。睡眠时间跟情绪状态有关系,但它们分别在两个App里,没法放在同一张表里看;体检报告里的血脂数值和日常饮食记录本来应该放在一起解读,实际上却隔着一整个网盘的距离。
所以第一步不是急着建笔记,而是先想清楚:这个系统要覆盖哪些数据、要为哪些决策服务。对我个人来说,核心是三类内容:每日身体与生活状态、周期性测量数据、医疗档案与医嘱。
1.2 相比App打卡,本地笔记库赢在四个地方
用Obsidian管理健康,不是因为它能做得比专业健康App更花哨,而是因为它解决了App很难解决的四件事:
第一,数据所有权。所有笔记都是本地文件,不存在“换设备就丢记录”的问题,也不需要担心某个App某天改版后把数据隐藏起来。
第二,结构可自定义。App的字段是厂商预设好的,只能填它给你的项;笔记库的字段完全自己定,今天想加一个“夜间醒了几次”,明天想加一个“咖啡因摄入”,插件里改一行字段就搞定。
第三,反向链接能帮你做归因。睡眠差的那天到底发生了什么?吃得油腻还是加班太晚?一条记录的正文里,可以自然链到另一条记录上,这种关联性用表格类App做不出来。
第四,查询能力。Dataview插件能直接把散落在几十条笔记里的数据捞出来,按日期、按数值、按标签过滤,汇总成表。App里想看“最近30次体重”,需要翻到统计页等它慢慢算;这里一条查询语句就出来了。
1.3 它适合谁,不适合谁
这套方案适合用来做自我量化、慢病日常跟踪、体重管理、体检报告归档、运动记录整理。但它不是医疗设备,不能替代血压计、血糖仪本身的测量读数,更不能替代医生的诊断。我的原则是:记录归记录,看病归看病,系统里只存客观数据和医生的明确建议,不自己给自己下结论。
这个边界必须想清楚,否则后面很容易把个人笔记库当成一个“越用越准”的健康预测工具,那是危险的。
2. 先搭骨架:目录、标签、模板三位一体
2.1 目录结构:四段式编号,读起来一目了然
Obsidian默认把所有文件平铺在库里,如果几周下来不做规划,库就会变成一锅粥。我用了一套四位前缀的编号结构,兼顾排序和归类,复制即可用:
健康管理/ ├─ 00-收件箱/ ├─ 01-模板/ │ ├─ 每日健康日志模板.md │ ├─ 测量记录模板.md │ ├─ 事件记录模板.md │ └─ 体检档案模板.md ├─ 10-每日记录/ │ └─ 2025/ ├─ 20-测量/ │ ├─ 体重/ │ └─ 血压/ ├─ 30-日志/ │ ├─ 运动/ │ ├─ 饮食/ │ └─ 睡眠/ ├─ 40-档案/ │ ├─ 体检报告/ │ ├─ 门诊记录/ │ └─ 过敏与药物/ └─ 50-回顾/ └─ 周回顾.md很多新手上来就把所有笔记塞进同一个文件夹,然后靠标签硬撑。我的经验是,文件夹解决“归档在哪里”,标签解决“从哪个角度检索”,两者分工明确。00-收件箱用来临时记录,比如在地铁上突然想到今天要补记一条药盒上的剂量信息,先丢进去,周末再归类。
2.2 标签体系:够用就好,别文艺
标签不是越多越好,我见过有人给一条笔记挂了八个标签,结果没有一个能精确过滤。我的标签体系很克制,全部带健康/前缀,母子关系用/表达:
#健康/体重:所有体重测量笔记#健康/血压:血压测量笔记#健康/运动/跑步、#健康/运动/力量:运动类型#健康/睡眠:睡眠日志#健康/饮食:饮食日志#健康/情绪:情绪相关记录#健康/症状:身体不适记录
注意标签里不能用空格,#健康 体重是两个标签而不是一个层级标签。层级标签的好处是,写查询时只写#健康/运动也能覆盖下面所有子类。
2.3 插件不贪多,三个先保底
- Dataview:数据查询引擎,本系统的绝对核心。
- Templater:模板引擎,让每天新建笔记时自动填充日期、基本字段。
- Calendar:在侧边栏显示日期,点击某天直接跳到当天日志。
这三个插件加起来还是轻量的。体重曲线图之类的我会放到第4章单独讲,不建议一开始就折腾图表可视化,先把数据录进去再说。
3. 核心模块实操:动作分解与模板示例
3.1 每日健康日志:手工录入频率最高的入口
每天打开Obsidian必做的动作,就是新建一篇当天日期的健康日志。Templater模板如下:
--- 日期: <% tp.date.now("YYYY-MM-DD") %> 周数: <% tp.date.now("W") %> 类型: 健康日志 --- ## 睡眠 - 入睡时间: - 起床时间: - 睡眠质量评价(1-5): ## 运动 - 运动类型: - 运动时长(分钟): - 主观强度(1-10): ## 饮食 - 早餐: - 午餐: - 晚餐: - 饮酒/咖啡因:无/有(多少量) ## 情绪与精力 - 精力评分(1-10): - 情绪评分(1-10): - 备注: ## 症状与用药 - 是否不适:无/有 - 症状描述: - 用药记录:药品名 + 剂量 + 时间关键点是YAML里的英文字段名。写模板时我用中文表头给自己看,但frontmatter字段全用英文小写,比如sleep_hours、mood_score、symptom_desc。原因很简单,Dataview查询时要用字段名,如果字段是中文,写查询代码就得频繁切换输入法,容易错。字段名统一用英文,显示名放在查询代码里再映射成中文。
你可以不抄这个模板,但一定要遵守三条规则:字段名全局统一、日期用YYYY-MM-DD、所有数值保持同一种单位。体重要么全填公斤,要么全填斤,混着填会直接在统计表里制造灾难。
3.2 测量数据:一条笔记只记一次测量
体重、血压、心率这类数据,我强烈建议一条笔记只记录一次测量,而不是在一篇笔记里堆积多条记录。这样写有两个好处:一是Dataview可以直接按笔记条目读取数值,不用在一段文本里解析哪个数字是体重哪个是腰围;二是每次测量的时间、工况(是否晨起空腹、是否运动后)都有独立空间去描述,不会混成一片。
我的体重测量模板长这样:
--- 日期: <% tp.date.now("YYYY-MM-DD") %> 时间: <% tp.date.now("HH:mm") %> 类型: 体重测量 体重_kg: 体脂率_percent: 腰围_cm: 备注: 标签: - 健康/体重 --- #### 测量条件 (晨起空腹/运动后/餐后) #### 与上次相比的变化 (体重、围度、主观感受)同样,血压模板就是收缩压、舒张压、心率三个数值字段。每次测完,花30秒就能录入。
3.3 事件类记录:运动、饮食、睡眠的统一处理
运动、饮食、睡眠这三类记录,我不建独立模板,全部复用事件记录模板,靠标签区分领域:
--- 日期: <% tp.date.now("YYYY-MM-DD") %> 类型: 事件记录 事件标签: - 健康/运动/跑步 项目: 5公里慢跑 时长_min: 32 强度评分: 7 备注: ---饮食日志则把每一顿的关键内容写进备注,字段只有时间段、食物、大概热量、是否规律这几个。这样设计的理由是,饮食记录非常容易半途而废,如果一个笔记要求你把一日三餐的营养素全部精确到克,大概率坚持不了一周。降低记录粒度,先保证“记了”这个动作本身。
3.4 体检报告与病历归档:文档扫描件与双链档案
体检报告是PDF或纸质件,不能直接变成纯文本笔记。我的做法分几步:PDF报告存进Vault的40-档案/体检报告/子文件夹,图片扫描件也放同一目录,然后在目录里建一篇索引笔记,记录检查日期、机构名称、主要结果、医生建议,并用Markdown图片语法把关键检查表嵌到笔记里。
病历类笔记则使用双链互相连接。比如一篇就诊记录-骨科-右膝的笔记,正文里会链到上一年的同主题笔记,Pain记录里写了右膝不适的日期,也会反链到这篇就诊记录。Obsidian底部面板的反向链接区域会自动展示所有引用过它的笔记,这样系统性看某段时间的各类记录时,线索是串联在一起的。
4. 把数据变成趋势和答案
4.1 用Dataview做汇总表:30秒拉出最近体重记录
模板建齐了,数据也录了一周,下一步就是把散落的记录变成可看的表格。Dataview默认的查询语法很接近SQL,下面这段代码放在任何一篇笔记里都能显示体重表:
TABLE WITHOUT ID file.link AS "日期", weight_kg AS "体重(kg)", body_fat_percent AS "体脂率(%)", waist_cm AS "腰围(cm)" FROM "健康管理/20-测量/体重" WHERE weight_kg != null SORT file.name DESC LIMIT 30FROM后面的路径必须是你的Vault里真实存在的路径,大小写和空格都要一致。WHERE weight_kg != null是为了把还没填数值的空模板笔记过滤掉,否则表格里会出现一行行空白记录。
4.2 移动平均比单次读数更有参考价值
体重这种东西,一天之内的波动能达到一公斤以上,单次读数意义有限。我更关心趋势,所以用Dataviewjs算最近7次记录的移动平均:
const pages = dv.pages('"健康管理/20-测量/体重"') .filter(p => p.weight_kg) .sort(p => p.file.name, 'asc'); const last7 = pages.slice(-7).map(p => p.weight_kg); const avg = (last7.reduce((a, b) => a + b, 0) / last7.length).toFixed(2); dv.paragraph(`最近7次测量的平均体重:**${avg} kg**`);这个数字比单次体重稳定得多,适合用来判断一段时间的真实走向。同理可以算血压的7日平均,能看出一段时间内的血压水平,而不是被某一天没睡好的数据吓到。
4.3 症状归因:双链是数据之间的暗线
健康管理除了记录数字,还要记录症状和事件之间的关系。这里我用了一个非常简单的双链逻辑:在某次头痛记录的正文里,链到当天日志、前一天的睡眠记录、最近一次喝酒的饮食事件,然后把这些链接放在疼痛说明的下面。
等记录积累到几十条,反向链接面板里就会自然浮现规律:头痛那天的睡眠普遍少于6小时,或者每次饮酒后的第二天精力评分都偏低。这个发现过程很奇妙,像在给自己写一份身体使用说明书。靠双链串起来的数据,不是Dataview那些数值字段能替代的。
4.4 周回顾自动生成:给自己一份不费力的报告
每周日我会新建一篇周回顾笔记,用Templater生成日期,然后手动贴入四段Dataview查询:本周体重表、本周运动记录、本周睡眠均值、本周症状记录。最后在备注里写下三条观察。这样一个小时就能完成一次周粒度复盘,不需要自己打开几十篇笔记逐个算。
5. 日常维护与问题排查:记录习惯崩了怎么办
5.1 录入数据了但查询查不到
这是Dataview新手遇到最多的问题,90%的情况出在字段上:前端写了体重:58kg,但YAML区写的是体重_kg: 58,查询里用的又是weight_kg,三个地方三种写法,当然查不到。
解决思路是彻底统一。我把frontmatter字段名当成全局命名规范来管理,手动在01-模板/字段规范.md里维护了一张表:
| 含义 | 统一字段名 | 示例值 |
|---|---|---|
| 日期 | date | 2025-06-01 |
| 体重 | weight_kg | 58.5 |
| 体脂率 | body_fat_percent | 22.3 |
| 腰围 | waist_cm | 74 |
| 睡眠时长 | sleep_hours | 7.5 |
| 情绪评分 | mood_score | 8 |
每张模板都用这张表里的字段名,查询代码也照这张表写。出现查不到的问题时,先怀疑字段名。
5.2 Dataview的常见坑:大小写、路径缺引号、空值
还有一个高频问题是路径或标签大小写不一致。Obsidian的文件夹路径是大小写敏感的,20-测量和20-测量虽然看起来一样,但差别一个字母就会查询失败。路径里如果带空格,必须写完整路径,包在引号里。
空值是另一个隐藏问题。模板新建后字段值是空的,Dataview会把这些空字段笔记也算进结果集,导致表格里出现一大片未定义值。所以每个查询都得加WHERE xxx != null过滤。
5.3 多设备同步后冲突副本
健康管理库最大的使用场景是手机随时记录和电脑周末复盘。如果开了多设备同步,几乎不可避免会遇到 “conflicted” 冲突文件。解决方法是:同步软件弹警告后,别急着删任何一方,先在电脑端打开两个文件对比,把内容合并进主文件,再删掉冲突副本。
Dataview查询如果遇到冲突文件,可能导致同一日期两条记录、表格里出现重复数据。养成周末做一次维护的习惯,把同步工具里有冲突标记的旧文件统一处理掉。
5.4 记录习惯崩了怎么办
做健康管理最大的敌人不是技术,是坚持。我用过一个极简心法:设置一个极低的上限,每天只强制填五个指标——睡眠时长、运动时长、体重、情绪评分、症状有无。其他字段都是可选项。状态不好就只填这五行,状态好再补充细节。
断档也不要紧。补记日期填回实际日期,不要为了“让记录看起来连续”把昨天和今天的数据全塞进今天的页面里。记录的意义在于还原真实,不在于完美。
6. 从系统到生活:我踩过的坑和最终心得
6.1 简化是系统能活下来的根基
最初我设计过十一个模板、二十多个标签、四套Dataviewjs图表,结果用了不到两周就崩溃了——录入一个运动记录要打开模板、填八个字段、贴三个标签,太累了。
后来我把复杂度砍掉了三分之二。每个笔记只保留最核心的四五个字段,图表全部撤掉,只看表格和平均值。别看系统简单了,反而连续用了半年多。
6.2 自动化是一把双刃剑
Templater能省去每天输日期的时间,但自动化也容易制造幻觉:只要模板自动填充了字段,就感觉自己已经完成了记录。实际上数据不录入,一切系统能力都不存在。所以我给模板里所有需要手动填写的字段都留着空行,不在模板里写示例数字,防止自己糊弄自己。
6.3 健康数据是长期资产,不是打卡任务
这套系统跑下来之后,最大的收获不是那些曲线和表格,而是当我再次去医院复诊时,能直接给医生看过去三个月的血压波动分布、症状出现的频率、用药后指标变化,而不是只能靠记忆回答“大概还好”。
每次体检前,我也会花半小时把过去一年的回顾笔记翻一遍,看看有没有需要重点关注的异常趋势,再决定要不要额外检查。这个工作以前根本做不了,因为数据都是零散的。
回头想,用Obsidian做个人健康管理,本质上不是“更高效地记笔记”,而是给自己建立了一个可以随时检索的个人健康档案库。我最后想分享的实用建议是:从你当前最在意的那一个指标开始,不要贪多,跑通一个最小闭环之后,再慢慢把其他模块加进来。我最早只记录体重和睡眠,跑了整整一个月,确认自己能坚持,才逐步加入血压、饮食和运动日志。先让系统活下来,再让它变完整。