Desain Database Aplikasi Klinik: Tabel Inti, Relasi, dan Kesalahan yang Sering Terjadi
Panduan merancang database aplikasi klinik atau rekam medis sederhana: tabel pasien, kunjungan, diagnosis, resep, dan tagihan, pemakaian kode standar, audit trail, indeks, serta kesalahan desain yang sering terjadi.
Desain database adalah fondasi aplikasi. Kesalahan di tahap ini sulit diperbaiki setelah data ribuan pasien masuk. Artikel ini membahas pola yang umum dipakai untuk aplikasi klinik rawat jalan, dari tabel inti sampai hal-hal yang sering terlupakan seperti audit trail dan kode standar.
Pisahkan pasien dari kunjungan
Kesalahan paling mendasar adalah mencampur data pasien dengan data kunjungan dalam satu tabel. Satu pasien bisa datang berkali-kali, dan setiap kunjungan punya dokter, keluhan, diagnosis, dan tagihan sendiri.
| Tabel | Isi utama | Relasi |
|---|---|---|
| pasien | No. rekam medis, NIK, nama, tanggal lahir, jenis kelamin, alamat, kontak | – |
| kunjungan | Tanggal, poli, dokter, jenis penjamin (umum, BPJS, asuransi), status | Banyak kunjungan per pasien |
| pemeriksaan | Anamnesis, tanda vital, pemeriksaan fisik | Per kunjungan |
| diagnosis | Kode ICD-10, jenis (utama atau sekunder) | Banyak diagnosis per kunjungan |
| resep dan resep_detail | Obat, dosis, aturan pakai, jumlah | Per kunjungan |
| tindakan | Tindakan medis beserta tarifnya | Per kunjungan |
| tagihan dan pembayaran | Total, diskon, penjamin, metode bayar | Per kunjungan |
Data master seperti dokter, poli, obat, tarif, dan pengguna disimpan di tabel tersendiri dan dirujuk dengan kunci asing (foreign key).
Gunakan kode standar sejak awal
- Diagnosis memakai ICD-10, yang juga dipakai untuk klaim BPJS dan pelaporan.
- Pemeriksaan laboratorium sebaiknya bisa dipetakan ke kode LOINC.
- Obat dipetakan ke kode yang berlaku untuk integrasi nasional.
Menyimpan diagnosis sebagai teks bebas memang cepat di awal, tetapi menyulitkan laporan, klaim, dan integrasi ke SATUSEHAT. Pemetaan kode dibahas di artikel integrasi HL7, FHIR, dan SATUSEHAT. Simpan juga kolom untuk ID yang dikembalikan sistem luar, misalnya ID Encounter dari SATUSEHAT.
Contoh struktur tabel
Contoh sederhana dua tabel inti dalam SQL (PostgreSQL):
CREATE TABLE pasien (
id BIGSERIAL PRIMARY KEY,
no_rm VARCHAR(20) NOT NULL UNIQUE,
nik VARCHAR(16),
nama VARCHAR(150) NOT NULL,
tanggal_lahir DATE NOT NULL,
jenis_kelamin CHAR(1) NOT NULL,
dibuat_pada TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE TABLE kunjungan (
id BIGSERIAL PRIMARY KEY,
pasien_id BIGINT NOT NULL REFERENCES pasien(id),
poli_id INT NOT NULL REFERENCES poli(id),
dokter_id INT NOT NULL REFERENCES dokter(id),
penjamin VARCHAR(20) NOT NULL,
waktu_datang TIMESTAMPTZ NOT NULL,
satusehat_id VARCHAR(64),
dibatalkan_pada TIMESTAMPTZ
);
CREATE INDEX idx_kunjungan_waktu ON kunjungan (waktu_datang, poli_id);
Perhatikan NIK disimpan sebagai teks, tanggal lahir sebagai tanggal, nomor rekam medis dibuat unik, dan ada kolom untuk ID dari sistem luar serta penanda pembatalan.
Simpan harga saat transaksi
Tarif dan harga obat berubah. Bila tagihan hanya merujuk ke tabel tarif, tagihan lama akan ikut berubah saat tarif dinaikkan. Solusinya, salin harga ke tabel detail transaksi saat transaksi terjadi. Aturan yang sama berlaku untuk nama obat dan nama dokter bila laporan lama harus tetap menampilkan data sesuai kondisi saat itu.
Jangan menghapus data medis
Rekam medis tidak boleh hilang begitu saja. Gunakan soft delete (kolom penanda seperti dibatalkan_pada dan dibatalkan_oleh) untuk membatalkan data, bukan menghapus barisnya. Untuk koreksi catatan klinis, simpan riwayat perubahannya: siapa yang mengubah, kapan, dan nilai sebelumnya.
Audit trail
Buat tabel log akses dan perubahan yang mencatat pengguna, waktu, aksi (lihat, ubah, cetak, ekspor), dan data yang disentuh. Tabel ini tumbuh cepat, jadi rancang sejak awal: pisahkan dari tabel transaksi utama, beri indeks pada kolom waktu dan pengguna, dan tentukan kebijakan arsipnya. Alasannya dijelaskan di artikel keamanan data pasien dan UU PDP.
Indeks untuk pencarian yang sering dipakai
- Pencarian pasien berdasarkan nomor rekam medis, NIK, nomor BPJS, dan nama.
- Daftar kunjungan per tanggal dan per poli untuk layar antrean.
- Laporan berdasarkan rentang tanggal.
Buat indeks sesuai pola pencarian nyata, bukan di semua kolom. Indeks mempercepat pembacaan tetapi memperlambat penulisan dan menambah ukuran database. Perkirakan pertumbuhan data dan backup-nya dengan kalkulator storage dan backup.
Kesalahan yang sering terjadi
- Tanggal lahir disimpan sebagai umur. Umur berubah setiap tahun. Simpan tanggal lahir, hitung umur saat ditampilkan.
- NIK disimpan sebagai angka. Simpan sebagai teks, karena bisa diawali nol dan tidak dipakai untuk perhitungan.
- Tidak ada batasan unik pada nomor rekam medis, sehingga pasien ganda mudah terjadi.
- Zona waktu tidak konsisten antara server, database, dan aplikasi. Tetapkan satu standar sejak awal.
- Hasil lab disimpan sebagai satu teks panjang, sehingga nilai tidak bisa dibandingkan antarkunjungan atau dibuat grafik.
Pertanyaan yang sering diajukan
Database relasional atau NoSQL? Untuk data transaksi klinik yang sangat terstruktur dan saling berelasi, database relasional seperti PostgreSQL atau MySQL umumnya pilihan yang paling aman dan mudah dirawat.
Perlukah memakai struktur FHIR sebagai tabel database? Tidak harus. Banyak aplikasi menyimpan data dengan struktur yang sesuai kebutuhan internal, lalu memetakannya ke resource FHIR saat integrasi.