ER図のサンプル / 病院管理システム
病院管理システム
病院のデータベースは、二つの「出来事」のテーブルを中心に回ります。外来予約(医師との診察)と入院(病棟での滞在)です。どちらも患者を参照します。処方は外来予約ごとに書かれ、薬品マスタを参照します。
下では、このスキーマのすべてのテーブルとリレーションを ErdDocs が SQL から描いています。「テーブル定義書」タブには印刷用の一覧があり、このページでは全体を無料で見られます。SQL はページ下部にあります。
スキーマ
テーブルにカーソルを合わせるとリレーションが強調され、クリックで固定できます。
各テーブルの役割
- patientsmrn(カルテ番号)が業務で使う識別子で、サロゲートキーの id は内部用です。
- doctors / departments素直な一対多。専門は診療科ではなく医師が持ちます。
- appointments外来の出来事:患者・医師・日時・結果。
- admissions入院の出来事です。退院までは期間が開いたままで、入院中は discharged_at が NULL になります。
- medications / prescriptions処方は外来予約にぶら下がります。診察がその処方の臨床的な文脈だからです。
設計のポイント
- 外来予約と入院は、種別カラムを持つ一つの visits テーブルではなく、別テーブルにします。共通のカラムはほとんどなく、一つにまとめると種別ごとに意味の違う NULL が増えます。
- 処方は患者と医師を直接ではなく外来予約を参照します。診察が監査の文脈であり、患者と医師はそこからたどれます。
- discharged_at を NULL 許容にすると「入院中」が問い合わせ可能な事実になり、同期を保つべきステータス文字列が要りません。
SQL
PostgreSQL の方言です。上のツール(すでに入っています)や、ご自身のデータベース、マイグレーションに自由にコピーして使えます。
CREATE TABLE departments (
id bigserial PRIMARY KEY,
name varchar(80) NOT NULL UNIQUE
);
CREATE TABLE doctors (
id bigserial PRIMARY KEY,
department_id bigint NOT NULL REFERENCES departments(id),
full_name varchar(120) NOT NULL,
specialty varchar(80) NOT NULL
);
CREATE TABLE patients (
id bigserial PRIMARY KEY,
mrn varchar(20) NOT NULL UNIQUE,
full_name varchar(120) NOT NULL,
born_on date NOT NULL,
blood_type varchar(3)
);
COMMENT ON COLUMN patients.mrn IS '診察券番号(カルテ番号)。職員が実際に使う ID';
CREATE TABLE appointments (
id bigserial PRIMARY KEY,
patient_id bigint NOT NULL REFERENCES patients(id),
doctor_id bigint NOT NULL REFERENCES doctors(id),
at timestamptz NOT NULL,
status varchar(20) NOT NULL DEFAULT 'booked',
notes text
);
COMMENT ON COLUMN appointments.status IS '予約済 → 診察済、または無断キャンセル/キャンセル';
CREATE TABLE admissions (
id bigserial PRIMARY KEY,
patient_id bigint NOT NULL REFERENCES patients(id),
ward varchar(40) NOT NULL,
admitted_at timestamptz NOT NULL,
discharged_at timestamptz
);
COMMENT ON COLUMN admissions.discharged_at IS '入院中は NULL';
CREATE TABLE medications (
id bigserial PRIMARY KEY,
name varchar(120) NOT NULL,
form varchar(40) NOT NULL
);
COMMENT ON COLUMN medications.form IS '錠剤/注射/シロップ など';
CREATE TABLE prescriptions (
id bigserial PRIMARY KEY,
appointment_id bigint NOT NULL REFERENCES appointments(id),
medication_id bigint NOT NULL REFERENCES medications(id),
dosage varchar(60) NOT NULL,
days int NOT NULL
);よくある質問
検査と検査結果はどこに入れますか?
処方と同じく外来予約を参照する lab_orders テーブルと、lab_orders を参照する lab_results テーブルです。項目ごとに行を持つなら一対多になります。
医師テーブル一つで看護師や職員もまかなえますか?
課題のスキーマなら、role カラムを持つ staff テーブルで十分です。実際のシステムでは、シフト・資格・請求が違うので職種ごとに分けます。まず単純に作り、問い合わせが必要とした時点で分けましょう。