ErdDocs

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 テーブルで十分です。実際のシステムでは、シフト・資格・請求が違うので職種ごとに分けます。まず単純に作り、問い合わせが必要とした時点で分けましょう。

ほかのサンプル