Translate

viernes, 6 de febrero de 2026

Seguridad y Mantenimiento de la Base de Datos

La seguridad es uno de los pilares más importantes de la administración de bases de datos.
El objetivo es proteger los datos contra accesos no autorizados, evitar ataques y preservar la integridad de la información.

Autenticación y Autorización (Roles y Permisos)

Autenticación

Proceso de verificar la identidad del usuario que intenta acceder a la base de datos.

Ejemplo:
En PostgreSQL:

CREATE USER app_user WITH PASSWORD 'segura123';

En MySQL:

CREATE USER app_user'@'localhost' IDENTIFIED BY 'segura123';

Buenas prácticas:

  • Usar contraseñas robustas.

  • Implementar autenticación integrada (LDAP, Active Directory, IAM).

  • Evitar el uso de cuentas compartidas.


Autorización

Define qué puede hacer cada usuario dentro del sistema, mediante roles y permisos.

Ejemplo:

CREATE ROLE ventas;

GRANT SELECT, INSERT ON pedidos TO ventas;

GRANT ventas TO app_user;

Principio del mínimo privilegio:
Otorgar solo los permisos estrictamente necesarios.



Tipos de permisos más comunes

Tipo

Descripción

Ejemplo

SELECT

Leer datos

GRANT SELECT ON clientes TO usuario;

INSERT

Agregar registros

GRANT INSERT ON pedidos TO usuario;

UPDATE

Modificar registros

GRANT UPDATE ON productos TO usuario;

DELETE

Eliminar registros

GRANT DELETE ON pedidos TO usuario;

EXECUTE

Ejecutar funciones o procedimientos

GRANT EXECUTE ON sp_backup TO admin;


Inyección SQL: Prevención

La inyección SQL (SQL Injection) es uno de los ataques más frecuentes en aplicaciones conectadas a bases de datos.
Consiste en insertar código SQL malicioso en campos de entrada para manipular consultas.

Ejemplo de ataque:

-- Entrada del usuario

' OR 1=1 --


-- Consulta final vulnerable

SELECT * FROM usuarios WHERE nombre = '' OR 1=1 --' AND clave = '';

Esto devuelve todos los usuarios.


Prevención

  1. Usar consultas parametrizadas o prepared statements.


# Ejemplo en Python con psycopg2

cur.execute("SELECT * FROM usuarios WHERE nombre = %s AND clave = %s", (user, password))

  1. Validar y sanitizar entradas.

    • Aceptar solo tipos esperados (números, fechas, correos, etc.).

    • Rechazar caracteres especiales o comillas innecesarias.

  2. Evitar concatenar strings en consultas.

  3. Restringir permisos del usuario de conexión.

    • Que el usuario de la aplicación tenga solo permisos de lectura/escritura, no de administración.


Cifrado de Datos Sensibles

El cifrado protege la confidencialidad de la información, incluso si el almacenamiento físico es comprometido.

1. Cifrado en Reposo

Protege los datos almacenados en disco (archivos, backups, logs).

Ejemplo:

  • PostgreSQL + pgcrypto:


SELECT pgp_sym_encrypt('123456789', 'claveSecreta');

SELECT pgp_sym_decrypt(columna_cifrada, 'claveSecreta');

  • MySQL:


SELECT AES_ENCRYPT('123456789', 'clave');

SELECT AES_DECRYPT(campo, 'clave');

2. Cifrado en Tránsito

  • Usar SSL/TLS para proteger las conexiones.

  • Configurar los clientes con sslmode=require.

3. Cifrado a nivel de columna o campo

Ideal para datos como contraseñas, documentos, tarjetas o DNIs.

Consejo:

Usar funciones de hash (como bcrypt o SHA-256) para contraseñas, no cifrado reversible.

jueves, 5 de febrero de 2026

Herencia Múltiple en Python


En la mayoría de los lenguajes orientados a objetos, una clase hereda de una sola clase base.

Sin embargo, Python permite herencia múltiple, lo que significa que una clase puede derivar de más de una clase padre.


class A:

    def metodo(self):

        print("Método de A")


class B:

    def metodo(self):

        print("Método de B")


class C(A, B):  # Hereda de A y B

    pass


obj = C()

obj.metodo()


Salida : Método de A


