Normalización
Bases de Datos
Aviso Importante
Contenido
¿Qué es la Normalización?
Imagina una hoja de cálculo donde una celda contiene múltiples valores separados por barras — como almacenar varios números de artículo, descripciones y precios todos en una sola fila. Esa es una tabla no normalizada, y hace que actualizar, buscar y mantener los datos sea una pesadilla. La normalización es el proceso paso a paso de reorganizar esa tabla desordenada en un conjunto de tablas bien estructuradas que eliminan la redundancia y protegen la integridad de los datos.
El proceso sigue una serie de formas normales, cada una construida sobre la anterior. La Primera Forma Normal (1NF) asegura que cada celda contiene un solo valor atómico — sin grupos repetitivos. La Segunda Forma Normal (2NF) elimina las dependencias parciales, donde un atributo no clave depende de solo una parte de una clave compuesta. La Tercera Forma Normal (3NF) elimina las dependencias transitivas, donde un atributo no clave depende de otro atributo no clave en lugar de la clave primaria.
Piénsalo como organizar un archivero desordenado: la 1NF asegura que cada cajón tiene un tipo de documento, la 2NF asegura que los documentos estén archivados bajo la categoría correcta, y la 3NF mueve la información referenciada a su propio cajón dedicado. Al final, cada dato existe en exactamente un lugar — actualízalo una vez y es correcto en todas partes.
En esta lección, recorreremos dos ejemplos completos — un sistema de pedidos de hardware y un sistema de visitas hospitalarias — transformando cada uno de una tabla caótica en un conjunto limpio de tablas normalizadas en 3NF. En el camino, aprenderás a identificar claves primarias, claves foráneas, claves compuestas y las dependencias que impulsan cada paso de normalización.
UNF a 1NF — Eliminación de Grupos Repetitivos
Ejemplo de pedido de hardware: un valor por celda, un hecho por fila
Cómo identificarlo: Observa cada celda de tu tabla. ¿Alguna celda contiene más de un valor (separados por comas, barras o listados verticalmente)? Si es así, esos atributos forman un grupo repetitivo. La solución es siempre la misma: mueve los atributos repetidos a una nueva tabla, dale un nombre significativo y enlázala usando la clave primaria original como clave foránea.
| Order No | Date | Cust No | Name | Item No | Description | Cost | Qty |
|---|---|---|---|---|---|---|---|
| 1001 | 05-Feb | 0123 | Amal | X3412/X2189 | 120Gb HD/Cisco NIC | 40/20 | 5/25 |
| 1002 | 10-Feb | 0345 | Ali | Y7674/B3456/F67584 | 17" Monitor/Wireless Mouse/2GB Ram | 50/10/80 | 6/10/7 |
| Order No | Date | Cust No | Name | Address | Contact | Item No | Description | Cost | Qty |
|---|---|---|---|---|---|---|---|---|---|
| 1001 | 05-Feb | 0123 | Amal | Dublin | 39112200 | X3412 | 120Gb HD | 40 | 5 |
| 1001 | 05-Feb | 0123 | Amal | Dublin | 39112200 | X2189 | Cisco NIC | 20 | 25 |
| 1002 | 10-Feb | 0345 | Ali | Meath | 3321001 | Y7674 | 17" Monitor | 50 | 6 |
| 1002 | 10-Feb | 0345 | Ali | Meath | 3321001 | B3456 | Wireless Mouse | 10 | 10 |
| 1002 | 10-Feb | 0345 | Ali | Meath | 3321001 | F67584 | 2GB Ram | 80 | 7 |
| Order No (PK) | Date | Cust No | Name | Address | Contact |
|---|---|---|---|---|---|
| 1001 | 05-Feb-2024 | 0123 | Amal | Dublin | 39112200 |
| 1002 | 10-Feb-2024 | 0345 | Ali | Meath | 3321001 |
| Order No (FK) | Item No (PK) | Description | Cost | Qty |
|---|---|---|---|---|
| 1001 | X3412 | 120Gb HD | 40 | 5 |
| 1001 | X2189 | Cisco NIC | 20 | 25 |
| 1002 | Y7674 | 17" Monitor | 50 | 6 |
| 1002 | B3456 | Wireless Mouse | 10 | 10 |
| 1002 | F67584 | 2GB Ram | 80 | 7 |
Las columnas de artículos repetidos (naranja) se mueven a su propia tabla. Cada artículo ahora tiene su propia fila, y las dos tablas se enlazan por Order Number.
1NF a 2NF — Eliminación de Dependencias Parciales
Ejemplo de pedido de hardware: Description y Unit Cost dependen solo de Item Number
Cómo identificarlo: Primero, verifica si alguna tabla tiene una clave compuesta (dos o más columnas formando la clave primaria). Si la tiene, pregúntate para cada atributo no clave: "¿Este atributo necesita AMBAS partes de la clave para ser identificado, o solo una?" Si la respuesta es "solo una", ese atributo tiene una dependencia parcial y debe moverse a su propia tabla. Aquí, "¿Cómo se llama el artículo X3412?" solo necesita Item Number — no importa a qué pedido pertenece.
| Order No (FK) | Item No (FK) | Qty |
|---|---|---|
| 1001 | X3412 | 5 |
| 1001 | X2189 | 25 |
| 1002 | Y7674 | 6 |
| 1002 | B3456 | 10 |
| 1002 | F67584 | 7 |
| Item No (PK) | Description | Unit Cost |
|---|---|---|
| X3412 | 120Gb HD | 40 |
| X2189 | Cisco NIC | 20 |
| Y7674 | 17" Monitor | 50 |
| B3456 | Wireless Mouse | 10 |
| F67584 | 2GB Ram | 80 |
Description y Unit Cost se mueven a ITEM porque dependen solo de Item Number, no de la clave compuesta completa.
2NF a 3NF — Eliminación de Dependencias Transitivas
Ejemplo de pedido de hardware: Name, Address y Contact dependen de Customer Number, no de Order Number
Cómo identificarlo: Para cada atributo no clave, pregunta: "¿Este atributo describe directamente la clave primaria, o describe otro atributo no clave?" Si Name describe Customer Number (no Order Number), tienes una dependencia transitiva. La prueba práctica: "Si cambio este valor, ¿estaría mal en otras filas?" Si Amal se muda de Dublin a Cork, cada pedido que hizo mostraría la dirección incorrecta — eso significa que la dirección pertenece a su propia tabla.
| Order No (PK) | Cust No (FK) | Order Date |
|---|---|---|
| 1001 | 0123 | 05-Feb-2024 |
| 1002 | 0345 | 10-Feb-2024 |
| Cust No (PK) | Name | Address | Contact |
|---|---|---|---|
| 0123 | Amal | Dublin | 39112200 |
| 0345 | Ali | Meath | 3321001 |
| Order No (PK) | Cust No (FK) | Date |
|---|---|---|
| 1001 | 0123 | 05-Feb-2024 |
| 1002 | 0345 | 10-Feb-2024 |
| Cust No (PK) | Name | Address | Contact |
|---|---|---|---|
| 0123 | Amal | Dublin | 39112200 |
| 0345 | Ali | Meath | 3321001 |
| Item No (PK) | Description | Cost |
|---|---|---|
| X3412 | 120Gb HD | 40 |
| X2189 | Cisco NIC | 20 |
| Y7674 | 17" Monitor | 50 |
| B3456 | Wireless Mouse | 10 |
| F67584 | 2GB Ram | 80 |
| Order No (FK) | Item No (FK) | Qty |
|---|---|---|
| 1001 | X3412 | 5 |
| 1001 | X2189 | 25 |
| 1002 | Y7674 | 6 |
| 1002 | B3456 | 10 |
| 1002 | F67584 | 7 |
El resultado completo en 3NF: ORDER, CUSTOMER, ITEM y ORDER_ITEM — cuatro tablas sin redundancia, sin dependencias parciales y sin dependencias transitivas.
Pedido de Hardware — Relaciones entre Tablas
Cómo las cuatro tablas en 3NF se conectan mediante claves foráneas
Sistema de Visitas Hospitalarias — Paso a Paso
Aplicando la lista de verificación de tres pasos a datos de salud
| VisitID | Patient | Date | Treatments |
|---|---|---|---|
| V101 | Ali Khan | 2026-03-10 | X-Ray (Dr Smith, Radiology, €120), Blood Test (Dr John, Pathology, €50) |
| V102 | Sara Noor | 2026-03-11 | MRI Scan (Dr Lee, Imaging, €300), ECG (Dr Patel, Cardiology, €90) |
| V103 | Emma Cole | 2026-03-12 | Consulta (Dr Patel, Cardiología, €80), Radiografía (Dr Smith, Radiología, €120) |
| VisitID | PatientID | PatientName | Date | Treatment | Doctor | Dept | Cost |
|---|---|---|---|---|---|---|---|
| V101 | P01 | Ali Khan | 2026-03-10 | X-Ray | Dr Smith | Radiology | €120 |
| V101 | P01 | Ali Khan | 2026-03-10 | Blood Test | Dr John | Pathology | €50 |
| V102 | P02 | Sara Noor | 2026-03-11 | Resonancia | Dr Lee | Imagen | €300 |
| V102 | P02 | Sara Noor | 2026-03-11 | ECG | Dr Patel | Cardiología | €90 |
| V103 | P03 | Emma Cole | 2026-03-12 | Consulta | Dr Patel | Cardiología | €80 |
| V103 | P03 | Emma Cole | 2026-03-12 | Radiografía | Dr Smith | Radiología | €120 |
| VisitID | PatientID | Name | Date |
|---|---|---|---|
| V101 | P01 | Ali Khan | 2026-03-10 |
| V102 | P02 | Sara Noor | 2026-03-11 |
| V103 | P03 | Emma Cole | 2026-03-12 |
| VisitID (FK) | Treatment | Doctor | Dept | Cost |
|---|---|---|---|---|
| V101 | X-Ray | Dr Smith | Radiology | €120 |
| V101 | Blood Test | Dr John | Pathology | €50 |
| V102 | Resonancia | Dr Lee | Imagen | €300 |
| V102 | ECG | Dr Patel | Cardiología | €90 |
| V103 | Consulta | Dr Patel | Cardiología | €80 |
| V103 | Radiografía | Dr Smith | Radiología | €120 |
| PatientID | Name |
|---|---|
| P01 | Ali Khan |
| P02 | Sara Noor |
| P03 | Emma Cole |
| VisitID | PatientID (FK) | Date |
|---|---|---|
| V101 | P01 | 2026-03-10 |
| V102 | P02 | 2026-03-11 |
| V103 | P03 | 2026-03-12 |
| DoctorID | Name | Dept |
|---|---|---|
| D01 | Dr Smith | Radiology |
| D02 | Dr John | Pathology |
| D03 | Dr Lee | Imaging |
| D04 | Dr Patel | Cardiology |
| TreatmentID | Name | Cost |
|---|---|---|
| T01 | X-Ray | €120 |
| T02 | Blood Test | €50 |
| T03 | MRI Scan | €300 |
| T04 | ECG | €90 |
| T05 | Consultation | €80 |
| VisitID (FK) | TreatmentID (FK) | DoctorID (FK) |
|---|---|---|
| V101 | T01 | D01 |
| V101 | T02 | D02 |
| V102 | T03 | D03 |
| V102 | T04 | D04 |
| V103 | T05 | D04 |
| V103 | T01 | D01 |
El ejemplo hospitalario produce cinco tablas en 3NF. Cada dato se almacena una vez — actualizar el departamento de un médico o el costo de un tratamiento requiere cambiar solo una fila.
Sistema de Visitas Hospitalarias — Relaciones entre Tablas
Cómo las cinco tablas en 3NF se conectan mediante claves foráneas
Cómo Identificar Dónde Dividir Tablas
Una lista de verificación de tres pasos para cada forma normal
Busca: Barras (X3412/X2189), listas separadas por comas, múltiples filas de datos agrupadas en una celda.
Si SÍ: Primero, expande cada celda con múltiples valores en su propia fila — obtienes una gran tabla plana donde cada celda es atómica. Luego observa la redundancia (datos que se repiten entre filas) y divide los atributos repetidos en una nueva tabla. Usa la PK original como clave foránea en la nueva tabla y crea una clave compuesta (PK original + PK del nuevo atributo).
Si NO: La tabla ya está en 1NF — procede al paso 2.
Prueba: Para cada columna no clave, pregunta: "¿Necesito AMBAS partes de la clave compuesta para buscar este valor?"
Si SÍ (existe dep. parcial): Mueve los atributos parcialmente dependientes a una nueva tabla, con clave en la parte de la que dependen.
Si NO (o sin clave compuesta): La tabla ya está en 2NF — procede al paso 3.
Prueba: Para cada columna no clave, pregunta: "¿Esto describe la PK directamente, o describe una columna diferente?"
Prueba práctica: "Si actualizo este valor, ¿otras filas se volverían inconsistentes?"
Si SÍ (existe dep. transitiva): Mueve los atributos transitivamente dependientes a una nueva tabla. Mantén la columna intermediaria como FK.
Si NO: ¡Felicitaciones — tu tabla está en 3NF!
Aplica estas tres verificaciones en orden a cualquier tabla. Cada paso se basa en el anterior — debes lograr la 1NF antes de verificar la 2NF, y la 2NF antes de verificar la 3NF.
Ejemplo Resuelto — Sistema de Cursos de Profesores
Normalizando un horario universitario de UNF a 3NF
| Lect No | Name | Faculty | Office | Course Code | Course Name | Start Date | Weekly Hrs |
|---|---|---|---|---|---|---|---|
| 7146 | James | Business | Room 22 | BM01 | Buss Manage | 12/9/2023 | 4 |
| A01 | Account | 11/9/2023 | 3 | ||||
| E01 | Economics | 30/9/2023 | 7 | ||||
| 1463 | Denis | IT | Room 21 | CS01 | Computer Systems | 01/9/2023 | 6 |
| P01 | Programming | 02/9/2023 | 5 | ||||
| 6455 | Phil | Business | Room 22 | BM01 | Buss Manage | 04/10/2023 | 4 |
| M01 | Marketing | 10/10/2023 | 6 |
| Lect No | Name | Faculty | Office | Course Code | Course Name | Start | Hrs |
|---|---|---|---|---|---|---|---|
| 7146 | James | Business | Room 22 | BM01 | Buss Manage | 12/9/23 | 4 |
| 7146 | James | Business | Room 22 | A01 | Account | 11/9/23 | 3 |
| 7146 | James | Business | Room 22 | E01 | Economics | 30/9/23 | 7 |
| 1463 | Denis | IT | Room 21 | CS01 | Comp Systems | 01/9/23 | 6 |
| 1463 | Denis | IT | Room 21 | P01 | Programming | 02/9/23 | 5 |
| 6455 | Phil | Business | Room 22 | BM01 | Buss Manage | 04/10/23 | 4 |
| 6455 | Phil | Business | Room 22 | M01 | Marketing | 10/10/23 | 6 |
| Lect No (PK) | Name | Faculty | Office |
|---|---|---|---|
| 7146 | James | Business | Room 22 |
| 1463 | Denis | IT | Room 21 |
| 6455 | Phil | Business | Room 22 |
| Lect No (FK) | Course Code | Course Name | Start | Hrs |
|---|---|---|---|---|
| 7146 | BM01 | Buss Manage | 12/9/23 | 4 |
| 7146 | A01 | Account | 11/9/23 | 3 |
| 7146 | E01 | Economics | 30/9/23 | 7 |
| 1463 | CS01 | Comp Systems | 01/9/23 | 6 |
| 1463 | P01 | Programming | 02/9/23 | 5 |
| 6455 | BM01 | Buss Manage | 04/10/23 | 4 |
| 6455 | M01 | Marketing | 10/10/23 | 6 |
| Code (PK) | Name |
|---|---|
| BM01 | Buss Manage |
| A01 | Account |
| E01 | Economics |
| CS01 | Comp Systems |
| P01 | Programming |
| M01 | Marketing |
| Lect No (FK) | Code (FK) | Start Date | Weekly Hrs |
|---|---|---|---|
| 7146 | BM01 | 12/9/23 | 4 |
| 7146 | A01 | 11/9/23 | 3 |
| 7146 | E01 | 30/9/23 | 7 |
| 1463 | CS01 | 01/9/23 | 6 |
| 1463 | P01 | 02/9/23 | 5 |
| 6455 | BM01 | 04/10/23 | 4 |
| 6455 | M01 | 10/10/23 | 6 |
| Lect No (PK) | Name | Faculty | Office |
|---|---|---|---|
| 7146 | James | Business | Room 22 |
| 1463 | Denis | IT | Room 21 |
| 6455 | Phil | Business | Room 22 |
| Code (PK) | Name |
|---|---|
| BM01 | Buss Manage |
| A01 | Account |
| E01 | Economics |
| CS01 | Comp Systems |
| P01 | Programming |
| M01 | Marketing |
| Lect No (FK) | Code (FK) | Start | Hrs |
|---|---|---|---|
| 7146 | BM01 | 12/9/23 | 4 |
| 7146 | A01 | 11/9/23 | 3 |
| 7146 | E01 | 30/9/23 | 7 |
| 1463 | CS01 | 01/9/23 | 6 |
| 1463 | P01 | 02/9/23 | 5 |
| 6455 | BM01 | 04/10/23 | 4 |
| 6455 | M01 | 10/10/23 | 6 |
El ejemplo del profesor utiliza la misma lista de verificación de tres pasos. Course Name tenía una dependencia parcial de Course Code, pero no se encontró ninguna dependencia transitiva — se alcanzó la 3NF en el paso 2.
Sistema de Cursos de Profesores — Relaciones entre Tablas
Cómo las tres tablas en 3NF se conectan mediante claves foráneas
SQL — Paso 1: UNF a 1NF
Dividir la tabla ORDER en ORDER + ORDER_ITEM
-- STEP 1: UNF → 1NF -- Remove repeating groups (item details) into a new table CREATE TABLE "Order" ( order_number INT PRIMARY KEY, order_date DATE NOT NULL, customer_number VARCHAR(4) NOT NULL, name VARCHAR(50) NOT NULL, address VARCHAR(100) NOT NULL, contact_number VARCHAR(20) NOT NULL ); -- New table for the repeating item group -- Composite key: order_number + item_number CREATE TABLE Order_Item ( order_number INT REFERENCES "Order", item_number VARCHAR(10) NOT NULL, description VARCHAR(100) NOT NULL, unit_cost DECIMAL(10,2) NOT NULL, quantity INT NOT NULL, PRIMARY KEY (order_number, item_number) );
SQL — Paso 2: 1NF a 2NF
Extraer la tabla ITEM para eliminar la dependencia parcial
-- STEP 2: 1NF → 2NF -- Description and unit_cost depend only on item_number -- (partial dependency on the composite key) -- Move them to a new ITEM table CREATE TABLE Item ( item_number VARCHAR(10) PRIMARY KEY, description VARCHAR(100) NOT NULL, unit_cost DECIMAL(10,2) NOT NULL ); -- Order_Item now only keeps quantity -- (depends on the FULL composite key) CREATE TABLE Order_Item ( order_number INT REFERENCES "Order", item_number VARCHAR(10) REFERENCES Item, quantity INT NOT NULL, PRIMARY KEY (order_number, item_number) );
SQL — Paso 3: 2NF a 3NF
Extraer la tabla CUSTOMER para eliminar la dependencia transitiva
-- STEP 3: 2NF → 3NF -- Name, address and contact depend on customer_number -- (transitive dependency — not on the PK) -- Move them to a new CUSTOMER table CREATE TABLE Customer ( customer_number VARCHAR(4) PRIMARY KEY, name VARCHAR(50) NOT NULL, address VARCHAR(100) NOT NULL, contact_number VARCHAR(20) NOT NULL ); -- Order now only keeps customer_number as FK CREATE TABLE "Order" ( order_number INT PRIMARY KEY, customer_number VARCHAR(4) REFERENCES Customer, order_date DATE NOT NULL ); -- Final schema: 4 tables in 3NF -- Customer, Order, Item, Order_Item -- Each fact stored exactly once ✓
Referencia Rápida
| Concepto | Regla | Qué Hacer |
|---|---|---|
| UNF | Datos crudos, puede tener grupos repetitivos | Identificar la entidad, listar todos los atributos, encontrar la clave |
| 1NF | Sin atributos multivaluados | Eliminar grupos repetitivos en una nueva tabla; agregar una clave foránea para enlazarlos |
| 2NF | Sin dependencias parciales | Si existe una clave compuesta, mover los atributos que dependen de solo una parte |
| 3NF | Sin dependencias transitivas | Mover atributos no clave que dependen de otros atributos no clave |
| Clave Primaria (PK) | Identifica únicamente cada fila | No puede ser NULL; subrayada en la notación |
| Clave Foránea (FK) | Referencia una PK en otra tabla | Crea relaciones entre tablas |
| Clave Compuesta | Dos o más atributos formando una PK | Se usa cuando ningún atributo es único por sí solo (ej. Order No + Item No) |
Ejercicios Prácticos
Pon a prueba tu comprensión de la normalización
Lecturer_no, Name, Faculty, Office_loc, Course_code, Course_name, Start_date, Weekly_time. Un profesor puede impartir varios cursos. ¿Qué columnas forman el grupo repetitivo?| LoanID | MemberName | MemberEmail | BookTitle | Author | LoanDate | ReturnDate |
|---|---|---|---|---|---|---|
| L01 | Jane Doe | jane@mail.com | SQL Basics | T. Brown | 01/03/26 | 15/03/26 |
| L02 | Jane Doe | jane@mail.com | Data Design | R. Singh | 05/03/26 | 19/03/26 |
| L03 | Mark Lee | mark@mail.com | SQL Basics | T. Brown | 10/03/26 | 24/03/26 |
| BookingID | Client | Phone | Class | Instructor | Inst Phone | Room | Date |
|---|---|---|---|---|---|---|---|
| B01 | Anna | 555-1234 | Yoga | Coach Kim | 555-9999 | R1 | 10/03/26 |
| B02 | Tom | 555-5678 | Yoga | Coach Kim | 555-9999 | R1 | 10/03/26 |
| B03 | Anna | 555-1234 | Pilates | Coach Lee | 555-8888 | R2 | 11/03/26 |
| PurchID | CustEmail | CustName | Product | Category | CatDiscount | Qty | Date |
|---|---|---|---|---|---|---|---|
| P01 | jo@mail.com | Jo | Keyboard | Peripherals | 10% | 2 | 01/03/26 |
| P02 | jo@mail.com | Jo | Monitor | Displays | 5% | 1 | 02/03/26 |
| P03 | sam@mail.com | Sam | Mouse | Peripherals | 10% | 3 | 03/03/26 |
| ReservID | Guest | GuestEmail | CheckIn | RoomNo | RoomType | Rate | Services |
|---|---|---|---|---|---|---|---|
| R01 | Liam | liam@mail.com | 01/03 | 101 | Single | €80 | Breakfast €15, Spa €40 |
| R02 | Mia | mia@mail.com | 02/03 | 205 | Double | €120 | Breakfast €15, Gym €10, Laundry €25 |
| R03 | Liam | liam@mail.com | 10/03 | 101 | Single | €80 | Gym €10 |
| StudentID | Name | Address | DeptCode | DeptName | Modules |
|---|---|---|---|---|---|
| S001 | Ava | Dublin | CS | Comp Sci | M101 Databases (Dr Ryan, B+), M102 Networks (Dr Kelly, A) |
| S002 | Noah | Cork | CS | Comp Sci | M101 Databases (Dr Ryan, A-), M103 Web Dev (Dr Murphy, B) |
| S003 | Ella | Galway | BA | Business | M201 Marketing (Dr Walsh, A), M101 Databases (Dr Ryan, B+) |
Respuestas
| LoanID | MemberName | MemberEmail | BookTitle | Author | LoanDate | ReturnDate |
|---|---|---|---|---|---|---|
| L01 | Jane Doe | jane@mail.com | SQL Basics | T. Brown | 01/03/26 | 15/03/26 |
| L02 | Jane Doe | jane@mail.com | Data Design | R. Singh | 05/03/26 | 19/03/26 |
| L03 | Mark Lee | mark@mail.com | SQL Basics | T. Brown | 10/03/26 | 24/03/26 |
| LoanID | MemberName | MemberEmail | BookTitle | Author | LoanDate | ReturnDate |
|---|---|---|---|---|---|---|
| L01 | Jane Doe | jane@mail.com | SQL Basics | T. Brown | 01/03/26 | 15/03/26 |
| L02 | Jane Doe | jane@mail.com | Data Design | R. Singh | 05/03/26 | 19/03/26 |
| L03 | Mark Lee | mark@mail.com | SQL Basics | T. Brown | 10/03/26 | 24/03/26 |
| LoanID | MemberName | MemberEmail | BookTitle | Author | LoanDate | ReturnDate |
|---|---|---|---|---|---|---|
| L01 | Jane Doe | jane@mail.com | SQL Basics | T. Brown | 01/03/26 | 15/03/26 |
| L02 | Jane Doe | jane@mail.com | Data Design | R. Singh | 05/03/26 | 19/03/26 |
| L03 | Mark Lee | mark@mail.com | SQL Basics | T. Brown | 10/03/26 | 24/03/26 |
• MemberName y MemberEmail dependen del member, not on LoanID — dependencia transitiva.
• BookTitle y Author dependen del book, not on LoanID — dependencia transitiva.
Fix: extraer las tablas MEMBER y BOOK.
| MemberID | MemberName | MemberEmail |
|---|---|---|
| M01 | Jane Doe | jane@mail.com |
| M02 | Mark Lee | mark@mail.com |
| BookID | BookTitle | Author |
|---|---|---|
| B01 | SQL Basics | T. Brown |
| B02 | Data Design | R. Singh |
| LoanID | MemberID (FK) | BookID (FK) | LoanDate | ReturnDate |
|---|---|---|---|---|
| L01 | M01 | B01 | 01/03/26 | 15/03/26 |
| L02 | M01 | B02 | 05/03/26 | 19/03/26 |
| L03 | M02 | B01 | 10/03/26 | 24/03/26 |
| BookingID | Client | Phone | Class | Instructor | Inst Phone | Room | Date |
|---|---|---|---|---|---|---|---|
| B01 | Anna | 555-1234 | Yoga | Coach Kim | 555-9999 | R1 | 10/03/26 |
| B02 | Tom | 555-5678 | Yoga | Coach Kim | 555-9999 | R1 | 10/03/26 |
| B03 | Anna | 555-1234 | Pilates | Coach Lee | 555-8888 | R2 | 11/03/26 |
| BookingID | Client | Phone | Class | Instructor | Inst Phone | Room | Date |
|---|---|---|---|---|---|---|---|
| B01 | Anna | 555-1234 | Yoga | Coach Kim | 555-9999 | R1 | 10/03/26 |
| B02 | Tom | 555-5678 | Yoga | Coach Kim | 555-9999 | R1 | 10/03/26 |
| B03 | Anna | 555-1234 | Pilates | Coach Lee | 555-8888 | R2 | 11/03/26 |
| BookingID | Client | Phone | Class | Instructor | Inst Phone | Room | Date |
|---|---|---|---|---|---|---|---|
| B01 | Anna | 555-1234 | Yoga | Coach Kim | 555-9999 | R1 | 10/03/26 |
| B02 | Tom | 555-5678 | Yoga | Coach Kim | 555-9999 | R1 | 10/03/26 |
| B03 | Anna | 555-1234 | Pilates | Coach Lee | 555-8888 | R2 | 11/03/26 |
• Phone depende de Client, not on BookingID — dependencia transitiva (Anna's phone repeats in B01 & B03).
• Instructor, Inst Phone & Room depend on Class, not on BookingID — dependencia transitiva (Yoga is always Coach Kim in R1).
• Inst Phone depende de Instructor, not on Class — another dependencia transitiva (Coach Kim's phone describes the instructor).
Fix: extraer las tablas CLIENT, INSTRUCTOR y CLASS.
| ClientID | ClientName | Phone |
|---|---|---|
| C01 | Anna | 555-1234 |
| C02 | Tom | 555-5678 |
| InstructorID | Name | Phone |
|---|---|---|
| I01 | Coach Kim | 555-9999 |
| I02 | Coach Lee | 555-8888 |
| ClassID | ClassName | InstructorID (FK) | Room |
|---|---|---|---|
| CL01 | Yoga | I01 | R1 |
| CL02 | Pilates | I02 | R2 |
| BookingID | ClientID (FK) | ClassID (FK) | Date |
|---|---|---|---|
| B01 | C01 | CL01 | 10/03/26 |
| B02 | C02 | CL01 | 10/03/26 |
| B03 | C01 | CL02 | 11/03/26 |
| PurchID | CustEmail | CustName | Product | Category | CatDiscount | Qty | Date |
|---|---|---|---|---|---|---|---|
| P01 | jo@mail.com | Jo | Keyboard | Peripherals | 10% | 2 | 01/03/26 |
| P02 | jo@mail.com | Jo | Monitor | Displays | 5% | 1 | 02/03/26 |
| P03 | sam@mail.com | Sam | Mouse | Peripherals | 10% | 3 | 03/03/26 |
| PurchID | CustEmail | CustName | Product | Category | CatDiscount | Qty | Date |
|---|---|---|---|---|---|---|---|
| P01 | jo@mail.com | Jo | Keyboard | Peripherals | 10% | 2 | 01/03/26 |
| P02 | jo@mail.com | Jo | Monitor | Displays | 5% | 1 | 02/03/26 |
| P03 | sam@mail.com | Sam | Mouse | Peripherals | 10% | 3 | 03/03/26 |
| PurchID | CustEmail | CustName | Product | Category | CatDiscount | Qty | Date |
|---|---|---|---|---|---|---|---|
| P01 | jo@mail.com | Jo | Keyboard | Peripherals | 10% | 2 | 01/03/26 |
| P02 | jo@mail.com | Jo | Monitor | Displays | 5% | 1 | 02/03/26 |
| P03 | sam@mail.com | Sam | Mouse | Peripherals | 10% | 3 | 03/03/26 |
• CustName depende de CustEmail, not on PurchID — dependencia transitiva (Jo's name repeats whenever jo@mail.com appears).
• Category depende de Product, not on PurchID — dependencia transitiva (Keyboard is always Peripherals).
• CatDiscount depende de Category, not on Product — this is a cadena doble transitiva: PurchID → Product → Category → CatDiscount (el 10% pertenece a all Peripherals, no por producto).
Fix: extraer las tablas CUSTOMER, CATEGORY y PRODUCT.
| CustID | CustEmail | CustName |
|---|---|---|
| C01 | jo@mail.com | Jo |
| C02 | sam@mail.com | Sam |
| CatID | CatName | CatDiscount |
|---|---|---|
| CAT01 | Peripherals | 10% |
| CAT02 | Displays | 5% |
| ProdID | ProdName | CatID (FK) |
|---|---|---|
| PR01 | Keyboard | CAT01 |
| PR02 | Monitor | CAT02 |
| PR03 | Mouse | CAT01 |
| PurchID | CustID (FK) | ProdID (FK) | Qty | Date |
|---|---|---|---|---|
| P01 | C01 | PR01 | 2 | 01/03/26 |
| P02 | C01 | PR02 | 1 | 02/03/26 |
| P03 | C02 | PR03 | 3 | 03/03/26 |
| ReservID | Guest | GuestEmail | CheckIn | RoomNo | RoomType | Rate | Services |
|---|---|---|---|---|---|---|---|
| R01 | Liam | liam@mail.com | 01/03 | 101 | Single | €80 | Breakfast €15, Spa €40 |
| R02 | Mia | mia@mail.com | 02/03 | 205 | Double | €120 | Breakfast €15, Gym €10, Laundry €25 |
| R03 | Liam | liam@mail.com | 10/03 | 101 | Single | €80 | Gym €10 |
| ReservID | Guest | GuestEmail | CheckIn | RoomNo | RoomType | Rate | ServiceName | ServicePrice |
|---|---|---|---|---|---|---|---|---|
| R01 | Liam | liam@mail.com | 01/03 | 101 | Single | €80 | Breakfast | €15 |
| R01 | Liam | liam@mail.com | 01/03 | 101 | Single | €80 | Spa | €40 |
| R02 | Mia | mia@mail.com | 02/03 | 205 | Double | €120 | Breakfast | €15 |
| R02 | Mia | mia@mail.com | 02/03 | 205 | Double | €120 | Gym | €10 |
| R02 | Mia | mia@mail.com | 02/03 | 205 | Double | €120 | Laundry | €25 |
| R03 | Liam | liam@mail.com | 10/03 | 101 | Single | €80 | Gym | €10 |
| ReservID | Guest | GuestEmail | CheckIn | RoomNo | RoomType | Rate |
|---|---|---|---|---|---|---|
| R01 | Liam | liam@mail.com | 01/03 | 101 | Single | €80 |
| R02 | Mia | mia@mail.com | 02/03 | 205 | Double | €120 |
| R03 | Liam | liam@mail.com | 10/03 | 101 | Single | €80 |
| ReservID | ServiceName | Price |
|---|---|---|
| R01 | Breakfast | €15 |
| R01 | Spa | €40 |
| R02 | Breakfast | €15 |
| R02 | Gym | €10 |
| R02 | Laundry | €25 |
| R03 | Gym | €10 |
| ServiceID | ServiceName | Price |
|---|---|---|
| SV01 | Breakfast | €15 |
| SV02 | Spa | €40 |
| SV03 | Gym | €10 |
| SV04 | Laundry | €25 |
| ReservID (FK) | ServiceID (FK) |
|---|---|
| R01 | SV01 |
| R01 | SV02 |
| R02 | SV01 |
| R02 | SV03 |
| R02 | SV04 |
| R03 | SV03 |
| GuestID | GuestName | GuestEmail |
|---|---|---|
| G01 | Liam | liam@mail.com |
| G02 | Mia | mia@mail.com |
| RoomNo | RoomType | Rate |
|---|---|---|
| 101 | Single | €80 |
| 205 | Double | €120 |
| ReservID | GuestID (FK) | RoomNo (FK) | CheckIn |
|---|---|---|---|
| R01 | G01 | 101 | 01/03 |
| R02 | G02 | 205 | 02/03 |
| R03 | G01 | 101 | 10/03 |
| ReservID (FK) | ServiceID (FK) |
|---|---|
| R01 | SV01 |
| R01 | SV02 |
| R02 | SV01 |
| R02 | SV03 |
| R02 | SV04 |
| R03 | SV03 |
| StudentID | Name | Address | DeptCode | DeptName | Modules |
|---|---|---|---|---|---|
| S001 | Ava | Dublin | CS | Comp Sci | M101 Databases (Dr Ryan, B+), M102 Networks (Dr Kelly, A) |
| S002 | Noah | Cork | CS | Comp Sci | M101 Databases (Dr Ryan, A-), M103 Web Dev (Dr Murphy, B) |
| S003 | Ella | Galway | BA | Business | M201 Marketing (Dr Walsh, A), M101 Databases (Dr Ryan, B+) |
| StudentID | Name | Address | DeptCode | DeptName | ModCode | ModName | Lecturer | Grade |
|---|---|---|---|---|---|---|---|---|
| S001 | Ava | Dublin | CS | Comp Sci | M101 | Databases | Dr Ryan | B+ |
| S001 | Ava | Dublin | CS | Comp Sci | M102 | Networks | Dr Kelly | A |
| S002 | Noah | Cork | CS | Comp Sci | M101 | Databases | Dr Ryan | A- |
| S002 | Noah | Cork | CS | Comp Sci | M103 | Web Dev | Dr Murphy | B |
| S003 | Ella | Galway | BA | Business | M201 | Marketing | Dr Walsh | A |
| S003 | Ella | Galway | BA | Business | M101 | Databases | Dr Ryan | B+ |
| StudentID | Name | Address | DeptCode | DeptName |
|---|---|---|---|---|
| S001 | Ava | Dublin | CS | Comp Sci |
| S002 | Noah | Cork | CS | Comp Sci |
| S003 | Ella | Galway | BA | Business |
| StudentID | ModCode | ModName | Lecturer | Grade |
|---|---|---|---|---|
| S001 | M101 | Databases | Dr Ryan | B+ |
| S001 | M102 | Networks | Dr Kelly | A |
| S002 | M101 | Databases | Dr Ryan | A- |
| S002 | M103 | Web Dev | Dr Murphy | B |
| S003 | M201 | Marketing | Dr Walsh | A |
| S003 | M101 | Databases | Dr Ryan | B+ |
| ModCode | ModName | Lecturer |
|---|---|---|
| M101 | Databases | Dr Ryan |
| M102 | Networks | Dr Kelly |
| M103 | Web Dev | Dr Murphy |
| M201 | Marketing | Dr Walsh |
| StudentID (FK) | ModCode (FK) | Grade |
|---|---|---|
| S001 | M101 | B+ |
| S001 | M102 | A |
| S002 | M101 | A- |
| S002 | M103 | B |
| S003 | M201 | A |
| S003 | M101 | B+ |
| DeptCode | DeptName |
|---|---|
| CS | Comp Sci |
| BA | Business |
| StudentID | Name | Address | DeptCode (FK) |
|---|---|---|---|
| S001 | Ava | Dublin | CS |
| S002 | Noah | Cork | CS |
| S003 | Ella | Galway | BA |
| ModCode | ModName | Lecturer |
|---|---|---|
| M101 | Databases | Dr Ryan |
| M102 | Networks | Dr Kelly |
| M103 | Web Dev | Dr Murphy |
| M201 | Marketing | Dr Walsh |
| StudentID (FK) | ModCode (FK) | Grade |
|---|---|---|
| S001 | M101 | B+ |
| S001 | M102 | A |
| S002 | M101 | A- |
| S002 | M103 | B |
| S003 | M201 | A |
| S003 | M101 | B+ |
Referencias
Fuentes utilizadas en la elaboración de este material
¡Feliz estudio!
Las bases de datos son el fundamento de toda aplicación moderna