← SQL EspañolChapter 13 of 13

Mejores Prácticas

## Objetivos de Aprendizaje - Escribir SQL mantenible - Optimizar rendimiento de consultas - Asegurar seguridad de datos - Seguir convenciones de nomenclatura ## Estilo de Código ### Formato ```sql -- Bueno: legible e indentado SELECT e.first_name, e.last_name, d.department_name FROM employees e INNER JOIN departments d ON e.department_id = d.id WHERE e.salary > 50000 ORDER BY e.last_name; -- Malo: todo en una línea SELECT e.first_name,e.last_name,d.department_name FROM employees e INNER JOIN departments d ON e.department_id=d.id WHERE e.salary>50000 ORDER BY e.last_name; ``` ### Capitalización ```sql -- Palabras clave en mayúsculas, nombres en minúsculas SELECT first_name, last_name FROM employees WHERE department = 'Sales'; -- También aceptable: todo en minúsculas select first_name, last_name from employees where department = 'Sales'; ``` ## Convenciones de Nomenclatura ### Tablas ```sql -- Singulares, minúsculas con guiones bajos CREATE TABLE employee; -- Malo CREATE TABLE employees; -- Aceptable CREATE TABLE employee_record; -- Bueno CREATE TABLE person; -- Bueno (singular) ``` ### Columnas ```sql -- Descriptivas, minúsculas con guiones bajos first_name -- Bueno last_name -- Bueno date_of_birth -- Bueno emp_id -- Aceptable ``` ### Restricciones ```sql -- Nomenclatura consistente pk_employees -- Primary key fk_employees_department -- Foreign key uq_employees_email -- Unique constraint chk_employees_salary -- Check constraint ``` ### Alias ```sql -- Significativos o estándar SELECT e.first_name, d.department_name FROM employees e JOIN departments d ON e.department_id = d.id; -- Usar 'as' para claridad SELECT first_name AS "First Name" ``` ## Optimización de Consultas ### Usar Índices Apropiados ```sql -- Índice en columnas frecuentemente filtradas CREATE INDEX idx_employees_department ON employees(department); CREATE INDEX idx_employees_salary ON employees(salary); ``` ### Evitar SELECT * ```sql -- Malo: recupera columnas innecesarias SELECT * FROM employees; -- Bueno: solo columnas necesarias SELECT first_name, last_name, email FROM employees; ``` ### Usar EXISTS sobre COUNT ```sql -- Más rápido: se detiene en la primera coincidencia WHERE EXISTS (SELECT 1 FROM orders WHERE employee_id = e.id) -- Más lento: cuenta todos WHERE (SELECT COUNT(*) FROM orders WHERE employee_id = e.id) > 0 ``` ### Evitar Funciones en Columnas Indexadas ```sql -- Malo: no puede usar índice WHERE YEAR(hire_date) = 2020 -- Bueno: puede usar índice WHERE hire_date >= '2020-01-01' AND hire_date < '2021-01-01' ``` ### Usar JOINs Eficientemente ```sql -- Preferir JOIN sobre subconsulta (usualmente) SELECT e.first_name, d.department_name FROM employees e JOIN departments d ON e.department_id = d.id; -- A veces la subconsulta es más clara SELECT * FROM employees WHERE department_id IN (SELECT id FROM departments WHERE location = 'NYC'); ``` ## Seguridad ### Prevenir Inyección SQL ```sql -- Malo: vulnerable a inyección "SELECT * FROM users WHERE name = '" + user_input + "'" -- Bueno: consultas parametrizadas "SELECT * FROM users WHERE name = ?" -- Parámetros: [user_input] ``` ### Limitar Privilegios ```sql -- Usuario de aplicación con acceso limitado GRANT SELECT, INSERT, UPDATE ON employees TO app_user; REVOKE DELETE ON employees FROM app_user; ``` ### Nunca Almacenar Contraseñas en Texto Plano ```sql -- Malo INSERT INTO users (password) VALUES ('secret123'); -- Bueno: almacenar solo hash INSERT INTO users (password_hash) VALUES ('sha256$abc123...'); ``` ## Mantenimiento ### Usar Transacciones ```sql BEGIN; UPDATE accounts SET balance = balance - 1000 WHERE id = 1; UPDATE accounts SET balance = balance + 1000 WHERE id = 2; COMMIT; -- O ROLLBACK si hay error ``` ### Documentar Consultas Complejas ```sql -- Propósito: Encontrar el mejor pagado en cada departamento SELECT department, first_name, salary FROM employees e1 WHERE salary = ( SELECT MAX(salary) FROM employees e2 WHERE e2.department = e1.department ); ``` ### Probar Consultas Destructivas ```sql -- 1. Primero, SELECT para previsualizar SELECT * FROM employees WHERE department = 'Temp'; -- 2. Luego DELETE DELETE FROM employees WHERE department = 'Temp'; ``` ## Diseño de Esquema ### Normalización 1. **1NF**: Valores atómicos, sin grupos repetitivos 2. **2NF**: Sin dependencias parciales (claves compuestas) 3. **3NF**: Sin dependencias transitivas ### Desnormalización A veces intencional por rendimiento: ```sql -- Agregar columna calculada ALTER TABLE orders ADD COLUMN total_amount DECIMAL(10,2) GENERATED ALWAYS AS (quantity * unit_price); ``` ## Manejo de Errores ### Verificar Filas Afectadas ```sql UPDATE employees SET salary = 75000 WHERE employee_id = 999; -- Si 0 filas afectadas, el empleado no existe ``` ### Usar Tipos de Datos Apropiados ```sql -- Para precisión fija (dinero) DECIMAL(10,2) -- Bueno para moneda -- Para valores aproximados FLOAT -- Bueno para datos científicos ``` ## Documentación ### Comentar Tu Código ```sql -- Calcular bonificación basada en antigüedad SELECT first_name, hire_date, CASE WHEN hire_date < '2015-01-01' THEN salary * 0.15 WHEN hire_date < '2020-01-01' THEN salary * 0.10 ELSE salary * 0.05 END AS bonus FROM employees; ``` ## Resumen - Usar formato y nomenclatura consistentes - Escribir SQL legible y bien indentado - Optimizar con índices apropiados - Usar consultas parametrizadas para seguridad - Probar consultas destructivas primero con SELECT - Documentar consultas complejas - Usar transacciones para cambios relacionados - Elegir tipos de datos apropiados

Comments

Comments powered by Giscus

To enable comments, add your Giscus embed code here.

Learn more about Giscus →