Módulo 1: Introducción y Conceptos Clave

Sentando las bases: qué son las bases de datos, por qué son cruciales y cuáles son los principios que garantizan su fiabilidad.

1.1. El Ecosistema de Datos: Más allá de los Archivos

No todos los almacenamientos de datos son iguales. Es crucial entender el propósito de cada uno:

  • Archivos Planos (CSV, Excel): Excelentes para compartir y para análisis rápidos y pequeños. No gestionan concurrencia, seguridad ni integridad.
  • Bases de Datos (SGBD): Sistemas optimizados para transacciones operativas del día a día (lectura y escritura constante). Son la fuente de verdad para las aplicaciones.
  • Data Warehouse (Almacén de Datos): Bases de datos especializadas y optimizadas para el análisis y la generación de informes (Business Intelligence). Consolidan datos históricos de múltiples fuentes.
  • Data Lake (Lago de Datos): Repositorio centralizado para almacenar enormes cantidades de datos en su formato nativo (estructurados, semi-estructurados y no estructurados). Ideal para Machine Learning y Big Data.

1.2. El Modelo Relacional y sus Garantías: ACID

Las bases de datos relacionales garantizan la fiabilidad de las transacciones a través de las propiedades ACID:

Propiedades ACID (Click para expandir)

Atomicidad: Una transacción se ejecuta completamente o no se ejecuta en absoluto. Si falla a mitad de camino, todo se revierte (rollback). Analogía: Una transferencia bancaria. O el dinero sale de una cuenta y llega a la otra, o no ocurre nada.

Consistencia: La base de datos siempre se mantiene en un estado válido. Ninguna transacción puede dejar los datos en un estado "roto" que viole las reglas definidas (constraints). Analogía: El saldo de una cuenta no puede ser negativo si existe esa regla.

Isolamiento (Isolation): Las transacciones concurrentes no se interfieren entre sí. Cada una opera como si fuera la única que se está ejecutando en el sistema. Analogía: Dos personas intentando comprar el último tiquete de avión al mismo tiempo. Solo una puede tener éxito.

Durabilidad: Una vez que una transacción se ha confirmado (commit), sus cambios son permanentes y sobrevivirán a cualquier fallo del sistema (como un corte de energía). Analogía: Una vez que el cajero te da el dinero y el recibo, la transacción es final.

Módulo 2: Diseño y Normalización

El arte de construir bases de datos robustas y eficientes. Aprenderemos a planificar con diagramas ERD, a eliminar la redundancia con las formas normales y a entender cuándo romper las reglas.

2.1. El Arte de la Normalización

La normalización es un proceso sistemático para reducir la redundancia y mejorar la integridad de los datos. Exploraremos las formas más comunes con ejemplos prácticos.

stateDiagram-v2 [*] --> NoNormalizada: "Tabla Plana" NoNormalizada --> 1FN : Aplicar atomicidad 1FN --> 2FN : Eliminar dependencias parciales 2FN --> 3FN : Eliminar dependencias transitivas 3FN --> BCNF : Reforzar dependencias de clave BCNF --> [*] : "Esquema Normalizado"

2.2. Las Formas Normales en la Práctica

Primera Forma Normal (1FN): Valores Atómicos

Regla: Cada celda de una tabla debe contener un solo valor (atómico), y no puede haber grupos de columnas repetidas.

Anti-ejemplo (Viola 1FN):
id_clientenombretelefonos
1Juan Pérez"310-123, 311-456"
Solución (Cumple 1FN):

Se divide en dos tablas.

id_cliente (PK)nombre
1Juan Pérez
id_telefonoid_cliente (FK)telefono
1011310-123
1021311-456
Segunda Forma Normal (2FN): Dependencia Total

Regla: La tabla debe estar en 1FN y cada atributo que no es clave debe depender de la totalidad de la clave primaria (aplica a claves compuestas).

Anti-ejemplo (Viola 2FN):

Clave primaria compuesta: (id_pedido, id_producto). `nombre_producto` depende solo de `id_producto`.

id_pedidoid_productonombre_productocantidad
100155Laptop XYZ1
Solución (Cumple 2FN):
id_pedidoid_productocantidad
1001551
id_productonombre_producto
55Laptop XYZ
Tercera Forma Normal (3FN) y FNBC

