La lección anterior terminó con una decisión escrita: las reservas y los vuelos de Contoso Airlines van a Azure SQL Database, porque una plaza no puede venderse dos veces y eso exige transacciones ACID e integridad referencial de verdad. Hoy se ejecuta esa decisión. Al final existirán el servidor lógico sql-contoso-reservas-pro y la base de datos db-reservas, con su esquema, sus índices, su autenticación con Microsoft Entra ID y su punto de conexión privado pe-sql-reservas dentro de snet-datos, cerrando el hueco que el módulo 2 dejó dibujado pero vacío. Es el servicio relacional más maduro de Azure y el que más decisiones obliga a tomar —modelo de compra, nivel, redundancia, autenticación y red—, así que las veremos con el criterio de cuándo elegir cada cosa.
Aviso de coste importante: una base De uso general con 2 vCore ronda los 370 € al mes y factura las 24 horas: no existe el estado "detenida" de una máquina virtual. La única forma de dejar de pagar cómputo es el nivel sin servidor con pausa automática o eliminar la base. Crítico para la empresa multiplica el precio por tres. Para practicar, usa el nivel sin servidor en
rg-contoso-reservas-devy elimina el grupo de recursos al terminar.
Contenido
- Qué es, y por qué el servidor no es una máquina
- Modelos de compra y niveles de servicio
- Sin servidor, pausa automática y grupos elásticos
- Despliegue completo con Azure CLI
- Autenticación con Microsoft Entra ID
- Punto de conexión privado y cierre del acceso público
- El esquema de reservas y sus índices
- Copias de seguridad y restauración a un momento dado
- Alta disponibilidad, réplicas de lectura y conmutación por error
- Seguridad del dato: cifrado, enmascaramiento y auditoría
- Rendimiento, escalado en caliente y control del gasto
- Errores Comunes y Consejos
- Ejercicios
- Conclusión
- Qué es, y por qué el servidor no es una máquina
Azure SQL Database es el motor de SQL Server ofrecido como plataforma gestionada, con una diferencia conceptual importante: no hay una instancia de SQL Server que sea tuya. Hay una base de datos con su propio cómputo, sus copias y su ciclo de vida.
| Aspecto | Azure SQL Database | SQL Managed Instance | SQL Server en VM |
|---|---|---|---|
| Modelo | PaaS, base aislada | PaaS, instancia completa | IaaS |
| Compatibilidad con SQL Server local | Alta, con excepciones | Casi total | Total |
| SQL Agent y consultas entre bases | No | Sí | Sí |
| Sistema operativo, parches y copias | No accesible; automáticos | No accesible; automáticos | Tuyos por completo |
| Despliegue en red virtual | Punto de conexión privado | Nativo, subred delegada | Nativo |
| Coste de entrada | Bajo | Alto (cientos al mes) | Medio, más el trabajo |
| Elígelo para | Aplicaciones nuevas o modernizadas | Migraciones "tal cual" | Requisitos que impiden PaaS |
Contoso elige Azure SQL Database porque db-reservas es un esquema nuevo: no arrastra trabajos del Agente SQL ni consultas entre bases, así que Managed Instance sería pagar compatibilidad que nadie usará. Y aquí está el punto donde casi todos se equivocan: sql-contoso-reservas-pro no es una máquina. Es un servidor lógico, un contenedor administrativo sin CPU ni memoria por el que no se paga nada. En él viven el nombre DNS <nombre>.database.windows.net, los administradores de SQL y de Microsoft Entra ID, las reglas de firewall de servidor, la configuración de red (acceso público, TLS mínimo, puntos de conexión privados) y las directivas de auditoría heredables. En cada base de datos viven el nivel de servicio y su coste, el esquema y los datos, sus usuarios, la retención y redundancia de copias y el enmascaramiento dinámico. Consecuencia práctica: dos bases del mismo servidor pueden costar cosas muy distintas, pero comparten DNS, firewall y administradores; por eso Contoso separa servidores por entorno en lugar de mezclar producción y desarrollo.
- Modelos de compra y niveles de servicio
| DTU | vCore | |
|---|---|---|
| Qué compras | Mezcla opaca de CPU, memoria y E/S | vCores, memoria y almacenamiento por separado, con escalado independiente |
| Transparencia | Baja: no sabes cuánta CPU tienes | Alta: sabes exactamente qué pagas |
| Azure Hybrid Benefit | No aplicable | Sí, hasta un 55 % de ahorro |
| Sin servidor e Hiperescala | No | Sí |
| Recomendado para | Bases pequeñas y estables | Todo lo demás; es el modelo actual de Microsoft |
Contoso elige vCore: necesita el nivel sin servidor para desarrollo y quiere aplicar Azure Hybrid Benefit con sus licencias de SQL Server, algo que se detalla en la lección 08-03. Dentro de vCore hay tres niveles, cuyos nombres describen su arquitectura interna mejor de lo que parece (en DTU los equivalentes son Básico, Estándar y Premium, con el mismo orden de precio):
| Nivel | Arquitectura | Latencia de E/S | Tamaño máximo | Cuándo elegirlo |
|---|---|---|---|---|
| De uso general | Cómputo y almacenamiento separados (remoto) | 5-10 ms | 4 TB | El 80 % de las cargas; mejor relación precio/rendimiento |
| Crítico para la empresa | SSD local, clúster de 4 nodos | 1-2 ms | 4 TB | Latencia muy baja; incluye réplica de lectura gratuita |
| Hiperescala | Almacenamiento distribuido en capas | Variable | 100 TB | Bases enormes o de crecimiento sin techo previsible |
Decisión de Contoso: De uso general, 2 vCore, con redundancia de zona en producción. El volumen es de 40 GB creciendo 12 GB al año, muy lejos del techo, y 5-10 ms de latencia son irrelevantes dentro de una petición HTTP de 200 ms. Crítico para la empresa triplicaría el coste para resolver un problema que no existe.
- Sin servidor, pausa automática y grupos elásticos
El nivel sin servidor (en De uso general e Hiperescala) define un rango mínimo y máximo de vCores, escala dentro de él y factura por segundo consumido. Si la base pasa un tiempo configurable sin conexiones, se pausa y deja de facturar cómputo. Cuatro matices imprescindibles:
- El almacenamiento se paga siempre, esté pausada o no; lo que desaparece es la partida dominante.
- La primera conexión tras la pausa tarda entre 30 y 60 segundos y falla si el cliente no reintenta. La aplicación necesita reintentos con espera exponencial, algo obligatorio en la nube de todos modos.
- El retraso mínimo de pausa es de 60 minutos: sirve entre jornadas, no entre peticiones.
- A plena ocupación resulta más caro que el aprovisionado. Es para carga intermitente.
Un grupo elástico es la otra herramienta de ahorro: un conjunto de vCores compartido por muchas bases cuyos picos no coinciden. Contoso lo tiene previsto para un escenario concreto: si cada agencia asociada acaba teniendo su base aislada —unas 40 bases pequeñas, esporádicas y en husos horarios distintos—, el grupo costaría una fracción de 40 bases aprovisionadas. Regla: muchas bases pequeñas con picos no simultáneos.
- Despliegue completo con Azure CLI
Primero el servidor lógico, recordando que no crea ninguna máquina ni genera coste por sí mismo. La contraseña nunca se escribe en el script: se pide por teclado o se lee de Key Vault (04-03).
RG="rg-contoso-reservas-pro"; UBICACION="westeurope"; BD="db-reservas"
SERVIDOR="sql-contoso-reservas-pro" # unico en todo Azure: forma el nombre DNS
read -s -p "Contrasena del administrador de SQL: " ADMIN_PWD; echo
az sql server create --name $SERVIDOR --resource-group $RG --location $UBICACION \
--admin-user adminreservas --admin-password "$ADMIN_PWD" \
--minimal-tls-version 1.2 \ # rechaza conexiones con TLS antiguo
--enable-public-network false \ # acceso publico cerrado DESDE EL PRINCIPIO
--tags entorno=produccion proyecto=contoso-reservas centro-coste=CC-1042 [email protected]Dos detalles separan un despliegue correcto de uno que habrá que arreglar: cerrar el acceso público antes de que exista ningún dato —abrir lo justo después es mucho más fácil que cerrar lo que ya funcionaba— y poner las cuatro etiquetas obligatorias desde el minuto cero, porque sin centro-coste no se puede repartir la factura en el módulo 8.
# PRODUCCION: carga sostenida 24x7, capacidad fija y redundancia de zona
az sql db create -g $RG -s $SERVIDOR -n $BD \
--edition GeneralPurpose --family Gen5 --capacity 2 --compute-model Provisioned \
--zone-redundant true --backup-storage-redundancy Zone --max-size 128GB \
--tags entorno=produccion proyecto=contoso-reservas centro-coste=CC-1042 [email protected]
# DESARROLLO: sin servidor, con pausa automatica
az sql db create -g rg-contoso-reservas-dev -s sql-contoso-reservas-dev -n db-reservas \
--edition GeneralPurpose --family Gen5 \
--compute-model Serverless \ # facturacion por segundo de uso
--min-capacity 0.5 --capacity 2 \ # medio vCore en reposo, techo de 2 en los picos
--auto-pause-delay 60 \ # se pausa tras 60 min sin conexiones
--backup-storage-redundancy Local \ # LRS: en desarrollo no se paga geo
--tags entorno=desarrollo proyecto=contoso-reservas centro-coste=CC-1042 [email protected]
# Con --auto-pause-delay -1 se desactiva la pausa (p. ej. si hay pruebas nocturnas)
- Autenticación con Microsoft Entra ID
El usuario y contraseña de administrador es un mal mecanismo permanente: secreto compartido, sin caducidad, sin MFA y, si se filtra, abre la base entera. La alternativa es designar un administrador de Microsoft Entra ID:
GRUPO_ID=$(az ad group show --group "Contoso-DBA-Reservas" --query id -o tsv)
az sql server ad-admin create -g $RG --server $SERVIDOR \
--display-name "Contoso-DBA-Reservas" --object-id $GRUPO_ID
az sql server ad-only-auth enable -g $RG --name $SERVIDOR # desactiva la autenticacion localSe asigna un grupo y no a Marta Ríos directamente porque las personas cambian de puesto y los grupos no. Con ad-only-auth enable, el usuario y contraseña dejan de funcionar y toda la autenticación pasa por Entra ID, con su MFA y su acceso condicional. La aplicación de App Service se conectará con su identidad administrada, sin ninguna contraseña en la cadena de conexión: se monta en la lección 04-02, y los secretos restantes se centralizan en Key Vault (04-03).
- Punto de conexión privado y cierre del acceso público
Con el acceso público deshabilitado, la base solo es accesible desde la red. Se crea pe-sql-reservas en snet-datos (10.20.3.0/24) y, con él, la resolución de nombres: la aplicación seguirá pidiendo sql-contoso-reservas-pro.database.windows.net y ese nombre debe resolver a la IP privada.
SQL_ID=$(az sql server show -g $RG -n $SERVIDOR --query id -o tsv)
ZONA="privatelink.database.windows.net"
az network private-endpoint create --name pe-sql-reservas \
--resource-group rg-contoso-red-pro --location $UBICACION \
--vnet-name vnet-contoso-pro --subnet snet-datos \
--private-connection-resource-id $SQL_ID \
--group-id sqlServer \ # subrecurso: el motor SQL
--connection-name conexion-sql-reservas
az network private-dns zone create -g rg-contoso-red-pro -n "$ZONA"
az network private-dns link vnet create -g rg-contoso-red-pro -n enlace-vnet-pro \
-z "$ZONA" -v vnet-contoso-pro --registration-enabled false
# Registra automaticamente el registro A del punto de conexion en la zona
az network private-endpoint dns-zone-group create -g rg-contoso-red-pro \
--endpoint-name pe-sql-reservas -n grupo-zonas-sql -z "$ZONA" --zone-name sqlResultado: desde snet-app, el nombre de siempre resuelve a una dirección 10.20.3.x. Desde internet no resuelve a nada útil y, aunque alguien conociera la IP, el firewall rechazaría la conexión. Para administrar desde fuera hay tres caminos y solo dos son recomendables: la VPN de punto a sitio (02-06), una VM de gestión en snet-gestion a través de Bastion, o una regla de firewall temporal con tu IP, que es la opción que acaba olvidándose abierta durante meses.
- El esquema de reservas y sus índices
CREATE TABLE dbo.Vuelos (
VueloId INT IDENTITY(1,1) PRIMARY KEY,
Numero CHAR(6) NOT NULL, -- 'CT1042'
Origen CHAR(3) NOT NULL, -- codigo IATA: 'BCN'
Destino CHAR(3) NOT NULL,
SalidaUtc DATETIME2(0) NOT NULL,
PlazasTotales SMALLINT NOT NULL,
PlazasLibres SMALLINT NOT NULL,
CONSTRAINT CK_Vuelos_Plazas CHECK (PlazasLibres BETWEEN 0 AND PlazasTotales)
);
CREATE TABLE dbo.Pasajeros (
PasajeroId INT IDENTITY(1,1) PRIMARY KEY,
Nombre NVARCHAR(80) NOT NULL,
Apellidos NVARCHAR(120) NOT NULL,
Correo NVARCHAR(200) NOT NULL UNIQUE,
TarjetaFidelidad CHAR(16) NULL -- dato sensible: se enmascara
);
CREATE TABLE dbo.Reservas (
ReservaId INT IDENTITY(1,1) PRIMARY KEY,
Localizador CHAR(6) NOT NULL UNIQUE, -- 'X7K2QP'
VueloId INT NOT NULL REFERENCES dbo.Vuelos(VueloId),
PasajeroId INT NOT NULL REFERENCES dbo.Pasajeros(PasajeroId),
CreadaUtc DATETIME2(0) NOT NULL DEFAULT SYSUTCDATETIME(),
Estado VARCHAR(12) NOT NULL, -- 'confirmada', 'anulada'
ImporteEur DECIMAL(9,2) NOT NULL
);
-- Consulta mas frecuente de la web: vuelos de una ruta en una fecha
CREATE INDEX IX_Vuelos_Ruta_Salida ON dbo.Vuelos (Origen, Destino, SalidaUtc)
INCLUDE (Numero, PlazasLibres);
-- Panel de operaciones: reservas de un vuelo por estado
CREATE INDEX IX_Reservas_Vuelo_Estado ON dbo.Reservas (VueloId, Estado)
INCLUDE (Localizador, PasajeroId); -- por localizador no hace falta: UNIQUE ya indexaLa restricción CHECK sobre PlazasLibres es la red de seguridad que ninguna aplicación puede saltarse: aunque el código tenga un error de concurrencia, el motor impedirá que las plazas bajen de cero, que es justo la garantía por la que se eligió una base relacional. El orden de las columnas del índice no es decorativo: el motor puede usar IX_Vuelos_Ruta_Salida filtrando por Origen, por Origen + Destino o por los tres, pero no para buscar solo por SalidaUtc. El INCLUDE añade las columnas que la consulta devuelve sin que formen parte de la clave, de modo que se resuelve sin volver a la tabla: es un índice de cobertura. Y el aviso contrario, que siempre se olvida: cada índice se paga en espacio y en velocidad de escritura. Tres índices bien elegidos cubren el 95 % de la carga; quince degradan la venta de billetes.
- Copias de seguridad y restauración a un momento dado
Azure SQL Database copia automáticamente y sin configuración: completas semanales, diferenciales cada 12-24 horas y del registro de transacciones cada 5-10 minutos. De ahí sale poder restaurar a cualquier instante del periodo de retención. Hay dos retenciones: la de corto plazo, de 1 a 35 días (7 por defecto), que cubre los errores operativos, y la de largo plazo, de hasta 10 años en copias semanales, mensuales y anuales, para obligaciones legales y auditoría.
az sql db str-policy set -g $RG -s $SERVIDOR -n $BD --retention-days 35 --diffbackup-hours 12
# Copia anual conservada 7 anos por normativa fiscal
az sql db ltr-policy set -g $RG -s $SERVIDOR -n $BD \
--weekly-retention P4W --monthly-retention P12M --yearly-retention P7Y --week-of-year 1El martes por la tarde. Diego Salas ejecuta a las 16:40 un script que debía actualizar 300 reservas antiguas y, por un WHERE mal copiado, marca como anulada toda la tabla. A las 16:52 empiezan las llamadas de atención al cliente. La respuesta correcta no es reparar los datos a mano:
az sql db restore -g $RG -s $SERVIDOR --name db-reservas \
--dest-name db-reservas-restaurada \
--time "2026-08-11T16:38:00Z" # SIEMPRE en UTC, justo ANTES del errorTres cosas que hay que grabar: la restauración crea siempre una base nueva y nunca sobrescribe la original, lo que permite comparar antes de decidir; la hora es UTC, y en agosto España va dos horas por delante, así que equivocarse aquí es restaurar a un punto inútil; y la base restaurada también factura, así que se recuperan las filas, se intercambian nombres y se elimina el mismo día.
La restauración geográfica es distinta: usa las copias replicadas a North Europe y sirve cuando toda West Europe está caída. Su objetivo de punto de recuperación llega a una hora, así que puede perder los últimos minutos, y exige haber elegido redundancia de copias Geo o GeoZone al crear la base.
- Alta disponibilidad, réplicas de lectura y conmutación por error
Dentro de la región, la alta disponibilidad viene incluida: con --zone-redundant true el cómputo tiene réplicas en varias zonas y el SLA es del 99,99 %. Crítico para la empresa añade un clúster de cuatro nodos y una réplica de lectura gratuita, accesible con ApplicationIntent=ReadOnly en la cadena de conexión: la forma limpia de que los informes del panel de operaciones no compitan con la venta. Entre regiones se usa un grupo de conmutación por error, que replica la base y aporta un nombre DNS estable que siempre apunta al primario:
az sql failover-group create --name fg-contoso-reservas -g $RG --server $SERVIDOR \
--partner-server sql-contoso-reservas-nor --partner-resource-group $RG \
--add-db $BD --failover-policy Automatic --grace-period 1La aplicación se conecta a fg-contoso-reservas.database.windows.net sin saber qué región está activa. Coherentemente con la decisión de coste del módulo 1, no es activo-activo: North Europe solo sirve lecturas y asciende si West Europe cae. Aun así duplica el coste de cómputo, porque la réplica es una base completa que factura; Contoso lo valorará con el resto del plan de continuidad en la lección 07-05.
- Seguridad del dato: cifrado, enmascaramiento y auditoría
Cuatro capas complementarias, de menor a mayor esfuerzo:
- Cifrado de datos transparente (TDE): cifra ficheros de datos y copias en reposo. Activado por defecto. Protege del robo del medio físico, no de un usuario con permisos.
- Always Encrypted: cifra columnas concretas en el cliente, con una clave que el motor no tiene; ni un administrador puede leerlas. El precio es alto: sobre una columna con cifrado aleatorio no se puede filtrar ni ordenar en el servidor. Contoso lo reserva para los datos de pago, con la clave en Key Vault (04-03).
- Enmascaramiento dinámico de datos: no cifra; oculta el valor en el resultado según quién consulta.
- Auditoría: registra quién ejecutó qué y cuándo, con destino a Log Analytics (módulo 7).
-- El personal de tierra vera 'XXXX-XXXX-XXXX-4417' en lugar del numero completo
ALTER TABLE dbo.Pasajeros ALTER COLUMN TarjetaFidelidad
ADD MASKED WITH (FUNCTION = 'partial(0, "XXXX-XXXX-XXXX-", 4)');
ALTER TABLE dbo.Pasajeros ALTER COLUMN Correo
ADD MASKED WITH (FUNCTION = 'email()'); -- m***@ejemplo.comEl enmascaramiento no aplica a administradores ni a quien tenga concedido UNMASK, y no sustituye a los permisos: si alguien no debe ver una columna, lo correcto es no darle acceso a ella. La auditoría se activa con az sql server audit-policy update -g $RG -n $SERVIDOR --state Enabled --log-analytics-target-state Enabled --log-analytics-workspace-resource-id $WORKSPACE_ID, enviando cada evento al área de trabajo que se explotará con KQL en la lección 07-02.
- Rendimiento, escalado en caliente y control del gasto
El almacén de consultas está activado por defecto y guarda consultas, planes y estadísticas de ejecución. Es lo que convierte "la web va lenta desde ayer" en un diagnóstico concreto:
SELECT TOP 5 qt.query_sql_text,
SUM(rs.count_executions) AS ejecuciones,
SUM(rs.count_executions * rs.avg_cpu_time)/1000.0 AS cpu_total_ms
FROM sys.query_store_query_text qt
JOIN sys.query_store_query q ON q.query_text_id = qt.query_text_id
JOIN sys.query_store_plan p ON p.query_id = q.query_id
JOIN sys.query_store_runtime_stats rs ON rs.plan_id = p.plan_id
GROUP BY qt.query_sql_text
ORDER BY cpu_total_ms DESC; -- CPU acumulada, no duracion mediaOrdenar por CPU total (ejecuciones × tiempo medio) y no por duración es clave: una consulta de 8 ms lanzada 400.000 veces al día hace mucho más daño que un informe de 4 segundos que se ejecuta una vez. En el portal, Query Performance Insight presenta lo mismo en gráficos y es el primer sitio al que ir ante una queja de lentitud; el ajuste automático puede además crear índices que faltan y revertir planes que empeoraron. Escalar, por su parte, es un solo comando y se aplica en caliente, con unos segundos de desconexión al final que la aplicación absorbe si reintenta:
az sql db update -g $RG -s $SERVIDOR -n $BD --capacity 4 # campana de verano
az sql db update -g $RG -s $SERVIDOR -n $BD --capacity 2 # vuelta a temporada baja
# Control del gasto: ninguna base de prueba debe quedar facturando
az sql db list -g $RG -s $SERVIDOR --query "[].{n:name, nivel:sku.name, vcores:sku.capacity}" -o table
az sql db delete -g $RG -s $SERVIDOR -n db-reservas-restaurada --yes
az group delete --name rg-contoso-reservas-dev --yes --no-wait # laboratorioEste escalado se automatiza por calendario con Azure Automation (07-04), igual que el perfil apertura-temporada-verano del módulo 2.
Errores Comunes y Consejos
- Creer que el servidor lógico cuesta dinero o que es una máquina. No cuesta nada y no tiene CPU: facturan las bases.
- Restaurar con la hora local. Las marcas de tiempo son UTC; en verano, dos horas de desfase pueden significar recuperar los datos ya destrozados.
- Olvidar la base restaurada. Factura igual que la original. Bórrala el mismo día.
- Dejar activado "Permitir servicios de Azure". No significa "mis servicios": significa cualquier recurso de Azure, incluida la suscripción de un tercero. Con punto de conexión privado no hace falta.
- Poner Crítico para la empresa "por si acaso". Triplica el coste. Súbelo cuando el almacén de consultas demuestre que la E/S es el cuello de botella, y no antes.
- Crear un índice por cada consulta lenta, o confundir enmascaramiento con cifrado. Revisa antes si un índice existente puede cubrir la consulta cambiando el orden de columnas o el
INCLUDE; y recuerda que el enmascaramiento es cosmético: quien es administrador lo ve todo. - Consejo: activa la retención a largo plazo antes de que la exija una auditoría; no se aplica retroactivamente a copias ya caducadas.
- Consejo: implementa siempre reintentos con espera exponencial. En PaaS, las desconexiones breves durante mantenimiento o escalado son normales, no un fallo.
Ejercicios
Ejercicio 1: dimensionar dos entornos
db-reservas en producción tiene 40 GB y 300 transacciones por segundo en hora punta, disponible 24×7; en desarrollo, 2 GB usados de lunes a viernes de 9 a 18 h.
- Elige modelo de compra, nivel y modelo de cómputo para cada entorno, justificando cada decisión.
- ¿Qué redundancia de copias pondrías en cada uno y por qué?
Ejercicio 2: recuperar de un borrado accidental
Un miércoles a las 09:15 hora peninsular (verano), un script elimina 12.000 filas de dbo.Reservas. Se detecta a las 11:30.
- ¿Qué comando ejecutarías y con qué marca de tiempo exacta?
- ¿Por qué no se restaura directamente sobre
db-reservas? - ¿Qué harías después con la base restaurada?
Ejercicio 3: cerrar la superficie de exposición
Auditas sql-contoso-reservas-pro y encuentras: acceso público habilitado, una regla de firewall 0.0.0.0 - 255.255.255.255, la casilla de servicios de Azure activada, autenticación solo por usuario y contraseña, y auditoría desactivada.
- Ordena las correcciones de mayor a menor riesgo.
- Escribe los comandos de las tres primeras.
- ¿Qué hay que verificar antes de deshabilitar el acceso público para no dejar la web sin base de datos?
Soluciones
Solución 1:
- Ambos en vCore, que habilita sin servidor y Azure Hybrid Benefit. Producción: De uso general, 2 vCore Gen5, aprovisionado y con redundancia de zona, porque la carga es sostenida y 24×7 y 300 transacciones por segundo con 5-10 ms de latencia caben holgadamente. Desarrollo: De uso general sin servidor, de 0,5 a 2 vCore con pausa a los 60 minutos, porque se usa unas 45 h de las 168 de la semana: elimina en torno al 70 % de la partida de cómputo sin cambiar la forma de trabajar del equipo.
- Producción,
Zonecomo mínimo, yGeoZonesi se quiere poder hacer restauración geográfica, que es requisito para ella. Desarrollo,Local: los datos son sintéticos y regenerables, así que la redundancia geográfica es gasto puro.
Solución 2:
- Las 09:15 peninsulares de verano son las 07:15 UTC; se toma un margen de seguridad hacia atrás:
az sql db restore -g rg-contoso-reservas-pro -s sql-contoso-reservas-pro \
--name db-reservas --dest-name db-reservas-restaurada --time "2026-08-12T07:13:00Z"- Porque no se puede: la restauración a un momento dado siempre crea una base nueva. Y es una virtud, no una limitación: durante esas dos horas y cuarto se han creado reservas legítimas que se perderían al sustituir la base entera. Lo correcto es extraer de la restaurada solo las filas que ya no existen (
WHERE NOT EXISTSsobreReservaId) e insertarlas en la original conSET IDENTITY_INSERT ON; como en Azure SQL Database no hay consultas entre bases, se hace exportando conbcpo con una canalización de datos. - Eliminarla el mismo día con
az sql db delete, tras verificar los recuentos. Si se olvida, factura cada hora como una base más.
Solución 3:
- Orden por riesgo: (a) la regla
0.0.0.0-255.255.255.255, que expone la base al mundo entero; (b) el acceso público habilitado; (c) la casilla de servicios de Azure, que admite conexiones desde suscripciones ajenas; (d) la autenticación local sin Entra ID ni MFA; (e) la auditoría desactivada, que no abre riesgo pero impide investigar lo ocurrido. - Comandos:
az sql server firewall-rule delete -g $RG -s $SERVIDOR -n AllowAll
az sql server update -g $RG -n $SERVIDOR --enable-public-network false
az sql server firewall-rule delete -g $RG -s $SERVIDOR -n AllowAllWindowsAzureIps- Que
pe-sql-reservasesté aprovisionado y aprobado, que la zonaprivatelink.database.windows.netesté vinculada avnet-contoso-pro, y que la aplicación de App Service tenga activada la integración con la red virtual (02-05); sin eso resolvería el nombre público y perdería la conexión en cuanto se cierre el acceso.
Conclusión
db-reservas ya existe de verdad. Sabes que sql-contoso-reservas-pro es un servidor lógico sin CPU ni coste, que agrupa DNS, firewall y administradores mientras el gasto vive en cada base. Has elegido con criterio entre DTU y vCore y entre De uso general, Crítico para la empresa e Hiperescala, has aplicado el nivel sin servidor con pausa automática al entorno de desarrollo y conoces el escenario de los grupos elásticos. Has desplegado servidor y bases con Azure CLI, con las cuatro etiquetas obligatorias y el acceso público cerrado desde el primer comando, has designado un administrador de Microsoft Entra ID sobre un grupo y activado la autenticación exclusiva de Entra, y has conectado la base a snet-datos mediante pe-sql-reservas y su zona DNS privada, de modo que el nombre de siempre resuelve a una IP 10.20.3.x.
Encima has creado el esquema de vuelos, pasajeros y reservas con una restricción CHECK que impide vender plazas inexistentes y dos índices de cobertura justificados por consultas reales; has recuperado la plataforma de la migración fallida del martes con una restauración a un momento dado en UTC; y has cubierto la restauración geográfica, la alta disponibilidad con redundancia de zona, las réplicas de lectura, el grupo de conmutación por error a North Europe con su nombre DNS estable y su coste duplicado, las cuatro capas de seguridad del dato —TDE, Always Encrypted, enmascaramiento de la tarjeta de fidelización y auditoría—, el almacén de consultas y el escalado en caliente.
Pero el motor relacional no lo resuelve todo. El catálogo de tarifas de Contoso tiene condiciones distintas para cada tipo de billete, cambia de forma cada temporada y se consulta miles de veces por minuto desde la web y desde la API de Disponibilidad, con clientes en toda Europa y América. Normalizarlo significaría veinte tablas y consultas con diez uniones para responder algo tan simple como "dame esta tarifa completa". En la siguiente lección, Azure Cosmos DB, verás el otro extremo del mapa de datos: documentos JSON, distribución global, la clave de partición como la decisión más irreversible del diseño, las unidades de solicitud que miden lo que cuesta cada consulta y cinco niveles de consistencia para elegir, dato a dato, entre exactitud y latencia.
Curso de Azure
Módulo 1: Introducción a Azure
- ¿Qué es Azure?
- Modelos de servicio, regiones y zonas de disponibilidad
- Crear y configurar tu cuenta de Azure
- Recorrido por el portal de Azure
- Azure Resource Manager: suscripciones, grupos de recursos y etiquetas
- Azure CLI, PowerShell y Cloud Shell
Módulo 2: Servicios principales de Azure
- Máquinas virtuales de Azure
- Escalado y alta disponibilidad del cómputo
- Azure App Service
- Azure Storage: blobs, archivos, colas y tablas
- Redes en Azure: redes virtuales, subredes y NSG
- Conectividad híbrida y entrega global
Módulo 3: Bases de datos de Azure
- Elegir el servicio de datos adecuado
- Azure SQL Database
- Azure Cosmos DB
- Azure Database for MySQL
- Azure Database for PostgreSQL
- Analítica de datos: Data Lake, Data Factory y Synapse
Módulo 4: Seguridad en Azure
- Microsoft Entra ID y gestión de identidades
- RBAC e identidades administradas
- Azure Key Vault
- Protección DDoS y firewall de aplicaciones web
- Microsoft Defender for Cloud
- Gobernanza y cumplimiento con Azure Policy
Módulo 5: Azure DevOps
- Introducción a Azure DevOps
- Azure Repos
- Azure Pipelines: integración continua
- Despliegue continuo con entornos y aprobaciones
- Azure Artifacts
- Infraestructura como código con Bicep
Módulo 6: Servicios avanzados de Azure
- Contenedores en Azure: Container Registry y Container Apps
- Azure Kubernetes Service (AKS)
- Azure Functions
- Azure Logic Apps
- Mensajería y eventos: Service Bus, Event Grid y Event Hubs
- Servicios de IA de Azure
Módulo 7: Monitoreo y gestión
- Azure Monitor: métricas, alertas y paneles
- Log Analytics y consultas KQL
- Application Insights
- Azure Automation y runbooks
- Copias de seguridad y recuperación ante desastres
Módulo 8: Gestión y optimización de costos
- Calculadora de precios y estimación de costes
- Azure Cost Management: análisis, presupuestos y alertas
- Reservas, planes de ahorro y Azure Hybrid Benefit
- Azure Advisor
- Estrategias de optimización y cultura FinOps
