1.2. Entorno Cliente / Servidor

 

Tutorial Práctico: Entorno Cliente/Servidor en SQL

1. Conceptos Fundamentales

Arquitectura Cliente/Servidor en Bases de Datos:

text

┌─────────────────┐    Red/TCP-IP    ┌─────────────────┐

│                 │ ◄──────────────► │                 │

│    CLIENTE      │                  │    SERVIDOR     │

│   (Solicita)    │   Consultas SQL  │   (Procesa)     │

│                 │   Resultados     │                 │

└─────────────────┘                  └─────────────────┘

        ↓                                       ↓

  Aplicación Web                           MySQL

  App Móvil                             PostgreSQL

  Consola SQL                           SQL Server


2. Ejemplo 1: Configuración Básica Cliente/Servidor

Paso 1 - En el Servidor (MySQL):

sql

-- 1. Crear usuario para cliente remoto

CREATE USER 'cliente_app'@'%' IDENTIFIED BY 'clave123';


-- 2. Crear base de datos

CREATE DATABASE ventas_online;


-- 3. Otorgar permisos

GRANT ALL PRIVILEGES ON ventas_online.* TO 'cliente_app'@'%';


-- 4. Crear tabla de ejemplo

USE ventas_online;


CREATE TABLE productos (

    id INT PRIMARY KEY AUTO_INCREMENT,

    nombre VARCHAR(100) NOT NULL,

    precio DECIMAL(10,2) NOT NULL,

    stock INT DEFAULT 0

);


INSERT INTO productos (nombre, precio, stock) VALUES

('Laptop Gamer', 1200.00, 15),

('Mouse Inalámbrico', 25.99, 100),

('Teclado Mecánico', 89.99, 30);

Paso 2 - Desde el Cliente (conexión remota):

sql

-- Comando para conectar desde consola:

-- mysql -h 192.168.1.100 -u cliente_app -p ventas_online


-- Una vez conectado, ejecutar consultas:

SELECT * FROM productos WHERE stock > 0;


-- Insertar nuevo producto desde el cliente

INSERT INTO productos (nombre, precio, stock)

VALUES ('Monitor 24"', 199.99, 25);


3. Ejemplo 2: Comunicación Cliente-Servidor Paso a Paso

Secuencia de comunicación:

sql

-- 1. Cliente envía conexión

-- TCP: Connect to 192.168.1.100:3306


-- 2. Autenticación

-- Usuario: cliente_app

-- Password: clave123


-- 3. Cliente envía consulta

SELECT nombre, precio FROM productos ORDER BY precio DESC;


-- 4. Servidor procesa la consulta:

--   - Valida permisos

--   - Analiza sintaxis SQL

--   - Ejecuta en motor de base de datos

--   - Recupera resultados


-- 5. Servidor envía respuesta:

+-------------------+--------+

| nombre            | precio |

+-------------------+--------+

| Laptop Gamer      | 1200.00|

| Monitor 24"       | 199.99 |

| Teclado Mecánico  | 89.99  |

| Mouse Inalámbrico | 25.99  |

+-------------------+--------+


4. Ejemplo 3: Múltiples Clientes Concurrentes

Simulación de dos clientes trabajando simultáneamente:

Cliente A (Aplicación Web):

sql

-- Inicia transacción para compra

START TRANSACTION;


-- Verifica stock

SELECT stock FROM productos WHERE id = 1;

-- Respuesta: 15


-- Actualiza stock (compra de 2 unidades)

UPDATE productos SET stock = stock - 2 WHERE id = 1;

-- Stock ahora: 13

Cliente B (App Móvil) - Mismo tiempo:

sql

-- Consulta disponibilidad

SELECT nombre, stock FROM productos WHERE precio < 100;


-- Respuesta del servidor:

-- Teclado Mecánico: 30

-- Mouse Inalámbrico: 100

-- (Nota: No ve el cambio aún de Cliente A porque no hizo COMMIT)

Cliente A completa la transacción:

sql

-- Registra la venta

INSERT INTO ventas (producto_id, cantidad, fecha)

VALUES (1, 2, NOW());


-- Confirma cambios

COMMIT; -- Ahora Cliente B vería stock = 13


5. Ejemplo 4: Tipos de Clientes Diferentes

Cliente 1: Aplicación Web (PHP/Python)

python

# Ejemplo en Python

import mysql.connector


# Conexión cliente-servidor

conexion = mysql.connector.connect(

    host="192.168.1.100",

    user="cliente_app",

    password="clave123",

    database="ventas_online"

)


# Ejecutar consulta

cursor = conexion.cursor()

cursor.execute("SELECT * FROM productos")

resultados = cursor.fetchall()


# Cerrar conexión (importante!)

cursor.close()

conexion.close()

Cliente 2: Consola SQL (MySQL Workbench)

sql

-- Conexión directa

-- Host: 192.168.1.100

-- Port: 3306

-- Username: cliente_app


-- Consulta con parámetros

SELECT * FROM productos 

WHERE precio BETWEEN 50 AND 200 

ORDER BY nombre;


-- Ejecutar procedimiento almacenado

CALL obtener_productos_populares(10);

Cliente 3: Aplicación Móvil (conexión segura)

java

// Ejemplo Android/Java

// URL de conexión: jdbc:mysql://192.168.1.100:3306/ventas_online

// SSL activado para seguridad


6. Ejemplo 5: Configuración de Red y Puertos

Comandos útiles para diagnóstico:

bash

# Desde el cliente, verificar conectividad

ping 192.168.1.100

telnet 192.168.1.100 3306


# Ver conexiones activas en el servidor (Linux)

netstat -tulpn | grep :3306


# Configuración típica de puertos:

# MySQL: 3306

# PostgreSQL: 5432