Regla (3FN): La tabla debe estar en 2FN y ningún atributo no-clave debe depender de otro atributo no-clave (dependencia transitiva).

Anti-ejemplo (Viola 3FN):

`nombre_departamento` depende de `id_departamento`, que no es la clave primaria.

id_empleadonombreid_departamentonombre_departamento
E10AnaD5Ventas
Solución (Cumple 3FN y FNBC):
id_empleadonombreid_departamento
E10AnaD5
id_departamentonombre_departamento
D5Ventas

Módulo 3: SQL a Profundidad

Si el diseño de la base de datos es el esqueleto, SQL es el sistema nervioso que le da vida. En este módulo, vamos a diseccionar el lenguaje para entender no solo cómo pedir datos, sino cómo definirlos, manipularlos, controlarlos y asegurar su integridad. Dominarás SQL como un conjunto de herramientas completo, entendiendo el rol de cada comando y la lógica que el motor de base de datos aplica para ejecutar tus peticiones de la forma más eficiente.

3.1. Las Cuatro Caras de SQL: DDL, DML, DCL y TCL

SQL se divide en cuatro sub-lenguajes. Cada uno tiene una misión específica y es crucial entender sus diferencias para ser un profesional de datos completo.

A. DDL (Data Definition Language - Lenguaje de Definición de Datos)

El arquitecto de tu base de datos. Define y gestiona la estructura de las tablas y otros objetos.

graph TD subgraph "Ciclo de Vida de un Objeto (DDL)" A[Inicio] --> B(CREATE TABLE); B --> C{¿Estructura correcta?}; C -- No --> D(ALTER TABLE); D --> C; C -- Sí --> E{¿Objeto necesario?}; E -- No --> F(DROP TABLE); E -- Sí --> G[Fin]; end
Ver Comandos Clave de DDL
  • CREATE: Construye un nuevo objeto en la base de datos. `CREATE TABLE` es el más común, definiendo columnas y sus tipos de datos, pero también se usa para `INDEX`, `VIEW`, `SCHEMA`, etc.
  • ALTER: Modifica la estructura de un objeto existente sin eliminarlo. Permite añadir, eliminar o cambiar columnas, cambiar sus tipos de datos, o añadir restricciones (`CONSTRAINTS`).
  • DROP: Elimina un objeto de la base de datos de forma permanente. Es una operación irreversible que borra la estructura y todos sus datos. Usar con extrema precaución.
  • TRUNCATE: Vacía una tabla eliminando todas sus filas de forma masiva. Es mucho más rápido que `DELETE` porque no registra cada borrado de fila, pero a cambio, no se puede revertir fácilmente (no dispara `TRIGGERS`).

B. DML (Data Manipulation Language - Lenguaje de Manipulación de Datos)

El operador del día a día. Se utiliza para consultar, insertar, modificar y eliminar los datos dentro de las tablas.

graph LR subgraph "Flujo de Datos (DML)" direction LR D[(Tabla de Datos)] end A[INSERT] -- Añade datos --> D; D -- Se consultan con --> B(SELECT); B -- ¿Requiere cambio? --> E(UPDATE); B -- ¿Requiere borrado? --> G(DELETE); E -- Modifica datos en --> D; G -- Elimina datos de --> D;
Ver Comandos Clave de DML
  • SELECT: El comando fundamental para el análisis. Extrae datos de las tablas, permitiendo filtrar, ordenar, agrupar y combinar información. Los JOINs y Funciones de Ventana son parte de su poder.
  • INSERT: Añade nuevas filas (registros) a una tabla. Se debe proporcionar valores para las columnas requeridas.
  • UPDATE: Modifica los valores de una o más columnas en filas existentes que cumplan una condición especificada en la cláusula `WHERE`.
  • DELETE: Elimina filas completas de una tabla que cumplan una condición en la cláusula `WHERE`. Si no se especifica `WHERE`, borra todas las filas.

C. DCL (Data Control Language - Lenguaje de Control de Datos)

El guardia de seguridad. Administra los permisos y derechos de acceso de los usuarios.

graph TD subgraph "Control de Acceso (DCL)" Admin(Administrador) --> G(GRANT); Admin --> R(REVOKE); G -- Otorga Permiso --> User(Usuario); R -- Quita Permiso --> User; User -- Intenta acceder --> DB(Base de Datos); end
Ver Comandos Clave de DCL
  • GRANT: Otorga a un usuario o rol permisos específicos (como `SELECT`, `INSERT`, `UPDATE`, `EXECUTE`) sobre un objeto de la base de datos (como una tabla o vista).
  • REVOKE: Es la operación inversa a `GRANT`. Remueve permisos previamente concedidos a un usuario o rol, restringiendo su acceso.

