iT邦幫忙

2026 iThome 鐵人賽

DAY 15
0
Software Development

三十天轉職成「醫療軟體工程師」系列 第 15 篇

Day14 - 醫療資料模型:一筆生命徵象紀錄由什麼組成?

  • 分享至 

  • xImage
  •  

前幾天我們討論,風險管理、UI/UX、錯誤處理。接下來要聊聊,軟體要顯示這些資訊,背後的資料要怎麼存?

如果是體溫紀錄 App,第一個想到的可能就是「姓名、體溫、時間」三個欄位。看起來應該就夠用了,但只要加上幫家人登錄、離線補傳或修改紀錄,這三個欄位很快就不夠。今天就沿用家庭生命徵象 App,把一筆紀錄拆開來看。

定義資料模型,就是先說清楚我們在記什麼

把資料模型理解成:先決定有哪些東西要記、各自代表什麼,以及彼此怎麼連起來,再決定資料庫和 API 要怎麼寫。

例如「一位家人可以有很多筆量測紀錄」,就是一個關係;「一筆紀錄可能被修改好幾次」,又是另一個關係。如果一開始沒分清楚,後面很容易拿同一個欄位硬塞不同意思,最後連自己都不知道 time 到底是哪個時間。

先不用急著選資料庫。我們可以先畫出這個教學 App 的關係:

flowchart LR
    P["量測對象"] -->|擁有多筆| O["量測紀錄:固定 ID"]
    O -->|保留各次內容| V["紀錄版本:項目、數值、單位、量測時間、狀態"]
    U["操作帳號"] -->|建立或修訂| V
    D["量測裝置:已知時關聯"] -->|提供量測來源| V
    V -->|記錄傳送結果| S["同步資訊:待同步、已同步、失敗"]

這是誰的數值?又是誰輸入的?

假設我幫爸爸量體溫,再用自己的帳號輸入 App。這時候至少有兩個角色:量測對象是爸爸,登錄者是我。如果系統只存一個 userId,到底指誰?光看名字猜不出來。

所以這個案例會分開保存 subjectId 和 recordedBy,前者指向家人資料,後者指向操作帳號。如果還需要知道誰實際執行量測,也要另外記,因為量的人不一定是輸入的人。

姓名則拿來顯示,不拿來當唯一識別。家人可能改名,也可能同名;「爸爸」更只是某位使用者對他的稱呼。至於這個帳號有沒有權限替他登錄,仍要由授權規則檢查,不能因為傳來一個 subjectId 就直接接受。

數值旁邊,還要帶著量測的背景

語意脈絡

Day 4 提過資料要有語意脈絡。若只紀錄 37.2,光看數字本身一定看不出是在量什麼,要一起知道量測項目和單位。如果是體溫,產品也可能需要記錄量測部位與方法,避免之後比較時,把不同條件下的結果混在一起。

若匯入資料需要換算單位,App 保留原始數值、原始單位及換算依據,才能回頭檢查。遇到缺值時,同樣要分清楚是沒量、量測失敗,還是資料沒有傳到。切記:不能為了讓數字欄位不空白,就全部補成 0,因為在某些數值, 0 代表死亡(沒有脈搏怎麼還會活著)。

來源

來源也要拆開看。「手動輸入」描述資料怎麼進 App;「耳溫計量測」描述數值怎麼來。即使是我手動輸入,原始數值仍可能來自一台裝置,兩者並不衝突。

裝置資料可以另外保存型號與識別資訊,紀錄再透過 deviceId 連回去。不過,同型號不代表同一台裝置;不知道是哪台時,也不要隨便補一台。模型要能表達「裝置不詳」,是否允許這種紀錄,則回到產品需求決定。

一筆紀錄,可能有三個不同的時間

假設爸爸早上八點量完體溫,我八點十分才輸入,但家裡網路斷了,中午十二點才同步成功。這筆紀錄的時間要存哪個?

這三個時間各自回答不同問題,所以我會分開記:

欄位 回答的問題 案例範例
measuredAt 什麼時候量的? 2026-09-28 08:00,UTC+8
recordedAt 什麼時候登錄的? 2026-09-28 08:10,UTC+8
syncedAt 這個版本什麼時候確認同步成功? 2026-09-28 12:00,UTC+8

如果畫體溫趨勢,我們要看的是量測時間。拿同步時間來排,早上的體溫就會跑到中午,看起來像剛量過。

時間也要帶著時區資訊,或在儲存時統一成 UTC,再依需求顯示。不過格式正確,不代表時鐘一定正確。如果時間來自使用者補填或裝置時鐘,必要時還要記下時間來源及是否存疑。只記得「早上」時,也不該默默補成精確的八點整。

輸錯可以改,但要留下更改的紀錄

再延續剛才的例子:我原本輸入 37.2 °C,後來核對才發現應該是 36.7 °C。如果直接蓋掉原本的值,之後有人問「為什麼早上看到的數字不一樣」,我們可能就答不出來了。

下面資料模型會保留同一個紀錄 ID,新增修訂版本,留下修改者、修改時間和原因:

資訊 第 1 版 第 2 版
紀錄 ID/量測對象 OBS-001/P-001 OBS-001/P-001
項目/數值/單位 體溫/37.2/°C 體溫/36.7/°C
量測時間 08:00,UTC+8 08:00,UTC+8
輸入方式/裝置 手動/DEV-001 手動/DEV-001
操作者/操作時間 U-002/08:10,UTC+8 U-002/12:30,UTC+8
操作原因 初次登錄 核對裝置讀值後,更正輸入錯誤
紀錄狀態/同步狀態 完成登錄/已同步 完成登錄/待同步

表內時間都在同一天。注意,修正的是輸入值,量測時間仍是八點;如果十二點半重新量了一次,那就應該新增量測紀錄,而不是修改早上的結果。

同樣地,第 1 版已同步,不代表第 2 版也已經送到伺服器。畫面和查詢都得分清楚目前看的版本;畫趨勢時,也不能把兩個版本當成兩次量測一起算。至於多人同時修改時怎麼處理衝突,還需要另外定義規則,光有版本欄位不會自動解決。

回頭看,前幾天提到的需求,其實都需要資料模型配合。畫面想顯示「幫誰記」,資料就要分清對象與操作者;想告訴使用者「還沒同步」,就要知道哪一版還沒送到;想讓人查修改紀錄,就得保留修訂內容。

今天先把 App 內部要保存的意思說清楚。明天再接著談:當這筆資料要交給另一套系統,怎麼用 FHIR、術語和編碼,讓對方也能理解我們記的是什麼。

小記

設計與規劃資料模型時,我們需要把需求仔細的考量清楚,在醫療軟體中,資料的新增/異動是需要被稽核的,所以在設計資料模型時,也需要將這些稽核所需要的欄位、資料表都一併設計清楚。另外,儲存數據時,需要多注意的是單位,單位不正確,那麼紀錄的數值就會意義不同。一筆資料所包含的語意脈絡也是非常重要的,醫護人員在觀看這些數值時,不會只有查看單一數值就下結論,一般來說都會參考多個數值來下診斷的。


上一篇
Day13 - 從需求到安全使用:風險、介面與邊界條件怎麼串起來?
下一篇
Day15 - 醫療資訊交換標準-FHIR(上)
系列文
三十天轉職成「醫療軟體工程師」 共 17 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言