# SQL Server: 1433

# Oracle: 1521

Configurar servidor para aceptar conexiones remotas:

En MySQL (my.cnf):

ini

[mysqld]

bind-address = 0.0.0.0  # Aceptar todas las IPs

# o

bind-address = 192.168.1.100  # IP específica

port = 3306

max_connections = 100


7. Ejemplo 6: Transacciones y Concurrencia

sql

-- Cliente A inicia operación bancaria

START TRANSACTION;


-- Transferencia de $100

UPDATE cuentas SET saldo = saldo - 100 WHERE id = 1;

UPDATE cuentas SET saldo = saldo + 100 WHERE id = 2;


-- Mientras tanto, Cliente B consulta saldo

-- Dependiendo del nivel de aislamiento:

-- READ UNCOMMITTED: Vería los cambios inmediatamente

-- READ COMMITTED: No vería cambios hasta COMMIT

-- REPEATABLE READ: Vería datos consistentes


-- Cliente A confirma

COMMIT; -- Ahora todos ven los cambios


8. Ejemplo 7: Pool de Conexiones

Configuración común para optimización:

python

# Ejemplo pool de conexiones en Python

from mysql.connector import pooling


# Crear pool (mantiene conexiones activas)

connection_pool = pooling.MySQLConnectionPool(

    pool_name="mypool",

    pool_size=5,  # 5 conexiones simultáneas

    host="192.168.1.100",

    user="cliente_app",

    password="clave123",

    database="ventas_online"

)


# Cliente obtiene conexión del pool

conexion = connection_pool.get_connection()

# Usa la conexión...

conexion.close()  # Devuelve al pool, no cierra realmente

Ventajas del Pool:

  • Reutiliza conexiones existentes

  • Reduce sobrecarga de abrir/cerrar conexiones

  • Mejora rendimiento en aplicaciones web


9. Ejemplo 8: Seguridad en Comunicación Cliente/Servidor

Conexión segura con SSL:

sql

-- En el servidor, configurar certificados SSL

-- En my.cnf:

[mysqld]

ssl-ca=/etc/mysql/ca.pem

ssl-cert=/etc/mysql/server-cert.pem

ssl-key=/etc/mysql/server-key.pem


-- Desde el cliente, forzar conexión SSL:

mysql --ssl-ca=ca.pem --ssl-cert=client-cert.pem --ssl-key=client-key.pem -h servidor


-- Verificar conexión segura:

SHOW SESSION STATUS LIKE 'Ssl_cipher';

-- Debe mostrar un algoritmo de cifrado


10. Ejercicio Práctico: Sistema de Reservas

Paso 1: Configurar servidor

sql

CREATE DATABASE reservas_hotel;

USE reservas_hotel;


CREATE TABLE habitaciones (

    id INT PRIMARY KEY,

    numero VARCHAR(10),

    tipo VARCHAR(50),

    disponible BOOLEAN DEFAULT TRUE

);


INSERT INTO habitaciones VALUES

(1, '101', 'Individual', TRUE),

(2, '102', 'Doble', TRUE),

(3, '201', 'Suite', TRUE);


CREATE USER 'recepcion'@'%' IDENTIFIED BY 'hotel123';

GRANT SELECT, UPDATE ON reservas_hotel.* TO 'recepcion'@'%';

Paso 2: Simular múltiples clientes

Cliente Recepción:

sql

-- Reservar habitación

START TRANSACTION;

UPDATE habitaciones SET disponible = FALSE WHERE id = 1;

-- No hace COMMIT aún

Cliente Sistema Web:

sql

-- Muestra disponibilidad

SELECT * FROM habitaciones WHERE disponible = TRUE;

-- No ve cambio aún (aislamiento por transacción)

Cliente Recepción confirma:

sql

INSERT INTO reservas (habitacion_id, cliente, fecha) 

VALUES (1, 'Juan Pérez', NOW());

COMMIT;

-- Ahora todos ven habitación 1 como no disponible


11. Monitoreo de Conexiones Cliente/Servidor

sql

-- Ver todas las conexiones activas

SHOW PROCESSLIST;


-- Ver estadísticas de conexiones

SHOW STATUS LIKE 'Threads_connected';

SHOW STATUS LIKE 'Max_used_connections';


-- Ver conexiones por cliente

SELECT user, host, count(*) as conexiones

FROM information_schema.processlist

GROUP BY user, host;


-- Matar conexión problemática

KILL [id_conexion];


Diagrama Resumen:

text

┌─────────────┐          Red          ┌─────────────┐

│   CLIENTE   │      (TCP/IP 3306)    │   SERVIDOR  │

├─────────────┤◄─────────────────────►├─────────────┤

│ Aplicación  │                       │   MySQL     │

│ - Conexión  │     1. Autenticar     │ - Valida    │

│ - Envía SQL │◄─────────────────────►│ - Procesa   │

│ - Recibe    │     2. Ejecuta        │ - Responde  │

│   resultados│     3. Transmite      │             │

└─────────────┘     4. Cierra/Reusa   └─────────────┘


Consejos Prácticos:

  1. Siempre cerrar conexiones cuando termines

  2. Usar pool de conexiones en aplicaciones web

  3. Limitar permisos al mínimo necesario

  4. Monitorear conexiones activas periódicamente

  5. Implementar timeout para conexiones inactivas

  6. Usar SSL para datos sensibles

  7. Documentar IPs/clientes autorizados


Recuerda: En el modelo cliente/servidor, el servidor centraliza la gestión de datos mientras que los clientes se especializan en la presentación e interacción con el usuario.





Comentarios

Entradas más populares de este blog

1-3-¿Qué es SQL?

6-8-Proyecto del Día 1

5-7. MySQL y MySQL Workbench