D. TCL (Transaction Control Language - Lenguaje de Control de Transacciones)

El gerente de operaciones. Gestiona las transacciones para asegurar la integridad y consistencia de los datos (propiedades ACID).

graph TD subgraph "Flujo de Transacción (TCL)" A(BEGIN TRANSACTION) --> B{Operación 1}; B --> C(SAVEPOINT A); C --> D{Operación 2}; D -- Falla --> E(ROLLBACK TO SAVEPOINT A); E --> F{Continuar?}; F -- Sí --> D; D -- Éxito --> G{Operación 3}; G -- Falla Crítica --> H(ROLLBACK); H --> Z(Fin Transacción); G -- Éxito Total --> I(COMMIT); I --> Z; end
Ver Comandos Clave de TCL
  • COMMIT: Confirma y guarda permanentemente todos los cambios realizados durante la transacción actual.
  • ROLLBACK: Deshace todos los cambios realizados en la transacción actual, revirtiendo la base de datos a su estado anterior.
  • SAVEPOINT: Crea un punto de guardado intermedio dentro de una transacción. Permite hacer un `ROLLBACK` parcial a este punto sin deshacer toda la transacción.

3.2. El Arte de Unir Tablas: Dominando los JOINs

Unir tablas es el pan de cada día en SQL. Es crucial entender cómo funciona cada tipo de `JOIN` para combinar datos de forma precisa.

