Artículo

SQL distribuido y NewSQL: la próxima generación de bases de datos

SQL distribuido y NewSQL: la próxima generación de bases de datos

Durante décadas, el mundo de las bases de datos estuvo dividido en dos bandos: **bases de datos relacionales** (PostgreSQL, MySQL) con una fuerte consistencia pero escalabilidad limitada, y **bases de datos NoSQL** (MongoDB, Cassandra) con escalabilidad horizontal pero una consistencia más débil y capacidades de consulta limitadas.

4 min de lecturaIdioma: ES EspañolGratis0 aplausos0 comentarios
TecnologíaArtículos de ingenieríaDistributedDatabasesTechnologyEngineering ArticlesNextNewSQL
Opciones de lectura

Introducción

Durante décadas, el mundo de las bases de datos estuvo dividido en dos bandos: bases de datos relacionales (PostgreSQL, MySQL) con una fuerte consistencia pero escalabilidad limitada, y bases de datos NoSQL (MongoDB, Cassandra) con escalabilidad horizontal pero una consistencia más débil y capacidades de consulta limitadas.

SQL distribuido (también llamado NewSQL) cierra esta brecha. Proporciona todo el poder de SQL (transacciones ACID, uniones, claves externas y herramientas familiares) en una arquitectura distribuida y escalable horizontalmente. El resultado: la coherencia y el poder de consulta de una base de datos relacional con la escalabilidad de NoSQL.


El espectro de la base de datos

Strong Consistency
        ▲
        │           ┌───────────────────────┐
        │           │  Distributed SQL      │
        │           │  (CockroachDB,        │
        │           │   YugabyteDB,         │
        │           │   Google Spanner)     │
        │           └───────────────────────┘
        │
        │    ┌──────────────┐     ┌──────────────────┐
        │    │  Traditional │     │  Traditional      │
        │    │  SQL         │     │  NewSQL           │
        │    │  (PostgreSQL,│     │  (Vitess, TiDB)   │
        │    │   MySQL)     │     │                   │
        │    └──────────────┘     └──────────────────┘
        │
        │                              ┌──────────────────┐
        │                              │  NoSQL           │
        │                              │  (Cassandra,     │
        │                              │   DynamoDB,      │
        │                              │   CosmosDB)      │
        │                              └──────────────────┘
        └────────────────────────────────────────────────────
                              Horizontal Scalability  ──────►

¿Qué es SQL distribuido?

Características principales

Característica Descripción
Interfaz SQL Soporte completo de SQL: JOIN, subconsultas, agregaciones, funciones de ventana
Transacciones ACIDAS Serializable o aislamiento de instantáneas entre nodos
Escala horizontal Agregue nodos sin tiempo de inactividad, los datos se reequilibran automáticamente
fragmentación automática Datos distribuidos automáticamente entre nodos
Replicación Replicación síncrona para mayor durabilidad (RPO=0)
Alta disponibilidad Conmutación por error automática, sin intervención manual
Geodistribución Los datos pueden abarcar varias regiones con una latencia <50 ms

Arquitecturas SQL distribuidas

Google Spanner: el pionero

┌──────────────────────────────────────────┐
│         Spanner Global Architecture       │
├──────────────────────────────────────────┤
│  Zone 1 (us-east1)   Zone 2 (europe-west)│
│  ┌──────────────┐    ┌──────────────┐    │
│  │ Leader Node  │    │ Follower Node│    │
│  │   ┌────────┐ │    │              │    │
│  │   │ Spanner│ │    │              │    │
│  │   │ Server │ │    │              │    │
│  │   └────────┘ │    │              │    │
│  └──────────────┘    └──────────────┘    │
├──────────────────────────────────────────┤
│          TrueTime API (GPS + Atomic)     │
│          Clock synchronization < 7ms     │
└──────────────────────────────────────────┘

Innovación clave: API TrueTime: sincronización de reloj atómico y GPS que proporciona una incertidumbre de reloj limitada. Esto permite la coherencia externa (linealización) entre nodos distribuidos globalmente.

