Tabla de Contenidos
SQL
Normalización
Metodología para optimizar las bases de datos.
3 formas normales. El ABC de las bases de datos relacionales. Son una serie de reglas que se deben cumplir a la hora de diseñar una base de datos, con sus tablas, campos y relaciones.
Primera forma normal
No se deben repetir datos de una tabla.
Concepto de tabla maestra y tabla de detalle.
Ejemplo de tabla mal hecha:
| id | num_factura | producto | cantidad | precio | fecha | cliente |
|---|---|---|---|---|---|---|
| 1 | 150 | miproducto | 10 | 12 | 2020-01-05 | pepito |
| 2 | 150 | otroproducto | 5 | 3 | 2020-01-05 | pepito |
| 3 | 100 | producto1 | 3 | 1 | 2019-09-03 | pepito |
Podemos ver que se repite el número de factura y el cliente.
La tabla maestra debería ser:
| id_ | num_factura | cliente |
|---|---|---|
| 1 | 150 | 1 |
| 2 | 152 | 1 |
La de detalle:
| id | num_factura |
|---|---|
Segunda forma normal
Cada campo de la tabla debe depender de la clave principal. No podemos incluir campos que dan información de otras tablas.
Por ejemplo, si tenemos una tabla de clientes, no incluiremos campos de productos.
Tercera forma normal
No puede haber datos derivados. Si tenemos una clave foránea en una tabla, no podemos incluir en esa tabla otro campo de la tabla foránea si ellos los podemos obtener a través de dicha clave foránea.
Por ejemplo, si tenemos un campo llamado id_departamento en la tabla clientes, no podría incluir un campo nombre_departamento en esa tabla ya que es un dato que se puede obtener mediante el campo id_departamento cuando buscamos en la tabla de departamentos.
Esta forma normal obliga al uso de JOINS para poder obtener los datos que necesitemos.
Buenas prácticas
Más tablas, menos columnas
Es preferible tener todo más atomizado en diferentes tablas que no pocas tablas llenas de campos.
Más registros, menos columnas
Al separar los datos en varias tablas, cuando crucemos información tendremos más registros, pero no crecerá en campos.
Usar valores por defecto
Muy útil cuando necesitamos que aparezca un valor siempre que no se diga lo contrario.
Usar campos de estado
Con campos de tipo BIT, nos facilitará mucho las consultas a ciertas tablas. Ciertas comprobaciones, en lugar de hacer consultas o desarrollos complejos, podremos resolverlas con filtros sencillos.
Es muy mala práctica borrar registros de tablas maestras, podríamos tener problemas de consistencia por otros datos que de otras tablas que estén relacionadas con ella.
Por ejemplo, teniendo una tabla productos, podríamos tener los siguientes campos:
estado: indica si el producto está habilitado para su uso en el sistema.venta_suspendida: indica si el producto se quitó para la ventacompra_suspendida: indica si el producto se quitó para la compra
Índices en campos significativos
Si las búsquedas se suelen hacer por ciertos campos, es recomendable añadirles índices para acelerarlas.
Si el campo es de tipo BIT, añadir un índice no aporta ninguna mejora.
Tablas resumen
Con el tiempo, se almacenará tal cantidad de datos que afectará al tiempo que tardan las consultas.
Un buena recomendación es crear tablas de resumen. Normalmente se automatiza un proceso mensual para crear una tabla con totales de un determinado periodo y así en búsquedas de ese rango de fechas, se hagan a estas tablas resumen en lugar de la tabla con la información desde el origen de los tiempos.
No es nada recomendable que las tablas crezcan de forma descontrolada.
JOIN
FULL OUTER JOIN
En MySQL no existe este tipo de JOIN, pero se puede emular mediante UNION:
Con dos tablas:
SELECT * FROM t1 LEFT JOIN t2 ON t1.id = t2.id UNION SELECT * FROM t1 RIGHT JOIN t2 ON t1.id = t2.id
Con 3 tablas
SELECT * FROM t1 LEFT JOIN t2 ON t1.id = t2.id LEFT JOIN t3 ON t2.id = t3.id UNION SELECT * FROM t1 RIGHT JOIN t2 ON t1.id = t2.id LEFT JOIN t3 ON t2.id = t3.id UNION SELECT * FROM t1 RIGHT JOIN t2 ON t1.id = t2.id RIGHT JOIN t3 ON t2.id = t3.id
- Why does MySQL report a syntax error on FULL OUTER JOIN? (Stack Overflow)
Ejemplos
Seleccionar los registros de una tabla que no aparezcan en la otra:
SELECT * FROM table1 t1 LEFT JOIN table2 t2 ON t2.id = t1.id WHERE t2.id IS NULL
Convenciones
Tablas
Las tablas se usan para almacenar información en la base de datos.
Se puede poner el nombre en singular o plural.
Vistas
Son como tablas virtuales basadas en el resultado de consultas SQL. Una vista contiene filas y columnas, como una tabla normal.
Cada nombre de vista debería comenzar por vw_: vw_ProductDetails.
Claves primarias
Una clave primaria identifica de forma unívoca cada registro en una tabla
La clave debería comenzar con PK_ e ir seguido del nombre de la tabla: PK_Empleados.
Claves foráneas
Una clave foránea es un campo de una tabla que es clave primaria en otra tabla. El propósito de la clave foránea es asegurar la integridad referencial de los datos.
La clave foránea debería comenzar por FK_ e ir seguido del nombre de la tabla que la contiene y luego el nombre de la tabla donde es clave primaria: FK_Employees_Projects, FK_Students_ContactNumbers, FK_Orders_Details
