數據庫模式隨時間跟踪患者統計資訊
我想創建一個數據庫,允許隨著時間的推移記錄患者閱讀數據點,例如:體重、身高、壓力等。
我找到了一個類似於本問答中討論的數據庫架構,看起來與我的需求相似。我想知道這樣的設計是否為大量使用者提供了良好的性能?
例如,如果我們計劃每年至少跟踪 20 次 10 000 個使用者的 10 個參數 - 大約是每年 2 000 000 行。
可用引擎——InnodDB、MyISAM。
DB healthstats TABLE user memberID (int*, auto increment, unsigned, primary key) name (varchar, 50) gender (char, 1) birthdate (date) TABLE reading readingID (int*, auto increment, unsigned, primary key) memberID (int*, FK: TABLE user) date (datetime) TABLE stat statID (int*, auto increment, unsigned, primary key) readingID (int*, FK: TABLE reading) type (varchar, 3)* value (decimal 4.1)*
readingID
需要嗎ZEROFILL
?birthdate
需要嗎DATETIME
?- 使用 InnoDB。
- 不要使用EAV!10 列統計數據沒什麼大不了的,您可以為每列使用適當的數據類型。
也就是說,只有 2 個表 - 一個用於使用者,一個用於讀數。
如果您繪製圖表,請使用日期作為 x 軸。我看到一個診所在 x 軸上均勻分佈讀數。這簡直太糟糕了。
因為
weight
您可以選擇FLOAT
或DECIMAL(4,1)
或SMALLINT UNSIGNED
(4/3/2 字節,對於磅或公斤來說足夠了——但在儲存的內容上要保持一致)對於 Gender,使用
CHAR
、doCHAR(1) CHARACTER SET ascii
和 allow 比通常的選擇更多(這些天!)。如果您想在一天內禁止兩組測量,請擺脫
readingID
並擁有PRIMARY KEY(memberID, date)
. 這將產生更有效地查找有關一個人的所有資訊的副作用。2M 行/年是“中等規模”;不是問題。通過擺脫
stat
,您將減少到 200K 行/年,整個數據集將更接近“微小”。數據庫可能是 8MB/年。(與使用 . 的 EAV 可能每年 100MB 相比stats
。)插入率將是 200K/年。MySQL 可以輕鬆處理 200K/天,因此伺服器會非常空閒。
根據我的建議,應該能夠處理甚至一百萬行而無需進一步調整。(使用 EAV,您會在此之前很久就苦苦掙扎。)
為什麼或為什麼不 EAV
當屬性有很多變化時,EAV 會大放異彩。你的應用程序有一組固定的屬性——每個人都有脈搏;
NULL
如果沒有執行該測試,最壞的情況可能會儲存。另一方面,如果您選擇儲存可以從血液樣本中獲得的數百個(?)讀數,……通常血液工作集中在少數可能的測試上。也就是說,數據非常稀疏。
對於血液檢查,我建議使用一列 JSON 文本。(取決於您使用的是最新的 MySQL 還是 MariaDB,可能有一個
JSON
數據類型,或者只是一個TEXT
數據類型;效果類似。)在此列中,您將僅列出您擁有資訊的讀數。同時,“正常”讀數(脈衝、溫度等)將有自己的列。您可能有一個“真實”列,上面寫著“有一些超出範圍的血檢讀數”作為調查它的線索。是的,在 JSON 裡面翻找時有麻煩。但我聲稱 EAV 更糟糕——就大小、速度和編碼而言。
在您的評論中,您提到添加 10-20 個新讀數。必要的
ALTER TABLE .. ADD COLUMN .. NULL, ADD COLUMN .. NULL;
將是一次性的滋擾。但我仍然更喜歡它而不是 EAV 或 JSON。還有一點需要注意:
INDEXes
並不總是有用的。當您有大部分缺失的值(列、EAV或JSON)時,搜尋它們的成本*可能很高。*如果您想向我們展示一些查詢,我們可以進一步討論。對於“SELECT * FROM Readings WHERE userID = 123”的簡單查詢來建構圖表,那麼最佳模式是一個帶有或不帶 JSON且不帶EAV 的單個 Readings 表。我給出了最優的
PRIMARY KEY
.