CockroachDB: código abierto inspirado en Spanner

                     ┌─────────────────────────┐
                     │    SQL Gateway          │
                     │  (Any node can serve)   │
                     └──────────┬──────────────┘
                                │
         ┌──────────────────────┼──────────────────────┐
         │                      │                      │
   ┌─────▼─────┐          ┌─────▼─────┐          ┌─────▼─────┐
   │  Node 1   │          │  Node 2   │          │  Node 3   │
   │ ┌───────┐ │          │ ┌───────┐ │          │ ┌───────┐ │
   │ │ Range A│ │          │ │ Range A│ │          │ │ Range A│ │
   │ │ (LEADER)│          │ │(FOLLOWER│          │ │(FOLLOWER│ │
   │ └───────┘ │          │ └───────┘ │          │ └───────┘ │
   │ ┌───────┐ │          │ ┌───────┐ │          │ ┌───────┐ │
   │ │ Range B│ │          │ │ Range B│ │          │ │ Range B│ │
   │ │(FOLLOWER│          │ │ (LEADER)│          │ │(FOLLOWER│ │
   │ └───────┘ │          │ └───────┘ │          │ └───────┘ │
   └───────────┘          └───────────┘          └───────────┘

Cómo funciona CockroachDB:

  1. Los datos se dividen en rangos (64 MB de forma predeterminada, similar a las divisiones de Spanner).
  2. Cada rango se replica 3 veces (configurable) en todos los nodos.
  3. Una réplica es el arrendatario (maneja lecturas y escrituras).
  4. El Consenso de balsa garantiza la coherencia entre las réplicas.
  5. Cualquier nodo puede atender consultas: la puerta de enlace SQL se dirige al rango correcto.

YugabyteDB: compatible con PostgreSQL

YugabyteDB está diseñado para la compatibilidad con PostgreSQL a nivel de protocolo de conexión:

-- This is standard PostgreSQL syntax — it just works
CREATE TABLE orders (
    id UUID DEFAULT gen_random_uuid(),
    customer_id UUID NOT NULL,
    total NUMERIC(10,2) NOT NULL,
    status TEXT NOT NULL DEFAULT 'pending',
    created_at TIMESTAMPTZ DEFAULT NOW(),
    PRIMARY KEY (id)
);

-- Distributed ACID transaction across nodes
BEGIN;
INSERT INTO orders (customer_id, total, status)
VALUES ($1, $2, 'pending');
UPDATE inventory SET quantity = quantity - 1
WHERE product_id = $3 AND quantity > 0;
COMMIT;

-- Full PostgreSQL ecosystem compatibility
-- Supports: pgAdmin, Prisma, DBeaver, all standard drivers

Comparación de SQL distribuido

Característica CucarachaDB YugabyteDB TiDB llave inglesa
Compatibilidad PostgreSQL (85%) PostgreSQL (95%+) mysql propietario
Consistencia Serializable Serializable Aislamiento de instantáneas Consistencia externa
Replicación balsa balsa balsa Paxos
Geodistribución si si si si
fragmentación automática Sí (por rango) Sí (por hash/rango) Sí (por rango) Sí (por división)
Índices secundarios Global (distribuido) Global + Local Global + Local Mundial
Claves externas si si si si
CDC Sí (fregadero Kafka) Sí (Kafka, Elástico) Sí (TiCDC) Sí (Pub/Sub)
Licencia BSL (fuente disponible) apache 2.0 apache 2.0 propietario
Administrado en la nube Nube CucarachaDB YugabyteDB administrado Nube TiDB Llave de nube
Autoanfitrión si si si No

Cuándo utilizar SQL distribuido

Casos de uso ideales

Caso de uso Por qué SQL distribuido Ejemplo
Aplicaciones SaaS globales Los usuarios de todo el mundo necesitan baja latencia y una gran coherencia Cuentas de usuario multirregionales
Sistemas financieros Transacciones ACID entre fragmentos, sin pérdida de datos Procesamiento de pagos, libro mayor
Plataformas de comercio electrónico Inventario, pedidos, carros: todo necesita coherencia Picos de tráfico del Viernes Negro
Juegos Estado del jugador, tablas de clasificación, transacciones. Multijugador entre regiones
Series temporales de IoT + metadatos SQL para análisis de datos distribuidos Telemetría de flota con uniones

Cuándo NO utilizar SQL distribuido

Escenario ¿Por qué? Mejor alternativa
Búsquedas simples de clave-valor Gastos generales de transacciones distribuidas no justificados Redis, DynamoDB
Región única, datos pequeños Complejidad no necesaria PostgreSQL
Búsqueda de texto completo No diseñado para indexación de texto búsqueda elástica
Recorridos de gráficos Las UNIONES en relaciones profundas son lentas neo4j
Rendimiento de escritura muy alto (>100 000 escrituras/seg/nodo) Los gastos generales de consenso pueden ser demasiado altos Casandra, ScyllaDB

Estrategias de distribución de datos

Fragmentación basada en rango (CockroachDB, Spanner)

-- Data is split by primary key ranges
Table: orders

Range 1: PK '00000000' to '3fffffff'  → Node 1 (LEADER) + Node 2, Node 3
Range 2: PK '40000000' to '7fffffff'  → Node 2 (LEADER) + Node 1, Node 3
Range 3: PK '80000000' to 'bfffffff'  → Node 3 (LEADER) + Node 1, Node 2
Range 4: PK 'c0000000' to 'ffffffff'  → Node 1 (LEADER) + Node 2, Node 3

Pros: Escaneos de rango eficientes, buenos para claves secuenciales. Contras: Escribe puntos de acceso si se insertan claves secuenciales (resuelto mediante índices fragmentados).

Fragmentación basada en hash (YugabyteDB)

-- Hash-sharded primary key
CREATE TABLE orders (
    id UUID DEFAULT gen_random_uuid(),
    customer_id UUID,
    total NUMERIC,
    PRIMARY KEY (id HASH)
);

-- Data distribution by hash
Hash('00000000-...') = 0.23 → Tablet 1 → Node 1
Hash('11111111-...') = 0.67 → Tablet 2 → Node 2
Hash('22222222-...') = 0.12 → Tablet 3 → Node 3

Pros: Distribución uniforme de datos, sin puntos calientes. Contras: Los escaneos de rango en toda la mesa son ineficientes.


Funciones clave de SQL distribuido

Transacciones Distribuidas (2PC + Balsa)

-- This transaction spans multiple nodes
BEGIN;
UPDATE account_a SET balance = balance - 100 WHERE id = 'A';
UPDATE account_b SET balance = balance + 100 WHERE id = 'B';  -- Different node
COMMIT;

-- Under the hood:
-- 1. Transaction coordinator (any node) acquires locks
-- 2. Prepares both participants
-- 3. Raft commits the transaction record
-- 4. COMMIT acknowledged to client
-- All-or-nothing — guaranteed ACID

Índices secundarios globales

Los propios índices se distribuyen entre nodos:

CREATE INDEX idx_orders_customer ON orders (customer_id);

-- Query that uses the distributed index:
SELECT * FROM orders WHERE customer_id = $1;
-- 1. Routes to any node
-- 2. Node looks up customer_id in distributed index
-- 3. Index returns primary keys → fetch from correct ranges
-- 4. Returns results

Migraciones de esquemas en línea

SQL distribuido admite cambios de esquema sin tiempo de inactividad:

-- Add a column — non-blocking
ALTER TABLE orders ADD COLUMN discount NUMERIC(5,2) DEFAULT 0.00;

-- Create index — non-blocking (background build)
CREATE INDEX CONCURRENTLY idx_orders_date ON orders (created_at);

Cambiar captura de datos (CDC)

Transmita los cambios de la base de datos a los sistemas posteriores:

-- CockroachDB CDC
CREATE CHANGEFEED FOR TABLE orders, payments
  INTO 'kafka://kafka-cluster:9092'
  WITH updated, resolved, min_checkpoint_frequency = '5s';

-- YugabyteDB CDC connector
# Deploy to Kafka Connect
{
  "name": "yb-cdc-connector",
  "config": {
    "connector.class": "io.yugabyte.cdc.YBChangeDataCaptureConnector",
    "database.hostname": "yb-1.example.com",
    "database.port": "5433",
    "table.include.list": "public.orders"
  }
}

Consideraciones operativas

Topologías de implementación

Región única (3 nodos):

replication:
  factor: 3
  constraints:
    - "+region=us-east-1: 3"
  # All data in one region, 3 copies, survives 2 node failures

Multirregión (fallo de región de supervivencia):

replication:
  factor: 3
  constraints:
    - "+region=us-east-1: 1"
    - "+region=us-west-1: 1"
    - "+region=eu-west-1: 1"
  # One copy in each region, survives any single region failure
  # Write latency: round-trip to the farthest region

Multirregión con quórum cercano (para escrituras de baja latencia):

replication:
  factor: 5
  constraints:
    - "+region=us-east-1: 3"  # 3 copies here
    - "+region=us-west-1: 1"  # 1 copy for DR
    - "+region=eu-west-1: 1"  # 1 copy for DR
  # Write quorum = 3, achievable within us-east-1
  # Write latency = intra-region

Expectativas de latencia

Topología Latencia de escritura (p50) Leer Latencia (p50)
Nodo único 1-5 ms 0,5-2 ms
3 nodos, misma región 5-15 ms 1-5 ms
3 nodos, 3 regiones (EE. UU., UE, APAC) 100-300 ms 5-50 ms (más cercano)
5 nodos, 2 regiones (quorum cerrado) 5-15 ms 1-5 ms

Migración desde PostgreSQL/MySQL

Estrategia: NoSQL a SQL (distribuido)

Phase 1: Evaluate
  - Identify tables that need horizontal scaling
  - Assess which queries cross shards
  - Plan sharding key

Phase 2: Migrate schema
  - Convert CREATE TABLE statements
  - Choose primary key strategy (hash vs. range)
  - Handle sequences (use UUIDs instead of SERIAL)

Phase 3: Migrate data
  - Use CDC or batch export/import
  - Verify consistency
  - Set up replication from old DB

Phase 4: Cut over
  - Point application to new DB
  - Monitor performance
  - Keep old DB as rollback target for 1 week

Problemas comunes de migración

-- PostgreSQL → CockroachDB
-- ❌ Sequences (not distributed)
SERIAL PRIMARY KEY  →  UUID DEFAULT gen_random_uuid()

-- ❌ Array functions not supported
array_agg(DISTINCT x)  →  json_agg(DISTINCT x)  -- workaround

-- ❌ Long-running queries
-- Solution: add index or query hint

-- ❌ Cross-database queries (CockroachDB)
-- Each cluster = one database, no cross-DB queries

Conclusión

SQL distribuido representa la convergencia de dos décadas de evolución de bases de datos, combinando la confiabilidad y expresividad de SQL con la elasticidad y resistencia de los sistemas distribuidos.

Conclusiones clave

  1. Utilice SQL distribuido cuando necesite semántica de SQL pero haya superado un solo nodo.
  2. No apto para implementaciones pequeñas: PostgreSQL con réplicas de lectura es más sencillo y económico.
  3. Elija por compatibilidad: YugabyteDB para PostgreSQL, TiDB para MySQL, CockroachDB para nuevos proyectos.
  4. Planifique la latencia: las transacciones distribuidas tienen gastos generales. Comparar antes de comprometerse.
  5. Supervise cuidadosamente: esté atento a rangos elevados, consultas lentas y retrasos en la replicación.

Marco de decisión

Q: Do you need horizontal write scaling?
  ├─ Yes
  │  Q: Do you need ACID across all data?
  │  ├─ Yes → Distributed SQL (CockroachDB, Spanner)
  │  └─ No  → NoSQL (Cassandra, DynamoDB)
  └─ No
     Q: Do you need SQL features (joins, aggregations)?
     ├─ Yes → PostgreSQL
     └─ No  → Key-value or document store

SQL distribuido es la arquitectura de base de datos para la era global nativa de la nube: aplicaciones que deben funcionar en todas partes, con una gran coherencia y sin concesiones.

Artículos destacados

6 patrones de programación que aprendí de ingenieros senior
EditorialES
5 minGratis

6 patrones de programación que aprendí de ingenieros senior

TecnologíaCodeProgrammingCoding
0 aplausos
Leer
Crea un asistente privado de notas con IA
DestacadoES
9 minGratis

Crea un asistente privado de notas con IA

Convierte notas Markdown en un asistente consultable sin exponer borradores privados.

TecnologíaGuías de plataformaEscritura con IAAIAutomationData
0 aplausos
Leer
Automatiza la extracción de datos de facturas con OCR
EditorialES
8 minGratis

Automatiza la extracción de datos de facturas con OCR

Crea un flujo que lee facturas, extrae campos y marca valores dudosos para revisión.

TecnologíaArtículos de ingenieríaEscritura con IAAIAutomationData
0 aplausos
Leer

Comentarios

0 comentarios

Todavía no hay comentarios aprobados. Las respuestas nuevas pueden esperar moderación.