@xdev-asia/xdev-knowledge-mcp 1.0.56 → 1.0.57

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (22) hide show
  1. package/content/series/architecture/omop-cdm-5-4-cho-nguoi-moi-bat-dau/chapters/01-phan-1-tong-quan-nen-tang/lessons/bai-1-omop-cdm-la-gi-tai-sao-can-chuan-hoa-du-lieu-y-te.md +339 -0
  2. package/content/series/architecture/omop-cdm-5-4-cho-nguoi-moi-bat-dau/chapters/01-phan-1-tong-quan-nen-tang/lessons/bai-2-kien-truc-tong-the-omop-cdm-5-4-nhom-bang-nguyen-ly-thiet-ke.md +440 -0
  3. package/content/series/architecture/omop-cdm-5-4-cho-nguoi-moi-bat-dau/chapters/01-phan-1-tong-quan-nen-tang/lessons/bai-3-hieu-concept-trai-tim-cua-omop-cdm.md +441 -0
  4. package/content/series/architecture/omop-cdm-5-4-cho-nguoi-moi-bat-dau/chapters/02-phan-2-person-visit-nen-tang/lessons/bai-4-bang-person-quan-ly-danh-tinh-benh-nhan.md +323 -0
  5. package/content/series/architecture/omop-cdm-5-4-cho-nguoi-moi-bat-dau/chapters/02-phan-2-person-visit-nen-tang/lessons/bai-5-observation-period-khoang-thoi-gian-theo-doi-benh-nhan.md +308 -0
  6. package/content/series/architecture/omop-cdm-5-4-cho-nguoi-moi-bat-dau/chapters/02-phan-2-person-visit-nen-tang/lessons/bai-6-visit-occurrence-visit-detail-luot-kham-chi-tiet.md +353 -0
  7. package/content/series/architecture/omop-cdm-5-4-cho-nguoi-moi-bat-dau/chapters/03-phan-3-su-kien-lam-sang-chinh/lessons/bai-10-measurement-xet-nghiem-do-luong.md +409 -0
  8. package/content/series/architecture/omop-cdm-5-4-cho-nguoi-moi-bat-dau/chapters/03-phan-3-su-kien-lam-sang-chinh/lessons/bai-7-condition-occurrence-chan-doan-benh-ly.md +285 -0
  9. package/content/series/architecture/omop-cdm-5-4-cho-nguoi-moi-bat-dau/chapters/03-phan-3-su-kien-lam-sang-chinh/lessons/bai-8-drug-exposure-thuoc-dieu-tri.md +354 -0
  10. package/content/series/architecture/omop-cdm-5-4-cho-nguoi-moi-bat-dau/chapters/03-phan-3-su-kien-lam-sang-chinh/lessons/bai-9-procedure-occurrence-thu-thuat-phau-thuat.md +291 -0
  11. package/content/series/architecture/omop-cdm-5-4-cho-nguoi-moi-bat-dau/chapters/04-phan-4-bang-lam-sang-mo-rong/lessons/bai-11-observation-su-kien-lam-sang-tong-hop.md +289 -0
  12. package/content/series/architecture/omop-cdm-5-4-cho-nguoi-moi-bat-dau/chapters/04-phan-4-bang-lam-sang-mo-rong/lessons/bai-12-device-exposure-specimen-note.md +313 -0
  13. package/content/series/architecture/omop-cdm-5-4-cho-nguoi-moi-bat-dau/chapters/04-phan-4-bang-lam-sang-mo-rong/lessons/bai-13-death-episode-episode-event.md +346 -0
  14. package/content/series/architecture/omop-cdm-5-4-cho-nguoi-moi-bat-dau/chapters/05-phan-5-standardized-vocabularies/lessons/bai-14-concept-vocabulary-nen-tang-tu-dien-chuan.md +298 -0
  15. package/content/series/architecture/omop-cdm-5-4-cho-nguoi-moi-bat-dau/chapters/05-phan-5-standardized-vocabularies/lessons/bai-15-concept-relationship-concept-ancestor.md +336 -0
  16. package/content/series/architecture/omop-cdm-5-4-cho-nguoi-moi-bat-dau/chapters/05-phan-5-standardized-vocabularies/lessons/bai-16-drug-strength-cac-bang-vocabulary-con-lai.md +295 -0
  17. package/content/series/architecture/omop-cdm-5-4-cho-nguoi-moi-bat-dau/chapters/06-phan-6-health-system-economics-derived/lessons/bai-17-location-care-site-provider.md +334 -0
  18. package/content/series/architecture/omop-cdm-5-4-cho-nguoi-moi-bat-dau/chapters/06-phan-6-health-system-economics-derived/lessons/bai-18-payer-plan-period-cost.md +343 -0
  19. package/content/series/architecture/omop-cdm-5-4-cho-nguoi-moi-bat-dau/chapters/06-phan-6-health-system-economics-derived/lessons/bai-19-condition-era-drug-era-dose-era.md +418 -0
  20. package/content/series/architecture/omop-cdm-5-4-cho-nguoi-moi-bat-dau/chapters/07-phan-7-metadata-cohort-tong-ket/lessons/bai-20-cdm-source-metadata-cohort-tong-ket.md +517 -0
  21. package/content/series/architecture/omop-cdm-5-4-cho-nguoi-moi-bat-dau/index.md +385 -0
  22. package/package.json +1 -1
