Ejemplos / Sistema de hospital
Sistema de hospital
La base de datos de un hospital gira en torno a dos tablas de eventos. Una cita es una consulta externa con un médico, y un ingreso, una estancia en una planta. Las dos tablas apuntan al paciente. Las recetas se emiten por cita y remiten a un catálogo de medicamentos.
Abajo, ErdDocs dibuja este esquema a partir de su SQL, con todas las tablas y relaciones. En la pestaña «Diccionario de datos» tienes la versión imprimible, completa y gratis en esta página. El SQL está más abajo.
Pasa el cursor sobre una tabla para resaltar sus relaciones y haz clic para fijarlas.
Qué hace cada tabla
- patientsEl personal usa el número de historia clínica, mrn. El id sustituto queda interno.
- doctors / departmentsUna relación uno a muchos simple. La especialidad la tiene el médico, no el departamento.
- appointmentsLa consulta ambulatoria, con paciente, médico, hora y resultado.
- admissionsLa estancia en el hospital. Mientras dura, discharged_at queda en NULL.
- medications / prescriptionsLa receta depende de la cita, porque la consulta da el contexto clínico de la orden.
Decisiones de diseño que vale la pena copiar
- Citas e ingresos van en tablas separadas, no en una tabla «visitas» con una columna de tipo. Casi no comparten columnas. Si se fusionan, el esquema se llena de NULL cuyo significado depende del tipo.
- La receta referencia la cita, no al paciente y al médico por separado. La consulta sirve de contexto para la auditoría, y desde ella se llega al paciente y al médico.
- Un NULL en discharged_at significa «sigue ingresado». Es un hecho que se puede consultar. Una columna de estado aparte habría que mantenerla sincronizada a mano.
El SQL
Dialecto PostgreSQL. Este SQL ya está en la herramienta de arriba, y puedes copiarlo libremente a tu base de datos o a una migración.
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 'Número de historia clínica: el identificador que usa el personal';
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 'agendada -> atendida, o no se presentó / cancelada';
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 mientras el paciente sigue ingresado';
CREATE TABLE medications (
id bigserial PRIMARY KEY,
name varchar(120) NOT NULL,
form varchar(40) NOT NULL
);
COMMENT ON COLUMN medications.form IS 'tableta / inyección / jarabe …';
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
);Preguntas frecuentes
¿Dónde irían los análisis de laboratorio?
Hacen falta dos tablas. La tabla lab_orders referencia la cita, igual que las recetas. La tabla lab_results referencia lab_orders, uno a uno o uno a muchos si cada panel informa varias filas.
¿Basta una tabla de médicos para enfermería y personal?
Para un esquema de estudio, una tabla staff con una columna de rol sirve. Los sistemas reales separan al personal clínico porque turnos, colegiación y facturación son distintos. Empieza simple y separa cuando una consulta lo exija.