graph LR subgraph "Tablas Originales" A(Tabla A); B(Tabla B); end subgraph "Resultados del JOIN" C("INNER JOIN
Solo Intersección"); D("LEFT JOIN
Todo de A
+ Coincidencias"); E("RIGHT JOIN
Todo de B
+ Coincidencias"); F("FULL OUTER JOIN
Todo de A y B"); end A -- "Coincidencia en Clave" --> C; B -- "Coincidencia en Clave" --> C; A -- " " --> D; B -- " " --> D; A -- " " --> E; B -- " " --> E; A -- " " --> F; B -- " " --> F;

3.3. Consultas Legibles: Subconsultas vs. Expresiones Comunes de Tabla (CTE)

Ambas permiten construir consultas complejas, pero las CTEs (`WITH`) son a menudo más legibles y reutilizables dentro de una misma consulta, facilitando la lógica y la depuración.

Subconsulta (Menos legible)

SELECT * FROM Empleados
            WHERE salario > (SELECT AVG(salario) FROM Empleados);

CTE (Más legible y organizada)

WITH SalarioPromedio AS (
                SELECT AVG(salario) as avg_sal FROM Empleados
            )
            SELECT * FROM Empleados, SalarioPromedio
            WHERE salario > SalarioPromedio.avg_sal;

3.4. La Magia del Análisis: Funciones de Ventana

Las funciones de ventana realizan cálculos sobre un conjunto de filas relacionadas con la fila actual, sin colapsar el resultado como lo hace `GROUP BY`. Son esenciales para análisis avanzados como rankings, series temporales y cálculos acumulados.


            -- Ranking de ventas por vendedor y mes
            SELECT
                vendedor,
                mes,
                ventas,
                -- Ranking de ventas dentro de cada mes
                RANK() OVER (PARTITION BY mes ORDER BY ventas DESC) as ranking_mensual,
                -- Venta del mes anterior para este vendedor
                LAG(ventas, 1, 0) OVER (PARTITION BY vendedor ORDER BY mes) as ventas_mes_anterior,
                -- Venta acumulada para este vendedor
                SUM(ventas) OVER (PARTITION BY vendedor ORDER BY mes) as venta_acumulada
            FROM Ventas_Mensuales;
                        

Módulo 5: Modelado Dimensional para Business Intelligence

Hasta ahora, hemos dominado cómo diseñar y consultar bases de datos optimizadas para el día a día, las llamadas bases de datos transaccionales (OLTP). Su prioridad es la rapidez y la integridad al registrar operaciones: una venta, una inscripción, una actualización.

Ahora, cambiamos de sombrero. Nos convertimos en analistas de negocio y arquitectos de datos. Nuestro objetivo ya no es registrar transacciones, sino **entender el negocio a través de los datos históricos**. Para esto, necesitamos un tipo de diseño diferente, optimizado para consultas masivas y análisis complejos (OLAP). Aquí es donde entra el **Modelado Dimensional**.

5.1. El Punto de Partida: Diagramas Entidad-Relación (ER)

Antes de construir un Data Warehouse, los datos nacen en sistemas transaccionales, y estos sistemas se diseñan usando Diagramas Entidad-Relación (ERD). Un ERD es el plano de una base de datos normalizada (como las que vimos en el Módulo 2).

erDiagram CLIENTE ||--o{ PEDIDO : "realiza" PEDIDO ||--|{ DETALLE_PEDIDO : "contiene" PRODUCTO ||--|{ DETALLE_PEDIDO : "es parte de" CLIENTE { int id_cliente PK "DNI del Cliente" string nombre string direccion } PEDIDO { int id_pedido PK date fecha int id_cliente FK "A qué cliente pertenece" } PRODUCTO { int id_producto PK string nombre_producto float precio } DETALLE_PEDIDO { int id_pedido PK, FK int id_producto PK, FK int cantidad }

Los componentes de un ERD son:

  • Entidades: Son los "sustantivos" del negocio. Representan objetos o conceptos del mundo real sobre los que queremos guardar información (ej: `CLIENTE`, `PRODUCTO`, `PEDIDO`). Se convierten en tablas.
  • Atributos: Son las propiedades o características de una entidad (ej: el `nombre` de un cliente, el `precio` de un producto). Se convierten en las columnas de las tablas.
  • Relaciones: Son los "verbos" que conectan a las entidades. Describen cómo interactúan entre sí. Las más comunes son:
    • Uno a Muchos (1:N): Un `CLIENTE` puede realizar muchos `PEDIDOS`.
    • Muchos a Muchos (N:M): Un `PEDIDO` puede contener muchos `PRODUCTOS`, y un `PRODUCTO` puede estar en muchos `PEDIDOS`. Este tipo de relación siempre se resuelve con una tabla intermedia (en nuestro diagrama, `DETALLE_PEDIDO`).

5.2. Los Bloques del Análisis: Hechos y Dimensiones

El modelado dimensional cambia la terminología. En lugar de entidades y relaciones, hablamos de Hechos y Dimensiones. Son los dos únicos tipos de tablas que encontraremos.

Tablas de Hechos (Facts)

Son el corazón del modelo. Contienen las métricas de negocio, los números, lo que queremos medir y agregar. Responden a "¿cuánto?". Son tablas "delgadas" pero muy "largas" (muchas filas).

Tablas de Dimensiones (Dimensions)

Son el alma y el contexto del modelo. Contienen los atributos descriptivos que nos permiten filtrar, agrupar y etiquetar los hechos. Responden a "¿quién, qué, dónde, cuándo, cómo?". Son tablas "anchas" (muchas columnas) pero más "cortas".

5.3. El Protagonista: Esquema de Estrella (Star Schema)

Es el diseño más famoso, rápido y recomendado para la mayoría de los casos de BI. Su estructura es simple y potente: una tabla de hechos en el centro conectada directamente a sus dimensiones, formando una estrella.

graph TD subgraph "Esquema de Estrella" F(Fact_Ventas) -- FK_Tiempo --> D1(Dim_Tiempo) F -- FK_Cliente --> D2(Dim_Cliente) F -- FK_Producto --> D3(Dim_Producto) F -- FK_Vendedor --> D4(Dim_Vendedor) end subgraph "Tabla de Hechos" F["id_tiempo
id_cliente
id_producto
id_vendedor
monto_vendido
cantidad"] end subgraph "Tablas de Dimensiones (Desnormalizadas)" D1["id_tiempo
fecha
mes
año
dia_semana"] D2["id_cliente
nombre_cliente
ciudad
region
pais"] D3["id_producto
nombre_producto
categoria
marca"] D4["id_vendedor
nombre_vendedor
equipo"] end
Analizar el Esquema de Estrella

Concepto Clave: Desnormalización

La magia de la velocidad del modelo estrella reside en que sus tablas de dimensión están intencionadamente desnormalizadas. Nota en el diagrama cómo `Dim_Cliente` contiene `ciudad`, `region` y `pais` en una sola tabla. Esto crea redundancia, pero evita `JOINs` adicionales en las consultas, lo que las hace increíblemente rápidas.

Ventajas

  • Rendimiento Superior: Menos JOINS significan consultas más rápidas.
  • Simplicidad: Muy fácil de entender para los analistas y para las herramientas de BI.
  • Estándar de la Industria: La mayoría de las herramientas están optimizadas para este modelo.

Desventajas

  • Redundancia de Datos: Aumenta el espacio de almacenamiento.
  • Mantenimiento de Dimensiones: Actualizar atributos redundantes puede ser más lento.

Caso de Uso Típico

El punto de partida y el diseño final para la gran mayoría de Data Marts y Data Warehouses departamentales.

5.4. La Familia Dimensional: Copo de Nieve, Galaxia y más

Si bien el modelo Estrella es el rey, existen otras variaciones para resolver problemas específicos. Son como "evoluciones" del modelo estrella.

A. Esquema de Copo de Nieve (Snowflake Schema)

Una extensión del modelo estrella donde las dimensiones se normalizan. Esto crea ramificaciones, como en un copo de nieve.

graph TD F(Fact_Ventas) -- FK_Producto --> D_Prod(Dim_Producto) D_Prod -- FK_Categoria --> D_Cat(Dim_Categoria) D_Cat -- FK_Departamento --> D_Dep(Dim_Departamento)
Analizar el Esquema de Copo de Nieve
  • Ventaja Principal: Elimina la redundancia, ahorra espacio y facilita el mantenimiento de las jerarquías en las dimensiones.
  • Desventaja Principal: Requiere más `JOINs`, lo que degrada el rendimiento de las consultas y aumenta la complejidad del modelo.
  • Caso de Uso Típico: Cuando una o más tablas de dimensión son gigantescas (ej: una tabla de clientes con 50 millones de filas) y la redundancia genera un problema real de almacenamiento.

B. Esquema de Galaxia (Galaxy Schema)

Un modelo que contiene múltiples tablas de hechos que comparten dimensiones comunes, como una galaxia de estrellas.

graph TD F1(Fact_Ventas) --> D1(Dim_Tiempo) F1 --> D2(Dim_Producto) F1 --> D3(Dim_Cliente) F2(Fact_Inventario) --> D1 F2 --> D2 F2 --> D4(Dim_Almacen)
Analizar el Esquema de Galaxia
  • Ventaja Principal: Permite un análisis integrado de diferentes procesos de negocio (ej: comparar ventas vs. inventario) de una forma muy consistente.
  • Desventaja Principal: Puede volverse complejo de gestionar y mantener a medida que crecen el número de hechos y dimensiones.
  • Caso de Uso Típico: En Data Warehouses empresariales donde se necesita una visión 360° del negocio, consolidando métricas de diferentes departamentos.

5.5. Una Filosofía Diferente: El Modelo Data Vault

Data Vault no es solo otro tipo de esquema, es una metodología de modelado distinta. Su objetivo no es la consulta directa, sino la **integración de datos de forma ágil, escalable y auditable**.

graph TD subgraph "Data Vault" H1(Hub_Cliente) H2(Hub_Producto) L1(Link_Compra) H1 -- "describe al cliente" --> S1(Sat_Cliente_Detalles) H2 -- "describe al producto" --> S2(Sat_Producto_Info) L1 -- "describe la compra" --> S3(Sat_Compra_Transaccion) H1 -- "realiza" --> L1 H2 -- "es parte de" --> L1 end
Analizar el Modelo Data Vault

Componentes Principales

  • Hubs (Nodos): Contienen las claves de negocio únicas e inmutables (ej: DNI del cliente, SKU del producto). Son el ancla del modelo.
  • Links (Relaciones): Definen la relación o transacción entre dos o más Hubs. No contienen atributos, solo las claves.
  • Satellites (Satélites): Contienen todos los atributos descriptivos y temporales de los Hubs y Links. Guardan un historial completo de cambios, lo que es excelente para la auditoría.

Ventajas

Es extremadamente flexible para añadir nuevas fuentes de datos sin reestructurar el modelo existente. Proporciona una trazabilidad y auditoría perfectas.

Desventajas

El número de tablas es muy alto y las consultas directas son muy complejas. No está diseñado para el análisis por parte del usuario final.

Caso de Uso Típico

Como la capa de integración central ("Core Data Warehouse") en grandes empresas. A partir del Data Vault, se construyen Data Marts con esquemas de estrella para que los usuarios puedan explotar los datos fácilmente.

Módulo 4: Taller y Optimización Avanzada

¡Manos a la obra! Aplicaremos todo lo aprendido en un taller práctico y descubriremos los secretos para que nuestras consultas vuelen.

4.1. Taller Avanzado de Análisis

Usa la base de datos `taller_seguridad.db` para resolver estos retos. ¡Algunos requieren las técnicas avanzadas que acabamos de ver!

Script de Configuración en Python (Ejecutar primero)

# Este código prepara la base de datos para el taller.
import pandas as pd
import requests
import sqlite3

# Cargar datos de secuestros
api_url = "https://www.datos.gov.co/resource/886s-p2i3.json?$limit=10000"
response = requests.get(api_url)
data = response.json()
df_secuestros = pd.DataFrame(data)
df_secuestros['cantidad'] = pd.to_numeric(df_secuestros['cantidad'], errors='coerce').fillna(0).astype(int)
df_secuestros['año'] = pd.to_datetime(df_secuestros['fecha_hecho'], errors='coerce').dt.year
df_secuestros.dropna(subset=['departamento', 'año'], inplace=True)
df_secuestros['año'] = df_secuestros['año'].astype(int)

# Datos de población (ejemplo)
poblacion_data = {
    'nombre_depto': ['ANTIOQUIA', 'CUNDINAMARCA', 'VALLE DEL CAUCA', 'ATLÁNTICO', 'BOGOTÁ, D.C.', 'SANTANDER', 'BOLÍVAR'],
    'poblacion': [6677930, 3242996, 4532152, 2722128, 7743955, 2280908, 2180976]
}
df_poblacion = pd.DataFrame(poblacion_data)

# Crear y poblar la base de datos
conn = sqlite3.connect('taller_seguridad.db')
df_secuestros.to_sql('secuestros', conn, index=False, if_exists='replace')
df_poblacion.to_sql('poblacion_deptos', conn, index=False, if_exists='replace')
conn.close()

print("Base de datos 'taller_seguridad.db' lista para el taller.")
                            
Reto 4: Departamento con mayor crecimiento de secuestros entre 2020 y 2021

-- Solución con Funciones de Ventana
WITH CasosAnuales AS (
    SELECT
        departamento,
        año,
        SUM(cantidad) as total_anual
    FROM
        secuestros
    WHERE año IN (2020, 2021)
    GROUP BY departamento, año
)
SELECT
    departamento,
    total_anual - LAG(total_anual, 1, 0) OVER (PARTITION BY departamento ORDER BY año) AS crecimiento
FROM CasosAnuales
WHERE año = 2021
ORDER BY crecimiento DESC
LIMIT 1;
                                 
Reto 5: Ranking de departamentos por tasa de secuestros dentro de su región

-- Solución
WITH TasaDepartamental AS (
    SELECT
        s.departamento,
        p.region,
        (CAST(SUM(s.cantidad) AS REAL) / p.poblacion) * 100000 AS tasa_por_100k
    FROM
        secuestros s
    JOIN
        poblacion_deptos p ON s.departamento = p.nombre_depto
    GROUP BY s.departamento, p.region, p.poblacion
)
SELECT
    departamento,
    region,
    tasa_por_100k,
    RANK() OVER (PARTITION BY region ORDER BY tasa_por_100k DESC) as ranking_regional
FROM TasaDepartamental;
                                 

4.2. Optimización: Entendiendo al Gestor de Consultas

Cuando envías una consulta, el SGBD no la ejecuta ciegamente. Primero, crea un Plan de Ejecución, que es el "mapa" de la forma más eficiente de obtener los datos. Entender estos planes es clave para la optimización.

  • Planes de Ejecución: Usando comandos como `EXPLAIN QUERY PLAN` en SQLite, puedes ver si la base de datos está usando un "Full Table Scan" (lento) o un "Search using index" (rápido).
  • Índices Clustered vs. Non-Clustered:
    • Un índice Clustered ordena físicamente los datos en el disco según la columna del índice. Solo puede haber uno por tabla (generalmente la Clave Primaria).
    • Un índice Non-Clustered es una estructura separada que apunta a los datos. Puede haber muchos por tabla.