@@ -0,0 +1,323 @@
1
+ ---
2
+ id: 019f1a00-a104-7b01-e001-omopcdm54004
3
+ title: "Bài 4: Bảng PERSON — Quản lý danh tính bệnh nhân"
4
+ slug: bai-4-bang-person-quan-ly-danh-tinh-benh-nhan
5
+ description: >-
6
+ Cấu trúc bảng PERSON, các trường bắt buộc (person_id,
7
+ gender_concept_id, year_of_birth), demographic data, liên kết
8
+ với LOCATION và PROVIDER, ETL conventions cho dữ liệu Việt Nam.
9
+ duration_minutes: 60
10
+ is_free: true
11
+ video_url: null
12
+ sort_order: 4
13
+ section_title: "Phần 2: Person & Visit — Nền tảng dữ liệu"
14
+ course:
15
+ id: 019f1a00-a100-7b01-e001-omopcdm54001
16
+ title: "OMOP CDM 5.4 cho Người mới — Hiểu từ A đến Z"
17
+ slug: omop-cdm-5-4-cho-nguoi-moi-bat-dau
18
+ ---
19
+
20
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 340" style="max-width: 100%; height: auto; border-radius: 12px; margin-bottom: 1.5rem;">
21
+ <defs>
22
+ <linearGradient id="bg-omop04" x1="0%" y1="0%" x2="100%" y2="100%">
23
+ <stop offset="0%" style="stop-color:#0c1222"/>
24
+ <stop offset="100%" style="stop-color:#1e293b"/>
25
+ </linearGradient>
26
+ </defs>
27
+ <rect width="1200" height="340" rx="12" fill="url(#bg-omop04)"/>
28
+ <g>
29
+ <circle cx="659" cy="87" r="22" fill="#818cf8" opacity="0.12"/>
30
+ <circle cx="718" cy="106" r="29" fill="#818cf8" opacity="0.09"/>
31
+ <circle cx="777" cy="125" r="36" fill="#818cf8" opacity="0.06"/>
32
+ <circle cx="836" cy="144" r="13" fill="#818cf8" opacity="0.13"/>
33
+ <circle cx="895" cy="163" r="20" fill="#818cf8" opacity="0.1"/>
34
+ <line x1="600" y1="157" x2="1100" y2="237" stroke="#818cf8" stroke-width="0.5" opacity="0.1"/>
35
+ </g>
36
+ <rect x="60" y="50" width="4" height="60" rx="2" fill="#818cf8"/>
37
+ <rect x="80" y="50" width="121" height="28" rx="14" fill="#818cf8" opacity="0.15"/>
38
+ <text x="92" y="69" font-family="system-ui,-apple-system,sans-serif" font-size="13" font-weight="600" fill="#818cf8">🏗️ Kiến trúc — Bài 4</text>
39
+ <text x="60" y="140" font-family="system-ui,-apple-system,sans-serif" font-size="34" font-weight="700" fill="#f1f5f9">
40
+ <tspan x="60" dy="0">Bảng PERSON — Quản lý</tspan>
41
+ <tspan x="60" dy="42">danh tính bệnh nhân</tspan>
42
+ </text>
43
+ <text x="60" y="244" font-family="system-ui,-apple-system,sans-serif" font-size="15" fill="#94a3b8" opacity="0.8">OMOP CDM 5.4 cho Người mới — Hiểu từ A đến Z</text>
44
+ <text x="60" y="268" font-family="system-ui,-apple-system,sans-serif" font-size="13" fill="#64748b" opacity="0.6">Phần 2: Person &amp; Visit — Nền tảng dữ liệu</text>
45
+ <text x="1140" y="320" font-family="system-ui,-apple-system,sans-serif" font-size="12" fill="#475569" text-anchor="end" opacity="0.4">xdev.asia</text>
46
+ </svg>
47
+
48
+ ![PERSON — trung tâm của OMOP CDM, kết nối tất cả bảng lâm sàng](/storage/uploads/2026/04/omop-cdm-bai4-person-centric.png)
49
+
50
+ ## Giới thiệu
51
+
52
+ **PERSON** là bảng trung tâm của toàn bộ OMOP CDM — mọi bảng clinical đều tham chiếu đến PERSON qua `person_id`. Đây là nơi lưu trữ thông tin nhân khẩu học (demographics) của bệnh nhân.
53
+
54
+ Mỗi dòng trong PERSON = **một bệnh nhân duy nhất** (unique person).
55
+
56
+ ---
57
+
58
+ ## 1. Cấu trúc bảng PERSON
59
+
60
+ ### 1.1. Danh sách cột đầy đủ
61
+
62
+ | Cột | Kiểu | Bắt buộc | Mô tả |
63
+ |-----|------|----------|-------|
64
+ | `person_id` | INTEGER | ✅ PK | ID duy nhất cho mỗi bệnh nhân |
65
+ | `gender_concept_id` | INTEGER | ✅ | Giới tính (Standard Concept) |
66
+ | `year_of_birth` | INTEGER | ✅ | Năm sinh |
67
+ | `month_of_birth` | INTEGER | | Tháng sinh |
68
+ | `day_of_birth` | INTEGER | | Ngày sinh |
69
+ | `birth_datetime` | DATETIME | | Ngày giờ sinh đầy đủ |
70
+ | `race_concept_id` | INTEGER | ✅ | Chủng tộc (Standard Concept) |
71
+ | `ethnicity_concept_id` | INTEGER | ✅ | Dân tộc (Standard Concept) |
72
+ | `location_id` | INTEGER | FK | Địa chỉ (tham chiếu LOCATION) |
73
+ | `provider_id` | INTEGER | FK | Bác sĩ chính (tham chiếu PROVIDER) |
74
+ | `care_site_id` | INTEGER | FK | Cơ sở y tế (tham chiếu CARE_SITE) |
75
+ | `person_source_value` | VARCHAR(50) | | Mã bệnh nhân gốc từ HIS |
76
+ | `gender_source_value` | VARCHAR(50) | | Giới tính gốc (VD: "Nu", "F") |
77
+ | `gender_source_concept_id` | INTEGER | | Concept ID giới tính gốc |
78
+ | `race_source_value` | VARCHAR(50) | | Chủng tộc gốc |
79
+ | `race_source_concept_id` | INTEGER | | Concept ID chủng tộc gốc |
80
+ | `ethnicity_source_value` | VARCHAR(50) | | Dân tộc gốc |
81
+ | `ethnicity_source_concept_id` | INTEGER | | Concept ID dân tộc gốc |
82
+
83
+ ### 1.2. Entity-Relationship
84
+
85
+ ```
86
+ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
87
+ │ LOCATION │←──────│ PERSON │──────→│ PROVIDER │
88
+ │ location_id │ │ person_id │ │ provider_id │
89
+ │ address_1 │ │ gender_* │ │ provider_name│
90
+ │ city │ │ birth_* │ │ specialty_* │
91
+ │ state │ │ race_* │ └──────────────┘
92
+ │ zip │ │ ethnicity_* │ ↑
93
+ │ country_* │ │ location_id │ │
94
+ └──────────────┘ │ provider_id │ ┌──────┴───────┐
95
+ │ care_site_id│──────→│ CARE_SITE │
96
+ └──────┬───────┘ │ care_site_id │
97
+ │ │ care_site_name│
98
+ ┌───────────┼───────────┐ └──────────────┘
99
+ ↓ ↓ ↓
100
+ VISIT_OCC. CONDITION DRUG_EXPOSURE
101
+ OBSERVATION MEASUREMENT ... (tất cả clinical)
102
+ ```
103
+
104
+ ---
105
+
106
+ ## 2. Các trường quan trọng chi tiết
107
+
108
+ ### 2.1. person_id
109
+
110
+ - **Kiểu**: INTEGER, Primary Key
111
+ - **Quy tắc**: Duy nhất, không thay đổi, không có ý nghĩa lâm sàng
112
+ - **Không phải** mã bệnh nhân gốc (mã BN gốc lưu ở `person_source_value`)
113
+
114
+ ```sql
115
+ -- ĐÚNG: person_id là số tự tăng hoặc hash
116
+ person_id = 100001
117
+ person_source_value = 'BN-2024-00123' -- Mã gốc từ HIS
118
+
119
+ -- SAI: Không dùng mã gốc làm person_id
120
+ -- person_id = 'BN-2024-00123' ← SAI (phải là INTEGER)
121
+ ```
122
+
123
+ ### 2.2. gender_concept_id
124
+
125
+ | Concept ID | Concept Name | Mô tả |
126
+ |-----------|--------------|-------|
127
+ | 8507 | Male | Nam |
128
+ | 8532 | Female | Nữ |
129
+ | 8551 | UNKNOWN | Không rõ |
130
+ | 8521 | OTHER | Khác |
131
+
132
+ ```sql
133
+ -- Ví dụ ETL cho dữ liệu Việt Nam
134
+ CASE
135
+ WHEN gioi_tinh IN ('Nam', 'M', '1') THEN 8507 -- Male
136
+ WHEN gioi_tinh IN ('Nữ', 'Nu', 'F', '2') THEN 8532 -- Female
137
+ ELSE 8551 -- UNKNOWN
138
+ END AS gender_concept_id,
139
+ gioi_tinh AS gender_source_value
140
+ ```
141
+
142
+ ### 2.3. year_of_birth, month_of_birth, day_of_birth
143
+
144
+ - `year_of_birth`: **Bắt buộc** — nếu không có, không nạp bệnh nhân
145
+ - `month_of_birth`, `day_of_birth`: Tùy chọn — đặt NULL nếu không có
146
+ - `birth_datetime`: Tùy chọn — hữu ích cho nhi khoa (tính tuổi chính xác)
147
+
148
+ ```sql
149
+ -- Ví dụ: BN sinh ngày 15/03/1980
150
+ year_of_birth = 1980
151
+ month_of_birth = 3
152
+ day_of_birth = 15
153
+ birth_datetime = '1980-03-15 00:00:00'
154
+ ```
155
+
156
+ ### 2.4. race_concept_id và ethnicity_concept_id
157
+
158
+ Đây là 2 trường theo chuẩn US Census. Cho dữ liệu Việt Nam:
159
+
160
+ | Trường | Khuyến nghị cho VN |
161
+ |--------|-------------------|
162
+ | `race_concept_id` | 8515 (Asian) |
163
+ | `race_source_value` | "Kinh", "Tày", "Mường"... |
164
+ | `ethnicity_concept_id` | 0 (No matching concept) |
165
+ | `ethnicity_source_value` | Ghi dân tộc gốc nếu có |
166
+
167
+ > **Lưu ý:** `race` và `ethnicity` trong OMOP theo chuẩn Mỹ (OMB). Khi ETL dữ liệu VN, ta vẫn phải đặt giá trị (dùng 0 nếu không map được) nhưng giữ thông tin gốc ở `*_source_value`.
168
+
169
+ ---
170
+
171
+ ## 3. Ví dụ thực tế
172
+
173
+ ### 3.1. Bệnh nhân Việt Nam
174
+
175
+ ```sql
176
+ INSERT INTO person VALUES (
177
+ 100001, -- person_id
178
+ 8532, -- gender_concept_id (Female)
179
+ 1980, -- year_of_birth
180
+ 3, -- month_of_birth
181
+ 15, -- day_of_birth
182
+ '1980-03-15 00:00:00', -- birth_datetime
183
+ 8515, -- race_concept_id (Asian)
184
+ 0, -- ethnicity_concept_id (N/A)
185
+ 1001, -- location_id (→ LOCATION table)
186
+ 5001, -- provider_id (→ PROVIDER table)
187
+ 2001, -- care_site_id (→ CARE_SITE table)
188
+ 'BN-2024-00123', -- person_source_value
189
+ 'Nữ', -- gender_source_value
190
+ 0, -- gender_source_concept_id
191
+ 'Kinh', -- race_source_value
192
+ 0, -- race_source_concept_id
193
+ NULL, -- ethnicity_source_value
194
+ 0 -- ethnicity_source_concept_id
195
+ );
196
+ ```
197
+
198
+ ### 3.2. SQL truy vấn cơ bản
199
+
200
+ ```sql
201
+ -- Đếm bệnh nhân theo giới tính
202
+ SELECT
203
+ c.concept_name AS gender,
204
+ COUNT(*) AS patient_count
205
+ FROM person p
206
+ JOIN concept c ON p.gender_concept_id = c.concept_id
207
+ GROUP BY c.concept_name;
208
+
209
+ -- Phân bố tuổi
210
+ SELECT
211
+ EXTRACT(YEAR FROM CURRENT_DATE) - year_of_birth AS age,
212
+ COUNT(*) AS count
213
+ FROM person
214
+ GROUP BY 1
215
+ ORDER BY 1;
216
+
217
+ -- Tìm bệnh nhân có dữ liệu gốc
218
+ SELECT
219
+ person_id,
220
+ person_source_value AS ma_bn_goc,
221
+ gender_source_value AS gioi_tinh_goc,
222
+ race_source_value AS dan_toc
223
+ FROM person
224
+ WHERE person_source_value IS NOT NULL
225
+ LIMIT 10;
226
+ ```
227
+
228
+ ---
229
+
230
+ ## 4. ETL Conventions
231
+
232
+ ### 4.1. Quy tắc quan trọng
233
+
234
+ | Quy tắc | Chi tiết |
235
+ |---------|----------|
236
+ | **1 person = 1 record** | Không trùng lặp, cần deduplicate |
237
+ | **year_of_birth bắt buộc** | Bỏ qua BN nếu không có năm sinh |
238
+ | **gender_concept_id bắt buộc** | Đặt 8551 (UNKNOWN) nếu không rõ |
239
+ | **person_id không mang ý nghĩa** | Đừng dùng mã BN gốc hoặc CMND/CCCD |
240
+ | **Không lưu PII trực tiếp** | Không có cột tên, CMND, sdt trong PERSON |
241
+
242
+ ### 4.2. De-identification (Khử danh)
243
+
244
+ OMOP CDM **không có cột tên, số CMND/CCCD, số điện thoại**. Đây là thiết kế có chủ đích:
245
+
246
+ ```
247
+ HIS gốc (có PII): OMOP CDM (de-identified):
248
+ ┌─────────────────────────┐ ┌──────────────────────────┐
249
+ │ ma_bn: BN-2024-00123 │ → │ person_id: 100001 │
250
+ │ ho_ten: Nguyễn Thị Lan │ → │ (không có cột tên!) │
251
+ │ cmnd: 079123456789 │ → │ (không có cột CMND!) │
252
+ │ sdt: 0901234567 │ → │ (không có cột SĐT!) │
253
+ │ ngay_sinh: 15/03/1980 │ → │ year_of_birth: 1980 │
254
+ │ gioi_tinh: Nữ │ → │ gender_concept_id: 8532 │
255
+ └─────────────────────────┘ └──────────────────────────┘
256
+ ```
257
+
258
+ > **Lưu ý:** `person_source_value` có thể chứa mã BN gốc (để truy vết). Tùy tổ chức có thể hash hoặc mã hóa giá trị này.
259
+
260
+ ### 4.3. Xử lý trùng lặp
261
+
262
+ Khi bệnh nhân có ≥2 mã ở nhiều hệ thống:
263
+
264
+ ```
265
+ HIS BV Chợ Rẫy: BN-CR-001 ┐
266
+ HIS BV Bạch Mai: BN-BM-555 ├──→ person_id = 100001
267
+ BHXH: DN-7900123456789 ┘ (1 person duy nhất)
268
+ ```
269
+
270
+ ETL cần thực hiện **Patient Matching** (khớp bệnh nhân) trước khi nạp vào PERSON.
271
+
272
+ ---
273
+
274
+ ## 5. Mối quan hệ với các bảng khác
275
+
276
+ ```sql
277
+ -- Tất cả dữ liệu lâm sàng của 1 bệnh nhân
278
+ SELECT 'Visits' AS data_type, COUNT(*) AS count
279
+ FROM visit_occurrence WHERE person_id = 100001
280
+ UNION ALL
281
+ SELECT 'Conditions', COUNT(*)
282
+ FROM condition_occurrence WHERE person_id = 100001
283
+ UNION ALL
284
+ SELECT 'Drugs', COUNT(*)
285
+ FROM drug_exposure WHERE person_id = 100001
286
+ UNION ALL
287
+ SELECT 'Measurements', COUNT(*)
288
+ FROM measurement WHERE person_id = 100001
289
+ UNION ALL
290
+ SELECT 'Observations', COUNT(*)
291
+ FROM observation WHERE person_id = 100001;
292
+ ```
293
+
294
+ ---
295
+
296
+ ## 6. Các lỗi ETL thường gặp
297
+
298
+ | Lỗi | Hậu quả | Cách khắc phục |
299
+ |-----|---------|---------------|
300
+ | Trùng person_id | Ghi đè dữ liệu | Kiểm tra unique constraint |
301
+ | year_of_birth = NULL | Vi phạm NOT NULL | Bỏ qua hoặc impute |
302
+ | gender_concept_id sai | Phân tích sai giới tính | Mapping chính xác |
303
+ | Để PII vào source_value | Vi phạm de-identification | Hash hoặc loại bỏ |
304
+ | Không deduplicate | 1 BN thành nhiều person | Patient matching trước ETL |
305
+
306
+ ---
307
+
308
+ ## Tổng kết
309
+
310
+ 1. **PERSON** là bảng trung tâm — mọi bảng clinical tham chiếu qua `person_id`
311
+ 2. **Trường bắt buộc**: person_id, gender_concept_id, year_of_birth, race_concept_id, ethnicity_concept_id
312
+ 3. **Không chứa PII** (tên, CMND, SĐT) — thiết kế de-identified
313
+ 4. **Liên kết**: LOCATION (địa chỉ), CARE_SITE (cơ sở), PROVIDER (bác sĩ chính)
314
+ 5. **ETL VN**: gender mapping, race = Asian (8515), ethnicity = 0
315
+
316
+ **Bài tiếp theo:** OBSERVATION_PERIOD — tại sao cần biết "khoảng thời gian theo dõi" và cách nó ảnh hưởng đến mọi phân tích.
317
+
318
+ ---
319
+
320
+ ## Tài liệu tham khảo
321
+
322
+ - [OMOP CDM 5.4 — PERSON](https://ohdsi.github.io/CommonDataModel/cdm54.html#PERSON)
323
+ - [The Book of OHDSI — Chapter 4.1](https://ohdsi.github.io/TheBookOfOhdsi/CommonDataModel.html)
@@ -0,0 +1,308 @@
1
+ ---
2
+ id: 019f1a00-a105-7b01-e001-omopcdm54005
3
+ title: "Bài 5: OBSERVATION_PERIOD — Khoảng thời gian theo dõi bệnh nhân"
4
+ slug: bai-5-observation-period-khoang-thoi-gian-theo-doi-benh-nhan
5
+ description: >-
6
+ Ý nghĩa của OBSERVATION_PERIOD, tại sao đây là bảng bắt buộc,
7
+ cách xác định start/end date từ dữ liệu nguồn, ảnh hưởng đến
8
+ tính toán incidence/prevalence, và các quy ước ETL.
9
+ duration_minutes: 45
10
+ is_free: true
11
+ video_url: null
12
+ sort_order: 5
13
+ section_title: "Phần 2: Person & Visit — Nền tảng dữ liệu"
14
+ course:
15
+ id: 019f1a00-a100-7b01-e001-omopcdm54001
16
+ title: "OMOP CDM 5.4 cho Người mới — Hiểu từ A đến Z"
17
+ slug: omop-cdm-5-4-cho-nguoi-moi-bat-dau
18
+ ---
19
+
20
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 340" style="max-width: 100%; height: auto; border-radius: 12px; margin-bottom: 1.5rem;">
21
+ <defs>
22
+ <linearGradient id="bg-omop05" x1="0%" y1="0%" x2="100%" y2="100%">
23
+ <stop offset="0%" style="stop-color:#0c1222"/>
24
+ <stop offset="100%" style="stop-color:#1e293b"/>
25
+ </linearGradient>
26
+ </defs>
27
+ <rect width="1200" height="340" rx="12" fill="url(#bg-omop05)"/>
28
+ <g>
29
+ <circle cx="659" cy="87" r="22" fill="#818cf8" opacity="0.12"/>
30
+ <circle cx="718" cy="106" r="29" fill="#818cf8" opacity="0.09"/>
31
+ <circle cx="777" cy="125" r="36" fill="#818cf8" opacity="0.06"/>
32
+ <circle cx="836" cy="144" r="13" fill="#818cf8" opacity="0.13"/>
33
+ <circle cx="895" cy="163" r="20" fill="#818cf8" opacity="0.1"/>
34
+ <line x1="600" y1="157" x2="1100" y2="237" stroke="#818cf8" stroke-width="0.5" opacity="0.1"/>
35
+ </g>
36
+ <rect x="60" y="50" width="4" height="60" rx="2" fill="#818cf8"/>
37
+ <rect x="80" y="50" width="121" height="28" rx="14" fill="#818cf8" opacity="0.15"/>
38
+ <text x="92" y="69" font-family="system-ui,-apple-system,sans-serif" font-size="13" font-weight="600" fill="#818cf8">🏗️ Kiến trúc — Bài 5</text>
39
+ <text x="60" y="140" font-family="system-ui,-apple-system,sans-serif" font-size="34" font-weight="700" fill="#f1f5f9">
40
+ <tspan x="60" dy="0">OBSERVATION_PERIOD — Khoảng</tspan>
41
+ <tspan x="60" dy="42">thời gian theo dõi bệnh nhân</tspan>
42
+ </text>
43
+ <text x="60" y="244" font-family="system-ui,-apple-system,sans-serif" font-size="15" fill="#94a3b8" opacity="0.8">OMOP CDM 5.4 cho Người mới — Hiểu từ A đến Z</text>
44
+ <text x="60" y="268" font-family="system-ui,-apple-system,sans-serif" font-size="13" fill="#64748b" opacity="0.6">Phần 2: Person &amp; Visit — Nền tảng dữ liệu</text>
45
+ <text x="1140" y="320" font-family="system-ui,-apple-system,sans-serif" font-size="12" fill="#475569" text-anchor="end" opacity="0.4">xdev.asia</text>
46
+ </svg>
47
+
48
+ ## Giới thiệu
49
+
50
+ **OBSERVATION_PERIOD** là bảng mà nhiều người mới hay bỏ qua — nhưng nó cực kỳ quan trọng. Bảng này trả lời câu hỏi: **"Từ khi nào đến khi nào chúng ta có dữ liệu về bệnh nhân này?"**
51
+
52
+ Nếu bệnh nhân không có OBSERVATION_PERIOD, ta không thể phân biệt: "bệnh nhân không bị bệnh" hay "bệnh nhân bị bệnh nhưng không đến khám (nên không có dữ liệu)".
53
+
54
+ ---
55
+
56
+ ## 1. Tại sao cần OBSERVATION_PERIOD?
57
+
58
+ ### 1.1. Vấn đề "absence vs missing"
59
+
60
+ ```
61
+ Bệnh nhân Lan:
62
+ ├── 2020-01-10: Khám → chẩn đoán Tiểu đường
63
+ ├── 2020-06-15: Tái khám
64
+ ├── 2021-01-20: Tái khám
65
+ ├── (im lặng 2 năm)
66
+ └── 2023-03-10: Nhập viện → Suy tim
67
+
68
+ Câu hỏi: Từ 2021-01 đến 2023-03, Lan có khỏe mạnh
69
+ hay chuyển sang bệnh viện khác?
70
+ ```
71
+
72
+ **OBSERVATION_PERIOD** cho biết khoảng thời gian bệnh nhân "nằm trong tầm quan sát" của nguồn dữ liệu:
73
+
74
+ ```
75
+ Observation Period:
76
+ ┌──────────────────────────────────────────────────────────────┐
77
+ │ 2020-01-10 ════════════════════════ 2021-12-31 │
78
+ │ (Có BHYT tại BV này) │
79
+ └──────────────────────────────────────────────────────────────┘
80
+
81
+ ┌──────────────────────────────────────────────────────────────┐
82
+ │ 2023-01-01 ════════════════════════ 2024-06-30 │
83
+ │ (Quay lại BV, có BHYT mới) │
84
+ └──────────────────────────────────────────────────────────────┘
85
+
86
+ → Trong observation period: không có Condition = bệnh nhân KHÔNG bị
87
+ → Ngoài observation period: không có Condition = KHÔNG BIẾT
88
+ ```
89
+
90
+ ### 1.2. Ảnh hưởng đến phân tích
91
+
92
+ | Phân tích | Không có OP | Có OP |
93
+ |-----------|-------------|-------|
94
+ | **Incidence rate** | Sai (mẫu số không chính xác) | Đúng (biết person-time at risk) |
95
+ | **Prevalence** | Sai (đếm không đủ) | Đúng (biết tổng population) |
96
+ | **Survival analysis** | Không biết censoring time | Time-to-event chính xác |
97
+ | **Cohort entry** | Có thể chọn BN ngoài dữ liệu | Chỉ chọn BN trong OP |
98
+
99
+ ---
100
+
101
+ ## 2. Cấu trúc bảng
102
+
103
+ | Cột | Kiểu | Bắt buộc | Mô tả |
104
+ |-----|------|----------|-------|
105
+ | `observation_period_id` | INTEGER | ✅ PK | ID duy nhất |
106
+ | `person_id` | INTEGER | ✅ FK | Tham chiếu PERSON |
107
+ | `observation_period_start_date` | DATE | ✅ | Ngày bắt đầu có dữ liệu |
108
+ | `observation_period_end_date` | DATE | ✅ | Ngày kết thúc có dữ liệu |
109
+ | `period_type_concept_id` | INTEGER | ✅ | Nguồn gốc xác định OP |
110
+
111
+ ### 2.1. period_type_concept_id
112
+
113
+ | Concept ID | Concept Name | Mô tả |
114
+ |-----------|--------------|-------|
115
+ | 32817 | EHR | Xác định từ EHR records |
116
+ | 32810 | Claim | Xác định từ claims/BHYT |
117
+ | 44814724 | Period covering healthcare encounters | Từ encounters |
118
+ | 44814725 | Period inferred by algorithm | Thuật toán suy ra |
119
+
120
+ ---
121
+
122
+ ## 3. Cách xác định Observation Period
123
+
124
+ ### 3.1. Từ dữ liệu claims/bảo hiểm
125
+
126
+ ```
127
+ BHXH cấp thẻ BHYT:
128
+ ┌─────────────────────────────────────────┐
129
+ │ Mã thẻ: DN-123456 Hiệu lực: 01/2020 │
130
+ │ BV đăng ký: Chợ Rẫy Hết hạn: 12/2024 │
131
+ └─────────────────────────────────────────┘
132
+
133
+ → observation_period_start_date = 2020-01-01
134
+ → observation_period_end_date = 2024-12-31
135
+ → period_type_concept_id = 32810 (Claim)
136
+ ```
137
+
138
+ ### 3.2. Từ dữ liệu EHR
139
+
140
+ Khi không có thông tin bảo hiểm rõ ràng, tính từ **encounter/visit đầu tiên đến cuối cùng**:
141
+
142
+ ```sql
143
+ -- Tính OP từ visits
144
+ SELECT
145
+ person_id,
146
+ MIN(visit_start_date) AS observation_period_start_date,
147
+ MAX(COALESCE(visit_end_date, visit_start_date))
148
+ AS observation_period_end_date,
149
+ 32817 AS period_type_concept_id -- EHR
150
+ FROM visit_occurrence
151
+ GROUP BY person_id;
152
+ ```
153
+
154
+ ### 3.3. Một bệnh nhân có thể có nhiều Observation Periods
155
+
156
+ ```
157
+ Bệnh nhân person_id = 100001:
158
+
159
+ OP 1: ═══════════ (2018-01-01 → 2019-06-30)
160
+ Có BHYT tại BV A
161
+
162
+ Gap (6 tháng, không có dữ liệu)
163
+
164
+ OP 2: ═══════════════════ (2020-01-01 → 2024-12-31)
165
+ Có BHYT mới tại BV A
166
+
167
+ → 2 records trong OBSERVATION_PERIOD
168
+ ```
169
+
170
+ ```sql
171
+ INSERT INTO observation_period VALUES
172
+ (1, 100001, '2018-01-01', '2019-06-30', 32810),
173
+ (2, 100001, '2020-01-01', '2024-12-31', 32810);
174
+ ```
175
+
176
+ ---
177
+
178
+ ## 4. Quy tắc quan trọng
179
+
180
+ ### 4.1. Mọi clinical event phải nằm trong Observation Period
181
+
182
+ ```
183
+ OP: ════════════════════════════════════
184
+ 2020-01-01 2024-12-31
185
+
186
+ ✅ Visit 2020-03-15 (trong OP)
187
+ ✅ Condition 2022-06-10 (trong OP)
188
+ ❌ Drug Exposure 2019-05-10 (NGOÀI OP!) → Cảnh báo data quality
189
+ ```
190
+
191
+ **ACHILLES data quality checks**: kiểm tra xem có clinical events nào nằm ngoài OBSERVATION_PERIOD không.
192
+
193
+ ### 4.2. Observation Periods không được chồng lấp
194
+
195
+ Cho cùng 1 person_id, các OP phải **thứ tự thời gian, không overlap**:
196
+
197
+ ```
198
+ ✅ ĐÚng:
199
+ OP1: ═══════ OP2: ═══════════
200
+ 2018-01 2019-06 2020-01 2024-12
201
+
202
+ ❌ SAI (overlap):
203
+ OP1: ═══════════════
204
+ OP2: ═══════════════
205
+ ```
206
+
207
+ ### 4.3. Quy ước đặc biệt
208
+
209
+ | Tình huống | Xử lý |
210
+ |-----------|-------|
211
+ | BN chỉ đến 1 lần | start_date = end_date = ngày khám |
212
+ | BN tử vong | end_date = ngày tử vong |
213
+ | Gap < 32 ngày (Claim) | Thường gộp thành 1 OP |
214
+ | Nhiều nguồn overlap | Gộp thành OP lớn nhất |
215
+
216
+ ---
217
+
218
+ ## 5. Ứng dụng trong phân tích
219
+
220
+ ### 5.1. Tính Person-Time at Risk
221
+
222
+ ```sql
223
+ -- Tổng thời gian theo dõi (person-years)
224
+ SELECT
225
+ SUM(
226
+ observation_period_end_date - observation_period_start_date
227
+ ) / 365.25 AS total_person_years
228
+ FROM observation_period;
229
+
230
+ -- Person-time cho incidence rate
231
+ SELECT
232
+ p.gender_concept_id,
233
+ SUM(
234
+ op.observation_period_end_date - op.observation_period_start_date
235
+ ) / 365.25 AS person_years
236
+ FROM observation_period op
237
+ JOIN person p ON op.person_id = p.person_id
238
+ GROUP BY p.gender_concept_id;
239
+ ```
240
+
241
+ ### 5.2. Lọc bệnh nhân "đủ dữ liệu"
242
+
243
+ ```sql
244
+ -- Chỉ chọn BN có ≥ 1 năm follow-up
245
+ SELECT person_id
246
+ FROM observation_period
247
+ WHERE observation_period_end_date - observation_period_start_date >= 365
248
+ GROUP BY person_id;
249
+ ```
250
+
251
+ ### 5.3. Kiểm tra data quality
252
+
253
+ ```sql
254
+ -- Tìm events nằm ngoài observation period
255
+ SELECT
256
+ 'CONDITION' AS event_type,
257
+ co.person_id,
258
+ co.condition_start_date AS event_date
259
+ FROM condition_occurrence co
260
+ LEFT JOIN observation_period op
261
+ ON co.person_id = op.person_id
262
+ AND co.condition_start_date
263
+ BETWEEN op.observation_period_start_date
264
+ AND op.observation_period_end_date
265
+ WHERE op.observation_period_id IS NULL;
266
+ ```
267
+
268
+ ---
269
+
270
+ ## 6. Ví dụ hoàn chỉnh
271
+
272
+ ```sql
273
+ -- OBSERVATION_PERIOD cho bệnh viện VN
274
+ INSERT INTO observation_period (
275
+ observation_period_id,
276
+ person_id,
277
+ observation_period_start_date,
278
+ observation_period_end_date,
279
+ period_type_concept_id
280
+ ) VALUES
281
+ -- BN 100001: có BHYT từ 2020 đến 2024
282
+ (1, 100001, '2020-01-01', '2024-12-31', 32810),
283
+ -- BN 100002: đến khám 3 lần trong 2023
284
+ (2, 100002, '2023-02-15', '2023-11-20', 32817),
285
+ -- BN 100003: 2 giai đoạn khác nhau
286
+ (3, 100003, '2019-03-10', '2020-06-30', 32817),
287
+ (4, 100003, '2022-01-15', '2024-06-30', 32817);
288
+ ```
289
+
290
+ ---
291
+
292
+ ## Tổng kết
293
+
294
+ 1. **OBSERVATION_PERIOD** = khoảng thời gian bệnh nhân "có dữ liệu" trong hệ thống
295
+ 2. Phân biệt **"không bị bệnh"** vs **"không có dữ liệu"**
296
+ 3. **Bắt buộc** cho mọi person — cần ít nhất 1 OP per person
297
+ 4. **Không overlap** giữa các OP cùng person_id
298
+ 5. **Mọi clinical events** phải nằm trong OP
299
+ 6. **Ứng dụng chính**: tính person-time, incidence rate, prevalence, cohort definition
300
+
301
+ **Bài tiếp theo:** VISIT_OCCURRENCE & VISIT_DETAIL — cách OMOP CDM ghi nhận mỗi lần bệnh nhân tiếp xúc với hệ thống y tế.
302
+
303
+ ---
304
+
305
+ ## Tài liệu tham khảo
306
+
307
+ - [OMOP CDM 5.4 — OBSERVATION_PERIOD](https://ohdsi.github.io/CommonDataModel/cdm54.html#OBSERVATION_PERIOD)
308
+ - [The Book of OHDSI — Observation Periods](https://ohdsi.github.io/TheBookOfOhdsi/CommonDataModel.html)