Python resuelve los métodos según el orden de resolución de métodos (MRO, Method Resolution Order).

En este caso, busca primero en A, luego en B, y finalmente en object.


Podemos ver el orden con:

print(C.__mro__)


Que muestra algo como:

(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)



Python permite usar super() para encadenar llamadas a métodos en la jerarquía.


class A:

    def metodo(self):

        print("A.metodo()")

        super().metodo()


class B:

    def metodo(self):

        print("B.metodo()")

        super().metodo()


class C:

    def metodo(self):

        print("C.metodo()")


class D(A, B, C):

    pass


d = D()

d.metodo()


Salida: 

A.metodo()

B.metodo()

C.metodo()


El orden sigue el MRO: D → A → B → C → object.


Una forma muy común de usar herencia múltiple en Python es con mixins: clases pequeñas que agregan comportamiento extra sin ser jerarquías principales.


class LoggerMixin:

    def log(self, mensaje):

        print(f"[LOG]: {mensaje}")


class Worker:

    def trabajar(self):

        print("Trabajando...")


class Empleado(LoggerMixin, Worker):

    def realizar_tarea(self):

        self.log("Iniciando tarea")

        self.trabajar()


e = Empleado()

e.realizar_tarea()


Salida:

[LOG]: Iniciando tarea

Trabajando...


Los mixins son una forma elegante de reutilizar código sin acoplar las clases principales.


Resumiendo:

  • Python permite herencia múltiple.
  • El MRO define el orden en que se buscan los métodos.
  • super() respeta ese orden automáticamente.
  • Los mixins son el uso más común y limpio de la herencia múltiple.



martes, 3 de febrero de 2026

Monitoreo Básico de Recursos de base de datos

 El monitoreo permite detectar cuellos de botella en el sistema físico (CPU, memoria, disco, red).

Una base de datos optimizada a nivel lógico puede seguir rindiendo mal si el servidor está saturado.


🔸 1. CPU

La CPU se usa para procesar consultas, ordenar datos, aplicar filtros, etc.
El síntoma típico de CPU saturada es un aumento de los tiempos de respuesta, especialmente en consultas complejas o con muchas agregaciones.

📘 Herramientas comunes:

  • Linux: top, htop, vmstat

  • Windows: Monitor de rendimiento (Performance Monitor)

  • SGBD: pg_stat_activity (PostgreSQL), SHOW PROCESSLIST (MySQL)

Buenas prácticas:

  • Revisar consultas costosas (EXPLAIN ANALYZE).

  • Evitar funciones o transformaciones innecesarias en las consultas.

  • Ajustar paralelismo (max_parallel_workers_per_gather en PostgreSQL, MAXDOP en SQL Server).


🔸 2. Memoria (RAM)

La memoria es clave para el caché y el procesamiento interno del SGBD.
Si es insuficiente, el motor recurre al disco, lo que degrada notablemente el rendimiento.

📘 Indicadores:

  • Uso de swap → señal de falta de memoria.

  • Alta actividad de disco por lectura de páginas → buffers pequeños.

Buenas prácticas:

  • Aumentar shared_buffers o innodb_buffer_pool_size.

  • Asignar suficiente work_mem para operaciones grandes.

  • Evitar ejecutar demasiadas consultas simultáneamente.


🔸 3. Disco (I/O)

El almacenamiento es el factor más lento en todo el sistema.
Las operaciones de escritura y lectura intensivas pueden ser un cuello de botella.

📘 Herramientas de monitoreo:

  • Linux: iostat, iotop

  • Windows: Resource Monitor

  • PostgreSQL: vistas pg_stat_io, pg_stat_bgwriter

Buenas prácticas:

  • Usar discos SSD o NVMe para reducir latencia.

  • Separar los archivos de datos, logs y backups en discos distintos.

  • Mantener índices actualizados (REINDEX, ANALYZE).


🔸 4. Entrada/Salida de Red

En sistemas distribuidos o aplicaciones web, la latencia de red puede impactar el tiempo total de las consultas.

Recomendaciones:

  • Minimizar el tráfico entre aplicación y base (consultas eficientes).

  • Usar connection pooling (p. ej. PgBouncer o HikariCP).

Monitorear latencias con ping, netstat o herramientas del proveedor cloud.