ข้ามไปที่เนื้อหา

ER Diagram - ระบบเภสัชกรรม (Pharmacy System)

📋 สารบัญ


ภาพรวม

ระบบเภสัชกรรมประกอบด้วย Entity หลัก 10 ตัว ที่มีความสัมพันธ์กันในการจัดการยาและการจ่ายยา

Core Entities

  1. Patient - ผู้ป่วย
  2. Visit - การมาพบแพทย์ (OPD/IPD)
  3. Prescription - ใบสั่งยา
  4. PrescriptionItem - รายการยาในใบสั่ง
  5. Medication - ข้อมูลยา (Master)
  6. Dispensing - การจ่ายยา
  7. DispensingItem - รายการยาที่จ่าย
  8. DrugInteraction - ปฏิกิริยาระหว่างยา
  9. MedicationTemplate - ชุดยาแพทย์
  10. MAR - Medication Administration Record (IPD)

Main ER Diagram

erDiagram
    PATIENT ||--o{ VISIT : "has"
    PATIENT ||--o{ ALLERGY : "has"

    VISIT ||--|| PRESCRIPTION : "generates"
    VISIT }o--|| DOCTOR : "treated by"
    VISIT }o--|| CLINIC : "at"

    PRESCRIPTION ||--|{ PRESCRIPTION_ITEM : "contains"
    PRESCRIPTION_ITEM }o--|| MEDICATION : "references"

    PRESCRIPTION ||--o| DISPENSING : "results in"
    DISPENSING ||--|{ DISPENSING_ITEM : "contains"
    DISPENSING_ITEM }o--|| MEDICATION : "references"
    DISPENSING }o--|| PHARMACIST : "dispensed by"

    MEDICATION ||--o{ DRUG_INTERACTION : "interacts with"
    MEDICATION ||--o{ INVENTORY : "has stock"

    DOCTOR ||--o{ MEDICATION_TEMPLATE : "creates"
    MEDICATION_TEMPLATE ||--|{ TEMPLATE_ITEM : "contains"
    TEMPLATE_ITEM }o--|| MEDICATION : "references"

    PRESCRIPTION_ITEM ||--o{ MAR : "tracked in"
    MAR }o--|| NURSE : "administered by"

Entity Descriptions

1. PATIENT (ผู้ป่วย)

Primary Key: hn (Hospital Number)

Field Type Description
hn VARCHAR(10) HN000123
title VARCHAR(10) mr, mrs, ms
firstName VARCHAR(100) ชื่อ
lastName VARCHAR(100) นามสกุล
dateOfBirth DATE วันเกิด
age INT อายุ (คำนวณ)
gender ENUM male, female, other
bloodGroup VARCHAR(5) O+, A+, B+, AB+
allergies JSON รายการแพ้ยา
chronicDiseases JSON โรคประจำตัว
insuranceType VARCHAR(20) uc, social, private

Relationships: - 1 Patient → N Visits - 1 Patient → N Allergies


2. VISIT (การมาพบแพทย์)

Primary Key: visitId (VN)

Field Type Description
visitId VARCHAR(20) VISIT-2024-001
hn VARCHAR(10) FK → Patient
visitType ENUM OPD, IPD
visitDate DATETIME วันที่มาพบ
clinicId VARCHAR(10) FK → Clinic
doctorId VARCHAR(10) FK → Doctor
chiefComplaint TEXT อาการสำคัญ
diagnosis JSON Array of
status ENUM active, completed, cancelled

For IPD: | Field | Type | Description | |-------|------|-------------| | an | VARCHAR(20) | Admission Number | | admitDate | DATETIME | วันเข้ารับการรักษา | | dischargeDate | DATETIME | วันจำหน่าย | | ward | VARCHAR(50) | หอผู้ป่วย | | bed | VARCHAR(20) | เตียง |

Relationships: - N Visits → 1 Patient - N Visits → 1 Doctor - N Visits → 1 Clinic - 1 Visit → 1 Prescription


3. PRESCRIPTION (ใบสั่งยา)

Primary Key: prescriptionId

Field Type Description
prescriptionId VARCHAR(20) RX2024123
visitId VARCHAR(20) FK → Visit
hn VARCHAR(10) FK → Patient
prescribedBy VARCHAR(10) FK → Doctor
prescribedAt DATETIME วันเวลาที่สั่ง
status ENUM ordered, dispensed, cancelled
type ENUM OPD, IPD
totalCost DECIMAL(10,2) ยอดรวม
copay DECIMAL(10,2) ค่าใช้จ่ายผู้ป่วย
insuranceCovered DECIMAL(10,2) ประกันจ่าย

Relationships: - 1 Prescription → 1 Visit - 1 Prescription → N PrescriptionItems - 1 Prescription → 0..1 Dispensing


4. PRESCRIPTION_ITEM (รายการยาในใบสั่ง)

Primary Key: itemId

Field Type Description
itemId VARCHAR(20) PRESC-ITEM-001
prescriptionId VARCHAR(20) FK → Prescription
drugCode VARCHAR(20) FK → Medication
dosage VARCHAR(50) 1-2 tab
frequency VARCHAR(20) tid, bid, qid
timing VARCHAR(20) ac, pc, hs
route VARCHAR(20) oral, IV, IM
quantity INT จำนวน
duration INT จำนวนวัน
instruction TEXT คำแนะนำ
unitPrice DECIMAL(10,2) ราคาต่อหน่วย
totalPrice DECIMAL(10,2) ราคารวม

For IPD: | Field | Type | Description | |-------|------|-------------| | orderType | ENUM | continue, stat, prn, one_day | | administrationTime | JSON | ["06:00", "18:00"] | | startDate | DATE | วันเริ่ม (continue) | | stopDate | DATE | วันหยุด (continue) | | prnCondition | TEXT | เงื่อนไข (PRN) | | urgency | ENUM | routine, urgent, critical (STAT) |

Relationships: - N PrescriptionItems → 1 Prescription - N PrescriptionItems → 1 Medication - 1 PrescriptionItem → N MAR (IPD only)


5. MEDICATION (ข้อมูลยา - Master)

Primary Key: drugCode

Field Type Description
drugCode VARCHAR(20) MED001
tmtCode VARCHAR(20) TMT Code
genericName VARCHAR(100) ชื่อสามัญ
tradeName VARCHAR(100) ชื่อการค้า
strength VARCHAR(20) ความแรง
unit VARCHAR(10) mg, ml
dosageForm VARCHAR(20) tablet, capsule, syrup
manufacturer VARCHAR(100) ผู้ผลิต
drugCategory VARCHAR(20) analgesic, antibiotic
costPrice DECIMAL(10,2) ต้นทุน
opdPrice DECIMAL(10,2) ราคา OPD
ipdPrice DECIMAL(10,2) ราคา IPD
indication TEXT ข้อบ่งใช้
contraindication TEXT ข้อห้าม
sideEffects TEXT ผลข้างเคียง
pregnancyCategory VARCHAR(1) A, B, C, D, X
lactationSafe BOOLEAN ปลอดภัยในหญิงให้นมบุตร
pediatricSafe BOOLEAN ปลอดภัยในเด็ก
maxDailyDose VARCHAR(50) ขนาดสูงสุดต่อวัน

Relationships: - 1 Medication → N PrescriptionItems - 1 Medication → N DispensingItems - 1 Medication → N DrugInteractions - 1 Medication → 1 Inventory


6. DISPENSING (การจ่ายยา)

Primary Key: dispensingId

Field Type Description
dispensingId VARCHAR(20) DISP-2024-001
prescriptionId VARCHAR(20) FK → Prescription
hn VARCHAR(10) FK → Patient
dispensedBy VARCHAR(10) FK → Pharmacist
dispensedAt DATETIME วันเวลาที่จ่าย
type ENUM OPD, IPD
status ENUM prepared, dispensed, returned
totalCost DECIMAL(10,2) ยอดรวม

For IPD: | Field | Type | Description | |-------|------|-------------| | ward | VARCHAR(50) | หอผู้ป่วย | | sentAt | DATETIME | เวลาส่งยา | | receivedBy | VARCHAR(10) | FK → Nurse (ผู้รับยา) | | receivedAt | DATETIME | เวลารับยา |

Relationships: - 1 Dispensing → 1 Prescription - 1 Dispensing → N DispensingItems - N Dispensing → 1 Pharmacist


7. DISPENSING_ITEM (รายการยาที่จ่าย)

Primary Key: itemId

Field Type Description
itemId VARCHAR(20) DISP-ITEM-001
dispensingId VARCHAR(20) FK → Dispensing
drugCode VARCHAR(20) FK → Medication
quantity INT จำนวนที่จ่าย
batchNumber VARCHAR(50) Batch/Lot number
expiryDate DATE วันหมดอายุ
unitPrice DECIMAL(10,2) ราคาต่อหน่วย
totalPrice DECIMAL(10,2) ราคารวม

Relationships: - N DispensingItems → 1 Dispensing - N DispensingItems → 1 Medication


8. DRUG_INTERACTION (ปฏิกิริยาระหว่างยา)

Primary Key: interactionId

Field Type Description
interactionId VARCHAR(20) INT001
drug1Code VARCHAR(20) FK → Medication
drug2Code VARCHAR(20) FK → Medication
severity ENUM major, moderate, minor
description TEXT คำอธิบาย
mechanism TEXT กลไก
effect TEXT ผลที่เกิด
management TEXT การจัดการ
references JSON แหล่งอ้างอิง

Relationships: - N DrugInteractions → 2 Medications


9. MEDICATION_TEMPLATE (ชุดยาแพทย์)

Primary Key: templateId

Field Type Description
templateId VARCHAR(20) TPL001
name VARCHAR(100) ชื่อชุดยา
type ENUM personal, shared
doctorId VARCHAR(10) FK → Doctor (personal only)
disease VARCHAR(100) โรค/อาการ
category VARCHAR(50) หมวดหมู่
guidelines VARCHAR(100) แนวทาง CPG
createdBy VARCHAR(10) FK → User
createdAt DATETIME วันที่สร้าง
approvedBy VARCHAR(10) ผู้อนุมัติ (shared only)

Relationships: - N Templates → 1 Doctor (personal) - 1 Template → N TemplateItems


10. MAR (Medication Administration Record)

Primary Key: marId

Field Type Description
marId VARCHAR(20) MAR-2024-001
prescriptionItemId VARCHAR(20) FK → PrescriptionItem
an VARCHAR(20) FK → Visit (IPD)
date DATE วันที่
scheduledTime TIME เวลาที่กำหนด
actualTime TIME เวลาที่ให้จริง
administeredBy VARCHAR(10) FK → Nurse
status ENUM given, missed, refused, held
remarks TEXT หมายเหตุ

Relationships: - N MAR → 1 PrescriptionItem - N MAR → 1 Nurse


Relationships

Core Relationships

1. Patient → Visit → Prescription

erDiagram
    PATIENT ||--o{ VISIT : "1:N"
    VISIT ||--|| PRESCRIPTION : "1:1"

    PATIENT {
        string hn PK
        string firstName
        string lastName
    }

    VISIT {
        string visitId PK
        string hn FK
        string visitType
        datetime visitDate
    }

    PRESCRIPTION {
        string prescriptionId PK
        string visitId FK
        string hn FK
        datetime prescribedAt
    }

Cardinality: - 1 Patient มี 0..N Visits - 1 Visit มี 0..1 Prescription - 1 Prescription เป็นของ 1 Patient


2. Prescription → Items → Medication

erDiagram
    PRESCRIPTION ||--|{ PRESCRIPTION_ITEM : "1:N"
    PRESCRIPTION_ITEM }o--|| MEDICATION : "N:1"

    PRESCRIPTION {
        string prescriptionId PK
        datetime prescribedAt
        string status
    }

    PRESCRIPTION_ITEM {
        string itemId PK
        string prescriptionId FK
        string drugCode FK
        string dosage
        int quantity
    }

    MEDICATION {
        string drugCode PK
        string genericName
        string tradeName
        decimal price
    }

Cardinality: - 1 Prescription มี 1..N PrescriptionItems - N PrescriptionItems อ้างถึง 1 Medication - 1 Medication ถูกใช้ใน N PrescriptionItems


3. Prescription → Dispensing → Items

erDiagram
    PRESCRIPTION ||--o| DISPENSING : "1:0..1"
    DISPENSING ||--|{ DISPENSING_ITEM : "1:N"
    DISPENSING_ITEM }o--|| MEDICATION : "N:1"

    PRESCRIPTION {
        string prescriptionId PK
        string status
    }

    DISPENSING {
        string dispensingId PK
        string prescriptionId FK
        datetime dispensedAt
        string dispensedBy FK
    }

    DISPENSING_ITEM {
        string itemId PK
        string dispensingId FK
        string drugCode FK
        int quantity
    }

    MEDICATION {
        string drugCode PK
        string tradeName
    }

Cardinality: - 1 Prescription มี 0..1 Dispensing - 1 Dispensing มี 1..N DispensingItems - N DispensingItems อ้างถึง 1 Medication


4. Drug Interactions (Self-referencing)

erDiagram
    MEDICATION ||--o{ DRUG_INTERACTION : "drug1"
    MEDICATION ||--o{ DRUG_INTERACTION : "drug2"

    MEDICATION {
        string drugCode PK
        string genericName
        string tradeName
    }

    DRUG_INTERACTION {
        string interactionId PK
        string drug1Code FK
        string drug2Code FK
        string severity
        text description
    }

Cardinality: - 1 Medication มี N DrugInteractions (เป็น drug1) - 1 Medication มี N DrugInteractions (เป็น drug2) - 1 DrugInteraction เชื่อม 2 Medications


5. IPD: PrescriptionItem → MAR

erDiagram
    PRESCRIPTION_ITEM ||--o{ MAR : "1:N"
    MAR }o--|| NURSE : "N:1"

    PRESCRIPTION_ITEM {
        string itemId PK
        string drugCode FK
        json administrationTime
        string orderType
    }

    MAR {
        string marId PK
        string prescriptionItemId FK
        date date
        time scheduledTime
        time actualTime
        string administeredBy FK
        string status
    }

    NURSE {
        string nurseId PK
        string name
    }

Cardinality: - 1 PrescriptionItem (IPD) มี N MAR records - N MAR records → 1 Nurse (ผู้ให้ยา)


Detail Diagrams

OPD Workflow Entities

erDiagram
    OPD_VISIT ||--|| OPD_PRESCRIPTION : has
    OPD_PRESCRIPTION ||--|{ PRESCRIPTION_ITEM : contains
    OPD_PRESCRIPTION ||--|| OPD_QUEUE : enters
    OPD_QUEUE ||--o| OPD_DISPENSING : results_in
    OPD_DISPENSING ||--|{ DISPENSING_ITEM : contains

    OPD_VISIT {
        string visitId PK
        string hn FK
        string clinicId FK
        datetime visitDate
    }

    OPD_PRESCRIPTION {
        string prescriptionId PK
        string visitId FK
        string status
    }

    OPD_QUEUE {
        string queueId PK
        string prescriptionId FK
        string status
        int queueNumber
    }

    OPD_DISPENSING {
        string dispensingId PK
        string prescriptionId FK
        datetime dispensedAt
    }

IPD Workflow Entities

erDiagram
    IPD_ADMISSION ||--|{ IPD_PRESCRIPTION : has
    IPD_PRESCRIPTION ||--|{ PRESCRIPTION_ITEM : contains
    PRESCRIPTION_ITEM ||--o{ MAR : tracked_in
    IPD_PRESCRIPTION ||--o{ IPD_DISPENSING : results_in
    IPD_DISPENSING }o--|| WARD : sent_to

    IPD_ADMISSION {
        string an PK
        string hn FK
        string ward
        string bed
        datetime admitDate
    }

    IPD_PRESCRIPTION {
        string prescriptionId PK
        string an FK
        string orderType
        datetime startDate
        datetime stopDate
    }

    MAR {
        string marId PK
        string prescriptionItemId FK
        datetime scheduledTime
        datetime actualTime
        string status
    }

    WARD {
        string wardId PK
        string wardName
        int capacity
    }

Template & Master Data

erDiagram
    DOCTOR ||--o{ MEDICATION_TEMPLATE : creates
    MEDICATION_TEMPLATE ||--|{ TEMPLATE_ITEM : contains
    TEMPLATE_ITEM }o--|| MEDICATION : references

    MEDICATION ||--o{ INVENTORY : has_stock
    MEDICATION ||--o{ DRUG_INTERACTION : interacts

    DOCTOR {
        string doctorId PK
        string name
        string specialty
    }

    MEDICATION_TEMPLATE {
        string templateId PK
        string doctorId FK
        string name
        string type
    }

    TEMPLATE_ITEM {
        string itemId PK
        string templateId FK
        string drugCode FK
        string dosage
    }

    MEDICATION {
        string drugCode PK
        string genericName
        decimal price
    }

    INVENTORY {
        string inventoryId PK
        string drugCode FK
        int stockQuantity
        int reorderLevel
    }

Index Recommendations

Primary Indexes

-- Already covered by PRIMARY KEY
PK_Patient(hn)
PK_Visit(visitId)
PK_Prescription(prescriptionId)
PK_PrescriptionItem(itemId)
PK_Medication(drugCode)
PK_Dispensing(dispensingId)

Foreign Key Indexes

IDX_Visit_HN(hn)
IDX_Visit_DoctorId(doctorId)
IDX_Prescription_VisitId(visitId)
IDX_PrescriptionItem_PrescriptionId(prescriptionId)
IDX_PrescriptionItem_DrugCode(drugCode)
IDX_Dispensing_PrescriptionId(prescriptionId)
IDX_MAR_PrescriptionItemId(prescriptionItemId)

Search Indexes

IDX_Medication_GenericName(genericName)
IDX_Medication_TradeName(tradeName)
IDX_Prescription_Status_Date(status, prescribedAt)
IDX_Visit_Date(visitDate)
IDX_DrugInteraction_Drugs(drug1Code, drug2Code)

Composite Indexes

IDX_Prescription_Patient_Date(hn, prescribedAt DESC)
IDX_Dispensing_Date_Status(dispensedAt, status)
IDX_MAR_Date_Status(date, status)

Data Integrity Constraints

Foreign Key Constraints

FK_Visit_Patient: Visit.hn  Patient.hn
FK_Visit_Doctor: Visit.doctorId  Doctor.doctorId
FK_Prescription_Visit: Prescription.visitId  Visit.visitId
FK_PrescriptionItem_Prescription: PrescriptionItem.prescriptionId  Prescription.prescriptionId
FK_PrescriptionItem_Medication: PrescriptionItem.drugCode  Medication.drugCode
FK_Dispensing_Prescription: Dispensing.prescriptionId  Prescription.prescriptionId
FK_DispensingItem_Medication: DispensingItem.drugCode  Medication.drugCode
FK_MAR_PrescriptionItem: MAR.prescriptionItemId  PrescriptionItem.itemId

Check Constraints

CHK_Prescription_Status: status IN ('ordered', 'dispensed', 'cancelled')
CHK_Severity: severity IN ('major', 'moderate', 'minor')
CHK_OrderType: orderType IN ('continue', 'stat', 'prn', 'one_day', 'discharge')
CHK_MAR_Status: status IN ('given', 'missed', 'refused', 'held', 'na')
CHK_Quantity: quantity > 0
CHK_Price: price >= 0

Business Rules

-- ใบสั่งยาต้องมีอย่างน้อย 1 รายการ
RULE: COUNT(PrescriptionItem WHERE prescriptionId = X) >= 1

-- การจ่ายยาต้องมีสถานะใบสั่งยาเป็น 'ordered'
RULE: Prescription.status = 'ordered' BEFORE Dispensing created

-- MAR ใช้เฉพาะ IPD
RULE: MAR.prescriptionItemId  PrescriptionItem WHERE Visit.visitType = 'IPD'

-- Drug Interaction ต้องไม่ซ้ำคู่ยา
RULE: UNIQUE(drug1Code, drug2Code) OR UNIQUE(drug2Code, drug1Code)

Sample Queries

1. ดึงประวัติการใช้ยาของผู้ป่วย

SELECT 
    p.prescriptionId,
    p.prescribedAt,
    pi.drugCode,
    m.tradeName,
    pi.dosage,
    pi.frequency,
    pi.quantity,
    d.dispensedAt
FROM Prescription p
INNER JOIN PrescriptionItem pi ON p.prescriptionId = pi.prescriptionId
INNER JOIN Medication m ON pi.drugCode = m.drugCode
LEFT JOIN Dispensing d ON p.prescriptionId = d.prescriptionId
WHERE p.hn = 'HN000123'
ORDER BY p.prescribedAt DESC
LIMIT 10;

2. ตรวจสอบ Drug Interaction

SELECT 
    di.severity,
    m1.tradeName AS drug1,
    m2.tradeName AS drug2,
    di.description,
    di.management
FROM PrescriptionItem pi1
INNER JOIN PrescriptionItem pi2 
    ON pi1.prescriptionId = pi2.prescriptionId 
    AND pi1.itemId < pi2.itemId
INNER JOIN DrugInteraction di 
    ON (di.drug1Code = pi1.drugCode AND di.drug2Code = pi2.drugCode)
    OR (di.drug1Code = pi2.drugCode AND di.drug2Code = pi1.drugCode)
INNER JOIN Medication m1 ON pi1.drugCode = m1.drugCode
INNER JOIN Medication m2 ON pi2.drugCode = m2.drugCode
WHERE pi1.prescriptionId = 'RX2024123';

3. MAR Summary สำหรับหอผู้ป่วย

SELECT 
    v.an,
    p.hn,
    p.patientName,
    pi.drugCode,
    m.tradeName,
    mar.scheduledTime,
    mar.actualTime,
    mar.status,
    n.nurseName
FROM MAR mar
INNER JOIN PrescriptionItem pi ON mar.prescriptionItemId = pi.itemId
INNER JOIN Prescription pr ON pi.prescriptionId = pr.prescriptionId
INNER JOIN Visit v ON pr.visitId = v.visitId
INNER JOIN Patient p ON v.hn = p.hn
INNER JOIN Medication m ON pi.drugCode = m.drugCode
LEFT JOIN Nurse n ON mar.administeredBy = n.nurseId
WHERE v.ward = 'Medical Ward'
  AND mar.date = CURDATE()
ORDER BY mar.scheduledTime;

4. คิวจ่ายยา OPD

SELECT 
    pr.prescriptionId,
    p.hn,
    p.firstName,
    p.lastName,
    pr.prescribedAt,
    pr.status,
    COUNT(pi.itemId) AS itemCount,
    SUM(pi.totalPrice) AS totalCost
FROM Prescription pr
INNER JOIN Patient p ON pr.hn = p.hn
INNER JOIN PrescriptionItem pi ON pr.prescriptionId = pi.prescriptionId
WHERE pr.type = 'OPD'
  AND pr.status IN ('ordered', 'ready_to_dispense')
GROUP BY pr.prescriptionId
ORDER BY pr.prescribedAt;

Summary Statistics

Entity Estimated Rows Growth Rate
Patient 50,000+ ~100/day
Visit 500,000+ ~500/day
Prescription 400,000+ ~400/day
PrescriptionItem 1,200,000+ ~1,200/day
Medication ~5,000 Stable
Dispensing 380,000+ ~380/day
DispensingItem 1,100,000+ ~1,100/day
DrugInteraction ~1,000 Stable
MedicationTemplate ~200 +5/month
MAR 50,000+ ~500/day (IPD only)

สร้างเมื่อ: 6 มกราคม 2026
Version: 1.0
เอกสารอ้างอิง: DATA_STRUCTURES.md