Consulting, Beratung
Azure SQL für Entwickler – Besonderheiten, Unterschiede zu SQL Server, Lizenzierung, Szenarien, FAQManagement Summary
Azure SQL (PaaS) bietet Softwareentwicklern eine fully-managed SQL-Plattform in der Cloud – mit integrierter Hochverfügbarkeit, automatischen Backups und einfacher Skalierbarkeit. Im Vergleich zu einer selbstverwalteten SQL Server-Instanz entfallen Installationsaufwand und Wartung von Betriebssystem oder Hardware: Sie können innerhalb von Minuten eine Datenbank bereitstellen und sich auf die Entwicklung konzentrieren. Azure SQL steigert die Entwicklerproduktivität durch vertrautes T-SQL und automatisierte Leistungsfeatures, während es zugleich typische Administratoraufgaben wie Patching und Sicherungen übernimmt.
Zur Azure SQL-Produktfamilie gehören Azure SQL Database, Azure SQL Managed Instance (MI) und SQL Server auf Azure-VM (IaaS). Dieser Artikel fokussiert auf die Platform-as-a-Service-Angebote Azure SQL Database und Azure SQL Managed Instance, da diese verwaltete Datenbankdienste mit minimalem Betriebsaufwand darstellen. (SQL Server auf Azure-VM liefert 100% SQL Server-Kompatibilität auf Infrastruktur-Ebene, erfordert aber mehr Eigenbetrieb und ist hier weniger im Fokus.)
Wichtigste Unterschiede zu SQL Server on-premises aus Entwicklersicht:
- Betrieb und Hochverfügbarkeit: Azure SQL ist ein vollständig verwalteter Dienst mit integrierter Hochverfügbarkeit (99,99% SLA) und automatischem Failover – im Gegensatz zu on-premises, wo Sie selbst für Clustering oder Always On sorgen müssen.
- Wartung: Sicherheitsupdates, Upgrades und Patches werden von Microsoft automatisch und ohne Ausfallzeiten eingespielt. On-premises erfordern solche Wartungen manuellen Aufwand und geplante Downtimes.
- Skalierbarkeit: In Azure SQL lassen sich Leistung und Speicher dynamisch skalieren (vertikal per Service-Tier-Wechsel oder horizontal via Read-Replica/Elastic Pools), oft ohne Downtime. On-premises ist Skalierung meist mit Hardwareinvestitionen oder komplexen Architekturen verbunden.
- Eingeschränkte Systemrechte: In PaaS-Umgebungen hat man keinen Zugriff auf das Betriebssystem oder bestimmte Instanzfunktionen (z.B. keine sysadmin auf OS-Ebene, kein direkter Dateizugriff, eingeschränkte Funktionen wie xp_cmdshell). Das reduziert den Wartungsaufwand, bedeutet aber auch, dass manche SQL Server-Features (Agent-Jobs, CLR etc.) nur in Azure Managed Instance oder gar nicht verfügbar sind.
- Feature-Gleichheit: Azure SQL Database und MI basieren auf der aktuellen SQL Server-Engine und unterstützen den Großteil von T-SQL und Datenbankfunktionen. Bestimmte Funktionen (z.B. SQL Server Agent, Cross-DB-Abfragen) unterscheiden sich: MI bietet nahezu volle Kompatibilität zu SQL Server, Single Databases sind stärker isoliert (eine DB pro Server) und erfordern teils alternative Ansätze (z.B. Elastic Jobs anstelle von Agent).
Kosten- und Betriebsimplikationen: Azure SQL nutzt ein flexibles Cloud-Preismodell:
- Leistungsmodelle: vCore-basiert (dedizierte virtuelle CPU-Kerne und Speicher, wahlweise General Purpose oder Business Critical), Serverless (automatische Skalierung der Compute-Leistung nach Bedarf, mit möglicher Auto-Pause bei Inaktivität) und Elastic Pools (gemeinsam genutzte Ressourcen für mehrere Datenbanken). Diese Optionen erlauben eine kostengerechte Auslegung je nach Workload und Nutzungsprofil.
- Azure Hybrid Benefit (AHB): Vorhandene SQL Server-Lizenzen mit Software Assurance lassen sich in Azure anrechnen, um die Kosten zu senken. Dadurch zahlen Sie in der Cloud nur noch für die Infrastrukturkomponenten – das kann ca. 30–40% Preisvorteil bieten. (Hinweis: AHB ist bei vCore-Reservierung nutzbar, jedoch nicht im Serverless-Tarif anwendbar.)
- Reservierte Kapazität: Durch 1- oder 3-Jahres-Reservierungen können bis zu ~33% (für 1J) bzw. ~50+% (für 3J, kombiniert mit AHB sogar bis ~75%) der Compute-Kosten eingespart werden. Das lohnt sich für dauerhafte Produktionsdatenbanken mit kontinuierlicher Last. Reservierungen betreffen vCore-basierte Modelle; Serverless profitiert von Pay-per-Use und pausiert automatisch, jedoch ohne Reservierungsrabatte.
1. Einordnung & Architektur
Azure SQL ist ein Sammelbegriff für verschiedene Betriebsmodelle der SQL Server-Datenbank-Engine in Azure. Je nach Anforderungen können Sie zwischen Einzel-Datenbanken, Pools oder instanzbasierten Diensten wählen, die alle auf der vertrauten SQL Server-Technologie basieren:
- Azure SQL Database (Single Database): Eine isolierte cloudbasierte Datenbank, die von einem logischen SQL-Server in Azure verwaltet wird. Diese Option entspricht einer einzelnen Datenbank als vollwertigem Database-as-a-Service mit eigenem Satz an Ressourcen (Compute, Speicher). Ideal für neue Cloud-Anwendungen – inkl. Unterstützung von Serverless (automatische Compute-Skalierung bis hin zum Pausieren) und Hyperscale (neue Architektur für nahezu unbegrenztes Datenwachstum).
- Azure SQL Database – Elastic Pool: Ein Datenbank-Pool, in dem mehrere Azure SQL-Datenbanken sich einen konfigurierten Ressourcenpool teilen. Dies eignet sich für SaaS-Multi-Tenant-Anwendungen oder Szenarien mit vielen kleineren DBs, deren Lastprofile sich ausgleichen. Alle DBs im Pool residieren auf demselben logischen Server und greifen auf den gemeinsamen vCore- bzw. DTU-Pool zu – so können kostenintensive Leistungsspitzen einzelner DBs abgefedert und ungenutzte Kapazität für andere DBs genutzt werden.
- Azure SQL Managed Instance (MI): Eine vollständig verwaltete SQL-Instanz in Azure, die bis zu mehrere hundert Datenbanken enthalten kann. MI bietet fast die komplette SQL Server-Funktionsvielfalt (nahezu 100% Feature-Parität) einschließlich instanzweiter Funktionen (SQL Agent, verteilte Transaktionen innerhalb der Instanz, CLR usw.), aber als PaaS-Service (automatisierte Updates, integriertes Backup/HA). Jede Managed Instance läuft isoliert in einem eigenen virtuellen Netzwerksegment. MI ist oft die Wahl für Lift-and-Shift von bestehenden On-Premises-Umgebungen, die nur minimale Änderungen vertragen.
- SQL Server auf Azure VM (IaaS): Eine traditionelle SQL Server-Installation auf einer Azure-VM (Windows oder Linux). Dieses Modell bietet vollständige Kontrolle (einschließlich OS-Zugriff) und 100% Kompatibilität, erfordert jedoch, dass Sie das Betriebssystem, SQL-Server-Patching, Hochverfügbarkeitslösungen etc. selbst verwalten. Es wird hier nur der Vollständigkeit halber genannt; Fokus dieses Artikels sind die PaaS-Varianten.
Architektur und zentrale Eigenschaften:
Azure SQL Database (Single und Pool) in den Service-Tiers General Purpose und Hyperscale trennt Compute und Storage: Die Datenbank-Engine läuft auf einem stateless Compute-Knoten, während die Datendateien in einem verteilten Speichersystem (Azure Premium Storage oder bei Hyperscale in gestuften Storage- und Page-Servern) liegen. Dieses Design ermöglicht es, Compute-Ressourcen unabhängig vom Speicher zu skalieren – z.B. vCores erhöhen/verringern, ohne die TB an Daten zu bewegen.
Im Business Critical-Tier (sowohl Single DB als auch MI) nutzt Azure SQL eine Architektur mit Always On-Knoten innerhalb eines Availability Groups-ähnlichen Clusters und schnellem lokaler NVMe-Speicher. Hier sind Compute und Storage enger geknüpft für niedrigste Latenzen. Die Hochverfügbarkeit wird erreicht, indem mehrere synchron replizierte Datenbank-Kopien auf isolierten Knoten gehalten werden (in Business Critical i.d.R. 3-4 Replica innerhalb einer Region, davon 1 aktiv genutzt). Fällt der aktive Knoten aus, übernimmt automatisch ein sekundärer innerhalb von Sekunden. Azure SQL garantiert pro Datenbank eine Verfügbarkeit von 99,99%, und mit optionaler Zonenredundanz (Verteilung der Replica auf Availability Zones) sogar 99,995% in vielen Regionen.
Automatisches Patching & Backups: Sowohl Azure SQL DB als auch MI werden durch Azure automatisch auf dem neuesten Stand gehalten. Sicherheitsupdates und minor Upgrades erfolgen ohne Benutzeraktion. Sie können kein spezifisches Wartungsfenster erzwingen (die meisten Updates sind online und beeinträchtigen den Betrieb kaum); für bestimmte Dienste (z.B. Hyperscale) kann jedoch ein bevorzugtes Wartungszeitfenster konfiguriert werden. Azure fertigt automatisierte Backups an (voll wöchentlich, differenziell i.d.R. alle 12h, Log-Backups alle 5–10 Minuten). Diese Backups werden in raumgetrennten Speichern abgelegt und ermöglichen ein Point-in-Time Restore (PITR) jeder Datenbank innerhalb der Aufbewahrungsdauer (standardmäßig 7 Tage, erweiterbar bis 35 Tage für kurzzeitige Wiederherstellung). Darüber hinaus kann eine Langzeitaufbewahrung (LTR) konfiguriert werden, um Backup-Schnappschüsse bis zu 10 Jahre zu archivieren (wichtig für Compliance). In Azure SQL Database sind diese Backups völlig managed – man kann sie nicht manuell abstellen oder eigene Backup-Skripte ausführen (im PaaS übernimmt Azure dies exklusiv). Bei Managed Instance sind zusätzlich auch vom Benutzer initiierte Copy-Only-Backups nach Azure Blob Storage möglich, falls erforderlich.
Skalierung: Azure SQL erlaubt vertikale Skalierung durch Ändern des Service-Tiers oder der zugewiesenen vCores/DTUs. Dieser Vorgang ist i.d.R. online (kurze Verbindungsneuherstellungen können auftreten, aber in der Regel ohne langen Ausfall). Beispielsweise kann man eine Datenbank von 4 auf 8 vCores hochskalieren, um mehr CPU/RAM bereitzustellen, oder von General Purpose auf Business Critical wechseln, um lokale SSD-Performance zu erhalten. Horizontal skalieren lässt sich Azure SQL Database über Sharding oder featurespezifisch: Hyperscale unterstützt mehrere Named Replicas (lesbare sekundäre Knoten, z.B. für Read-Scale-Out oder analytische Workloads) und kann dank verteilter Architektur sehr große Datenbanken (bis 100 TB) handhaben. Im Business Critical-Tier steht in Single Databases eine kostenlose lesbare sekundäre Replica (Read Scale-Out) innerhalb der Region zur Verfügung – die Anwendung kann mit ApplicationIntent=ReadOnly darauf zugreifen, um Lese-Workloads vom Primärknoten zu entlasten. Elastic Pools sind ebenfalls eine Art horizontale Skalierung über mehrere Datenbanken: Anstatt eine einzelne DB mit immer mehr Ressourcen auszustatten, können Sie mehrere kleinere DBs in einen Pool packen, die Last verteilt sich – ein Ansatz besonders für SaaS mit mandantenspezifischen DBs. Geo-Replikation (aktiv für Azure SQL DB, bzw. Failover-Gruppe für MI) ermöglicht zudem verteilte Architekturen über Regionen hinweg (dazu später mehr in Sicherheit/DR).
Region und Datenresidenz: Bei der Bereitstellung bestimmt Ihr gewählter Azure-Region-Standort, wo die Datenbank physisch gehostet wird. Azure SQL ist in allen gängigen Azure-Regionen verfügbar. Die Standortwahl beeinflusst Latenz (Nähe zu Ihren App-Services oder Nutzern) und möglicherweise Compliance (Datenhaltung im Land). Standardmäßig erfolgt die Hochverfügbarkeits-Replikation innerhalb einer Region (ggf. zonenübergreifend). Für Disaster Recovery über Regionsgrenzen hinaus können Sie sekundäre Replikate in anderen Azure-Regionen einrichten. Azure SQL Database bietet Active Geo-Replication: bis zu 4 asynchrone sekundäre Kopien in beliebigen Regionen, auf die im Read-Only-Modus zugegriffen werden kann. Alternativ oder ergänzend gibt es Auto-Failover-Gruppen, die eine Gruppierung von DBs und automatisches Failover ganzer Gruppen auf einen sekundären Server in einer anderen Region erlauben (mit einem einheitlichen Failover-Endpunkt). Azure MI unterstützt aktuell keine aktive Einzel-Geo-Replication pro DB, aber Failover-Gruppen auf Instanzebene (d.h. die gesamte MI kann ein sekundäres Pendant in einer anderen Region haben, um im DR-Fall umzuschalten – die Datenbanken innerhalb der MI werden dafür asynchron repliziert).
Recovery-Ziele (RPO/RTO): Zusammengefasst in Tabelle 1 sind die typischen Wiederherstellungsziele:
|
Aspekt |
Azure SQL Database (Single/Pool) |
Azure SQL Managed Instance |
SQL Server on-prem/Azure-VM |
|
Hochverfügbarkeit (intra-Region) |
99,99% SLA (automatische Failover innerhalb Region, i.d.R. < 5 Sek. Umschaltzeit). Zonenredundanz optional für erhöh. SLA. |
99,99% SLA (autom. Failover innerhalb Instanz-Cluster; Zonenredundanz für Business Critical verfügbar). |
Abhängig von eigener HA-Konfiguration (z.B. Failover-Cluster oder Always On AG nötig für 99,99%; sonst typ. 99,9–99,95%). |
|
Point-in-Time Restore (PITR) |
PITR bis max. 35 Tage. RPO: typ. < 5-10 Min. (Log Backup Intervall); RTO: Minuten bis wenige Stunden (abhängig von DB-Größe beim Restore). |
PITR bis max. 35 Tage (Backup-System analog). RPO: < 5-10 Min.; RTO: Minuten-Stunden je nach Datenmenge. |
Abhängig von Backup-Plan (typ. tägliches Full + Logs – RPO entsprechend Backup-Frequenz; RTO: abhängig von Infrastruktur für Restore). |
|
Geo-Disaster Recovery |
Optional: Active Geo-Replication/Fogroup mit asynchroner sekundärer DB in anderer Region. RPO: < 5 Sekunden (Datenverlust minimal), RTO: < 1 Minute für manuelles Failover (Auto-Failover-Gruppe ~30 Sekunden bis Ausfall erkannt + Umschalten). Ohne Geo-Rep.: Geo-Restore aus Backup (RPO bis 1 Std., RTO mehrere Stunden). |
Optional: Failover-Gruppe (ganze Instanz). RPO: typ. < 30 Sek. bis wenige Minuten (je nach Last); RTO: ~1–5 Minuten für Instanz-Failover. Ohne FG: Geo-Restore aus Backup (ähnlich oben). |
Abhängig von DR-Plan (z.B. Log Shipping, Replikation, offsite-Backups). RPO/RTO variabel – i.d.R. längere Wiederanlaufzeiten ohne teure synchrone Replikation. |
|
Langzeit-Backup (LTR) |
Bis 10 Jahre (monatliche/halbjährliche Backups archiviert). Optional, kostenpflichtiger Speicher. |
Bis 10 Jahre (LTR für MI ebenfalls verfügbar). |
Je nach Backup-Archivierung des Betriebs – manuell sicherzustellen. |
Tabelle 1: Vergleich der Verfügbarkeits- und Wiederherstellungsziele
<br>
2. Was ist das Besondere aus Entwicklersicht?
Für Entwickler bietet Azure SQL zahlreiche Vorteile, da es die vertraute SQL Server-Umgebung mit cloudnativen Verbesserungen kombiniert:
Schnelle Bereitstellung & geringe Setup-Hürden: Neue Datenbanken oder sogar ganze SQL-Instanzen (Managed Instances) lassen sich in Azure binnen Minuten bereitstellen. Es sind keine Installationen von SQL Server Software, Betriebssystem-Konfiguration oder Hardwarebeschaffung nötig. Das heißt, Ihr Entwicklungsteam kann für Projekte sofort mit einer vorkonfigurierten, optimal abgestimmten SQL-Umgebung arbeiten – sei es für Proof-of-Concepts, Testumgebungen oder neue Microservices. Die Datenbank ist “ready-to-use”, inklusive Standardkonfigurationen für Sicherung, Überwachung und Sicherheit.
Konsistentes T-SQL & Entwicklungsmodell: Azure SQL verwendet dieselbe SQL Server Engine. Das bedeutet, Ihre bestehenden Kenntnisse in T-SQL, Indexierung, Abfrageoptimierung und Tooling (SSMS, Visual Studio Code mit SQL-Erweiterung, Azure Data Studio etc.) bleiben relevant. Entwickler können nahezu identische CREATE TABLE, SELECT-, JOIN– und Stored Procedure-Logik wie on-premises nutzen. Code für Geschäftslogik in SQL (Prozeduren, Views, Funktionen) ist mit wenigen Ausnahmen portierbar. Somit geht die Migration oder parallele Entwicklung on-prem und auf Azure SQL leicht vonstatten. Auch EF Core und andere ORMs sprechen Azure SQL genauso an wie eine lokale SQL Instanz – lediglich der Connection-String zeigt in die Cloud. Beispiel eines einfachen EF Core-DbContext, der Azure SQL nutzt:
var options = SqlServerDbContextOptionsExtensions.UseSqlServer(
new DbContextOptionsBuilder(),
„Server=tcp:<IhrServer>.database.windows.net,1433;Database=MeineDB;User Id=…;Password=…;“,
sqlOpt => sqlOpt.EnableRetryOnFailure(maxRetryCount: 5, maxRetryDelay: TimeSpan.FromSeconds(10))
).Options;
using var context = new MyDbContext(options);
// … Verwendung von context (LINQ-Queries, SaveChanges etc.)
Wie im Beispiel gezeigt, ist es ratsam, in Cloud-Umgebungen transiente Fehler (z.B. kurzzeitige Netzwerkunterbrechungen oder Failover-Ereignisse) durch einen Retry-Mechanismus im Verbindungs-Stack abzufangen. EF Core bietet dafür EnableRetryOnFailure(), wodurch typische Verbindungsfehler automatisch erneut versucht werden – wichtig für robuste Cloud-Anwendungen.
Minimale Betriebsbelastung: Anders als bei einer selbst verwalteten SQL-Umgebung müssen Entwickler sich kaum um Wartungsaufgaben kümmern. Dinge wie Datenbank-Server einrichten, OS-Updates, Index-Wartung oder Backups laufen bei Azure SQL im Hintergrund. Dies erhöht die Produktivität im Team: Man kann sich auf das Datenbank-Design und die Query-Optimierung konzentrieren, ohne täglich DBA-Tätigkeiten zu erledigen. Insbesondere in kleineren Teams, wo Entwickler oft auch „DBA mit übernehmen“ mussten, entfällt viel Routinearbeit. Bei Bedarf lassen sich aber wichtige Einstellungen dennoch konfigurieren (z.B. Kollationen, Kompatibilitätslevel, Service-Tier hoch/runter).
Leistungs-Features für bessere Performance: Azure SQL bringt einige intelligente Optimierungsfunktionen mit, die Entwickler bei der Performance-Tuning entlasten:
- Query Store: In Azure SQL Database ist der Query Store standardmäßig aktiviert. Er protokolliert Historie von Ausführungsplänen und Laufzeiten aller abgefragten SQLs. Entwickler können damit leicht Performance-Regressionen erkennen (z.B. wenn eine Abfrage plötzlich langsamer wurde nach einem Re-Plan) und Pläne vergleichen. Query Store ermöglicht auch, einen früheren guten Plan festzusetzen (force plan), falls der neue Plan suboptimal ist. Über die Zeit hilft dies, die Anwendungsperformance stabil zu halten, ohne manuelles Logging.
- Automatic Tuning (automatische Plan-Korrektur): Azure SQL Database kann auf Wunsch automatisch erkennen, wenn ein Abfrageplan schlechter ist als der vorherige („Regressions-Erkennung“), und den letzten bekannten guten Plan wieder erzwingen. Ebenso kann der Dienst indexbezogene Empfehlungen geben und – falls aktiviert – fehlende Indizes automatisch anlegen oder überflüssige Indizes entfernen. Diese Features („Auto Create Index“, „Auto Drop Index“ und „Auto Force Plan“) sind in Single Databases zum Teil per Default eingeschaltet oder zumindest per Knopfdruck im Azure-Portal aktivierbar. Für Entwickler heißt das: weniger manuelles Eingreifen bei sich verändernden Workloads. (Hinweis: In Managed Instances sind automatische Indexeingriffe derzeit nicht aktiv; dort bleibt es bei Empfehlungen.)
- In-Memory OLTP: In bestimmten Azure SQL Tiers steht das In-Memory OLTP-Feature zur Verfügung – konkret in Business Critical und teilweise Hyperscale (sofern unterstützt). Damit lassen sich speicheroptimierte Tabellen und nativ kompilierte Stored Procedures nutzen, was bei hochgradig concurrenen Workloads enorme Latenz- und Durchsatzvorteile bringen kann. Entwickler können diese Technik gezielt einsetzen (z.B. für bestimmte Hotspot-Tabellen oder Warteschlangen), müssen aber beachten, dass das Feature z.B. in General Purpose-Tiers nicht verfügbar ist. In Managed Instance (ebenfalls im Business Critical-Tier) ist In-Memory OLTP analog nutzbar.
- Columnstore-Indizes: Azure SQL unterstützt Clustered- und Nonclustered-Columnstore-Indizes, die besonders für analytische Abfragen und Data-Mart-ähnliche Szenarien von Vorteil sind. Schon im Standard General Purpose Tier (vCore) können Columnstores genutzt werden (bzw. im DTU-Modell ab S3 und höher). Entwickler können also auch auf OLTP-Datenbanken gezielt Columnstore-Indizes auf großen Fact-Tabellen anlegen, um Reports oder aggregierte Queries zu beschleunigen – und brauchen hierfür kein separates Data Warehouse, solange das Volumen moderat bleibt.
- Read-Scale-Out: Wie erwähnt, steht im Premium/Business Critical-Modus eine kostenlose lesende Replik zur Verfügung (bei Single DB direkt verfügbar, bei MI BC in Form eines secondaries im Failover-Cluster, das optional lesbar geschaltet werden kann). Entwickler können also in Verbindungszeichenfolgen die ApplicationIntent-Option nutzen, um Lesevorgänge (z.B. Reporting, bestimmte API-Endpunkte) automatisch auf das Read-Only-Replikat zu routen. Dies entlastet den Primärknoten und verbessert die Gesamtperformance, ohne dass eine separate Infrastruktur aufgebaut werden muss.
Sicherheits- und Entwicklungsfeatures: Azure SQL bietet Security-by-Default plus erweiterte Schutzfunktionen, die in on-prem-Umgebungen erst eingerichtet werden müssten:
- Azure AD-Authentifizierung: Neben SQL-Logins können Azure SQL DBs und MIs über Azure Active Directory integriert werden. Sie können einzelnen Nutzern oder – besser – Azure AD-Gruppen Zugriffsrechte auf die DB geben. Entwickler in Unternehmen profitieren davon, sich mit ihrem Domänenkonto (bzw. Azure AD-Konto) als DB-User anzumelden, und man kann zentral Identity- und MFA-Richtlinien nutzen. Für Anwendungen können auch Managed Identities (von Azure VMs oder App Services) verwendet werden, um sich ohne Passwort bei der DB zu authentifizieren. Das erleichtert die Secrets-Verwaltung erheblich und erhöht die Sicherheit.
- Always Encrypted: Azure SQL unterstützt Always Encrypted (inkl. Enklaven-Technologie, sofern clientseitig genutzt). Damit können besonders sensitive Spalten clientseitig verschlüsselt in der DB abgelegt werden, sodass selbst DBA oder Microsoft nicht den Klartext sehen. In Entwicklungsszenarien heißt das, dass man z.B. Personendaten, Kreditkartennummern etc. Ende-zu-Ende schützen kann. Der .NET-Treiber und neuere Connectoren unterstützen Always Encrypted – Entwickler müssen entsprechend Column Encryption Settings im Connection String aktivieren und mit Key Vault oder lokalem Zertifikatstore arbeiten.
- Dynamic Data Masking: Mit einem einfachen T-SQL-Befehl oder per Portal können Sie Felder (z.B. E-Mail, Telefonnummer) mit einer Maske versehen. Unautorisierte Abfragen sehen dann nur noch Platzhalter („xxxx“) statt echter Werte. Für Dev/Test-Umgebungen ist das nützlich, wenn Produktionsdaten verwendet werden: Entwickler mit Leserollen können z.B. realistische aber anonymisierte Daten sehen, ohne die Originalwerte.
- Row-Level Security (RLS): Dieses Feature erlaubt es, einen Sicherheitsfilter pro Zeile zu definieren (durch eine Funktion und Sicherheitsrichtlinie in T-SQL). Damit können Entwickler Multi-Tenancy innerhalb einer Datenbank implementieren – jeder Mandant sieht nur „seine“ Zeilen. Azure SQL unterstützt RLS analog zu SQL Server. Beispiel: Ein Security Policy filtert Tabellen anhand einer TenantID, die per SESSION_CONTEXT gesetzt wird. So kann man eine Single-DB-Mandantenlösung bauen, ohne überall im Code WHERE TenantID = X zu schreiben – die DB erledigt das transparent. RLS eignet sich aber ebenso, um z.B. Abteilungsdaten für verschiedene Benutzergruppen abzuschotten.
- Auditing & Threat Detection: Azure SQL kann auf Knopfdruck ein Auditing einschalten, das alle oder ausgewählte Aktionen (z.B. SELECT/UPDATE auf sensitive Tabellen, Login-Versuche) in Logs schreibt – entweder ins Azure Log-Analytics, Event Hubs oder in Azure Storage. Entwickler können so Aktivitäten nachvollziehen, z.B. wer hat wann eine bestimmte Änderung durchgeführt. Zusätzlich gibt es die Advanced Threat Protection (heute Teil von Defender for SQL): verdächtige Ereignisse wie Massenlöschungen, SQL Injection-Versuche oder Anmeldeanomalien werden erkannt und als Alerts gemeldet. Dies hilft, Sicherheitsvorfälle schnell zu erkennen, ohne eigene komplexe Überwachung bauen zu müssen.
Typische Dev-Flows in Azure SQL: Die Entwicklung mit Azure SQL lässt sich mit modernen DevOps-Ansätzen gut kombinieren:
- Schema-Migrationen: Genau wie on-premises aktualisiert man das DB-Schema idealerweise automatisiert. Teams nutzen entweder EF Core Migrations (Code-First, in die App integriert) oder SQL-Projekt/DACPAC-Deployments (Declarative, Source-controlled Schema). Azure SQL unterstützt beide Ansätze. Mit EF Core kann beispielsweise bei jeder Deployment-Pipeline dotnet ef database update gegen die Azure SQL-DB ausgeführt werden, um Schemaänderungen einzuspielen. Alternativ kann eine DACPAC mit SqlPackage oder via Azure Pipelines auf die Azure SQL Database angewendet werden, die ein Delta-Update ausführt. Wichtig: Azure SQL erfordert keinerlei besondere Schritte gegenüber on-prem beim Schema-Update; man sollte nur bedenken, dass in Produktion evtl. Zero-Downtime-Strategien notwendig sind (siehe DevOps & Betrieb).
- Continuous Integration/Continuous Deployment (CI/CD): Entwicklungsteams können Azure SQL in ihre CI/CD einbinden. Beispielsweise kann für jede Pull Request eine temporäre Datenbank erstellt werden (Azure CLI: az sql db copy oder sogar CREATE DATABASE … AS COPY OF … via T-SQL, um einen bestehenden Stand zu klonen). Integrationstests laufen darauf, anschließend wird die DB wieder gelöscht – dank Pay-per-Use fallen nur wenige Cent an. Für das Deployment in Staging/Prod kann man Blue-Green Ansätze fahren, indem parallel zwei DBs/Schema-Versionen betrieben und umgeschaltet wird – oder traditionell via Migration-Scripts. Azure SQL lässt sich zudem per Infrastructure-as-Code verwalten (Bicep/ARM, Terraform), um z.B. Konfigurationen wie Failover-Gruppen, Auditing-Settings oder Server-Firewallregeln versioniert auszurollen.
- Datenbasierte Tests & Testdaten-Handling: Entwickler nutzen oft Prod-Daten für Staging oder Testing (unter Einhaltung von Datenschutz!). Azure SQL erleichtert das Bereitstellen solcher Daten z.B. durch BACPAC-Exporte – man kann eine DB als BACPAC (Schema+Data) exportieren und in einer kleineren Azure SQL-Instanz wieder importieren. Alternativ ist die erwähnte Copy Database-Funktion praktisch: innerhalb derselben Azure SQL-Serverinstanz kann man eine vollständige Kopie einer DB erstellen (CREATE DATABASE KopieXY AS COPY OF ProdXY). Die Kopie ist in Minuten einsatzbereit, ohne Downtime der Quelle. Entwickler können so schnell realistische Testumgebungen aufsetzen. In Managed Instance kann man analog per Backup/Restore (Backup to URL auf Prod, Restore in MI) Daten bereitstellen. Dynamische Datenmaskierung oder separate Maskierungs-Skripte helfen anschließend, sensible Inhalte zu verfremden.
- Codebeispiele & Skripte: Innerhalb der Anwendung unterscheidet sich der Code kaum von einem lokalen SQL. Der Connection-String für Azure SQL Database hat die Form Server=tcp:<servername>.database.windows.net,1433;Database=<dbname>;User ID=<user>@<servername>;Password=<pw>;Encrypt=True;TrustServerCertificate=False; usw. (Azure erfordert verschlüsselte Verbindung). Mit Azure AD kann statt User/Password auch Authentication=Active Directory Default o.ä. verwendet werden, sofern die App eine identität besitzt. T-SQL-Skripte für Azure SQL sehen vertraut aus. Beispiel: Das Aktivieren des Query Stores (sofern man es mal deaktiviert hatte) geschieht mit:
ALTER DATABASE [MeineDB] SET QUERY_STORE = ON (OPERATION_MODE = READ_WRITE);
Viele solche Operationen, die on-prem einmalig eingestellt werden mussten, sind in Azure oft per Default aktiv (z.B. Query Store ist out-of-the-box an, TDE-Verschlüsselung ebenso). Entwickler können sich somit auf die Nutzung der Features konzentrieren, statt auf deren Grundkonfiguration.
<br>
3. Unterschiede zu SQL Server (on-premises / Azure-VM)
Obwohl Azure SQL auf der SQL Server-Engine basiert, gibt es einige wichtige Unterschiede in den verfügbaren Features und dem Betriebsmodell. Die folgende Funktionsmatrix gibt einen Überblick über ausgewählte Punkte und deren Verfügbarkeit bzw. Besonderheiten in Azure SQL Database vs. Azure SQL Managed Instance im Vergleich zu einem selbstverwalteten SQL Server:
|
Funktion/Feature |
Azure SQL Database (Single/Pool) |
Azure SQL Managed Instance (MI) |
SQL Server on-prem/Azure-VM |
|
SQL Server Agent (Jobs) |
Nein, nicht verfügbar. Alternative: Azure Elastic Jobs (Job-Service auf Server-Ebene) oder Azure Automation verwenden. |
Ja, SQL Agent ist vorhanden und nutzbar (nahezu identisch zu on-prem). |
Ja, SQL Agent verfügbar. |
|
SQL CLR (benutzerdefinierte .NET-Assemblys) |
Nicht unterstützt. .NET-Code kann nicht innerhalb einer Azure SQL DB ausgeführt werden. (Workaround: Logik in App auslagern oder MI nutzen.) |
Eingeschränkt Ja – CLR wird unterstützt, allerdings ohne unsichere/Externe Zugriffsmöglichkeiten (z.B. kein File-Zugriff). Assemblies müssen als SAFE oder EXTERNAL_ACCESS (mit Einschränkungen) registriert sein. |
Ja, volle CLR-Unterstützung (SAFE, EXTERNAL, UNSAFE je nach Konfiguration). |
|
Linked Server / verteilte Abfragen |
Nein, Azure SQL erlaubt keine Linked-Server-Objekte und keine 3-/4-part queries zu anderen DB-Servern. (Alternative: Azure Elastic Query nutzen für externen Datenquellenzugriff, z.B. andere Azure SQL DBs via External Tables.) |
Ja, teilweise: Linked Server zu externen SQL-Datenquellen sind unterstützt (SQL Server, Azure SQL). Allerdings ohne MS DTC – verteilte Transaktionen über Servergrenzen hinweg sind nicht möglich. Innerhalb derselben MI sind Cross-DB-Transaktionen hingegen zulässig (eine MI verhält sich wie eine SQL-Instanz). |
Ja, Linked Server zu diversen Quellen (SQL, Oracle etc.) und verteilte Transaktionen via MSDTC sind möglich (sofern eingerichtet). |
|
Cross-Database Queries |
Begrenzt: Direktes DatabaseName.Schema.Table-Referenzieren anderer DBs auf demselben Server ist nicht möglich, da jede Azure SQL DB isoliert ist. (Workaround: Elastic Queries / Externe Tabellen oder Verwendung von Managed Instance.) |
Ja, innerhalb der MI-Instanz können Abfragen über mehrere DBs mittels drei-teiliger Namen ausgeführt werden, analog zu on-prem. |
Ja, volle Unterstützung für Cross-DB-Abfragen innerhalb derselben SQL Server-Instanz. |
|
Cross-Database Transactions |
Nein, Transaktionen können nicht mehrere Azure SQL-Datenbanken umfassen. Jede DB ist eine unabhängige Einheit. |
Ja, Transaktionen über mehrere DBs in derselben Managed Instance werden unterstützt (da eine MI einer SQL-Server-Instanz entspricht). Verteilte Transaktionen zwischen unterschiedlichen MIs oder externen Servern sind jedoch nicht unterstützt. |
Ja, via MSDTC sind verteilte Transaktionen über mehrere DBs/Server möglich (mit entspr. Konfiguration). |
|
xp_cmdshell & OS-Zugriff |
Nein, kein Zugriff auf Betriebssystemfunktionen. System-Prozeduren wie xp_cmdshell sind deaktiviert/nicht vorhanden. |
Nein, MI erlaubt ebenfalls keinen Zugriff auf das zugrundeliegende OS, xp_cmdshell ist nicht nutzbar. (Für Shell-Aktionen wäre ein Azure VM-Ansatz nötig.) |
Ja, volles OS-Zugriffsrecht bei sysadmin; xp_cmdshell standardmäßig deaktiviert, kann aber aktiviert und genutzt werden. |
|
PolyBase / Externe Datenquellen |
Teilweise: Azure SQL Database unterstützt externe Datenquellen über Elastic Query bzw. seit SQL 2022-Engine auch über neue Ansätze (CREATE EXTERNAL TABLE für bestimmte Formate). Der klassische PolyBase (bspw. Daten von Hadoop, Oracle abrufen) ist nicht vorhanden, aber es gibt Cloud-Alternativen (Azure Data Factory, Synapse Link). Zugriff auf Azure Blob/ADLS-Dateien via OPENROWSET (CSV, Parquet, Delta) ist unterstützt. |
Teilweise: MI unterstützt PolyBase-ähnliche externe Tabellen für Azure Storage (ADLS, Blob) als Quelle. Andere PolyBase-Szenarien (z.B. externen SQL Server via ODBC-Adapter) sind Stand Nov. 2025 in MI nicht verfügbar. |
Ja, PolyBase ab SQL 2016 verfügbar für diverse externe Datenquellen (Hadoop, Oracle, Teradata, flat files etc. via PolyBase-Konfiguration). |
|
FILESTREAM / FILETABLE |
Nein, nicht unterstützt, da kein direktes Dateisystem vorhanden ist. |
Nein, MI unterstützt weder FILESTREAM noch FILETABLE. |
Ja, FILESTREAM/FILETABLE optional konfigurierbar (benötigt Windows-OS Integration). |
|
Service Broker |
Nein, nicht verfügbar in Azure SQL Database. (Eventuelle Alternativen: Azure Service Bus, Storage Queue oder Migration auf MI falls SB intensiv genutzt.) |
Ja, Service Broker funktioniert innerhalb der Managed Instance (für DB-übergreifende SB-Kommunikation innerhalb der MI). Externe Aktivatoren müssten auf VM laufen; SB zwischen verschiedenen MI ist nicht gegeben. |
Ja, Service Broker verfügbar für lokale und zwischenserver Kommunikation (wenn konfiguriert). |
|
SQL Server Auditing (Legacy) |
N/A, das klassische SQL Server Auditing (auf OS-Ebene) ist nicht vorhanden – Azure SQL bietet stattdessen Azure Auditing auf DB-Ebene, konfigurierbar im Azure-Portal (Ergebnisse gehen in Azure Logs/Storage). |
Ja, MI unterstützt Auditing auf Instanzebene analog zu on-prem, jedoch werden Audit-Logs ebenfalls an Azure Storage/Log Analytics geleitet. (Einige erweiterte Optionen wie Windows Security Logs entfallen.) |
Ja, volles Auditing in Logs/Eventlog möglich, inkl. Schreiben ins OS/Datei. |
|
Wartungspläne & -fenster |
Nicht vom Nutzer steuerbar: Azure SQL führt regelmäßige Wartung (Indexreorgs, Updates) automatisiert durch. Es gibt keine herkömmlichen Wartungspläne, aber viele Aspekte (Statistiken, Indexfragmentierung) werden vom System oder via Automatic Tuning adressiert. Ein festes Wartungsfenster kann i.d.R. nicht gewählt werden (Ausnahme: bei einigen Tier-Optionen, z.B. Hyperscale, ist seit 2024 ein konfigurierbares Wartungs-Zeitfenster verfügbar). Updates sind so gestaltet, dass sie minimalinvasiv sind. |
Begrenzt steuerbar: MI bietet ebenfalls keine SQL-Agent-Wartungspläne. Standardwartungen (Patch, Rebalancing) geschehen automatisch. Für MI kann man ein wöchentliches Wartungszeitfenster (z.B. Sa 02:00) konfigurieren, innerhalb dessen nach Möglichkeit Updates stattfinden. |
Ja, vollständige Kontrolle – DBA kann Wartungspläne einrichten, Wartungsfenster selbst festlegen, oder Windows Update/Installationen nach eigenem Zeitplan durchführen. |
|
SQL Trace / Profiler |
Nein, traditionelle SQL Traces sind nicht verfügbar. Stattdessen nutzt man Extended Events oder Azure SQL-specific Monitoring (XEvent sind teilweise eingeschränkt verfügbar, aber Basis-Event-Tracing geht). Alternativ bieten Azure “Query Performance Insight” und Query Store ähnliche Funktionalität wie Profiler-Nachverfolgungen. |
Ja, MI erlaubt grundsätzlich auch Extended Events (vollständig wie on-prem) und unterstützt auch das SQL Server Profiler-Tool zum Echtzeit-Trace gegen die MI. (SQL-Trace an sich ist veraltet, aber XEvents voll da.) |
Ja, SQL Server Profiler/Trace und Extended Events stehen zur Verfügung. |
|
DMVs & Serverfunktionen |
Teilweise eingeschränkt: Die meisten Dynamic Management Views auf DB-Ebene sind verfügbar. Instanzweite DMVs (z.B. sys.dm_os_sys_info) sind nicht zugreifbar in Single DB, da kein Instanzzugriff. Azure bietet aber Alternativen, z.B. sys.server_resource_stats für Ressourcenverbrauch der DB. Ebenso sind einige sys.master_files-Infos nicht sichtbar (da Storage abstracted). |
Weitestgehend ja: Da MI einer vollen Instanz entspricht, sind auch viele systemweite DMVs zugänglich. Einschränkungen gibt es z.B. bei OS-bezogenen Infos (da kein direkter OS-Zugriff), aber z.B. sys.dm_os_wait_stats etc. funktionieren. |
Ja, uneingeschränkter DMV-Zugriff entsprechend Serverrechten. |
|
Kompatibilitätslevel |
Max. aktuell: Azure SQL hält den Kompatibilitätsgrad (compatibility level) auf dem Stand der neuesten SQL Server-Version (z.B. 160 für SQL Server 2022) und ermöglicht per Einstellung auch niedrigere Level (bis 100 minimum). Standard ist i.d.R. der neueste Level bei Neuerstellung. Damit können Query-Optimierungen nach neuerem Level oder falls nötig Abwärtskompatibilität eingestellt werden. |
Ähnlich: MI unterstützt auch verschiedene Kompatibilitätslevel pro DB, Standard ist ebenfalls der neueste (je nach MI-Version). MI selbst wird im Hintergrund regelmäßig auf neueste Engine gehoben, aber mit optionaler Verzögerung (sog. „Versionen“ und Wartungskanäle). |
Abhängig von installierter SQL Server-Version. Neue Hauptversion erfordert manuelles Upgrade. Compatibility Level kann manuell pro DB gesetzt werden, Standard ist meist Level der Serverversion. |
|
Größen- und Leistungsgrenzen |
Begrenzte Ressourcen pro DB: Max. Datenbankgröße General Purpose: 4–8 TB (je nach Gen & Region), Business Critical: ~4 TB, Hyperscale: 100 TB. Max. 128 vCores pro DB. Es gibt Limits für gleichzeitige Anfragen, Worker-Threads etc., abhängig vom Tier (Bsp.: ein 4-vCore GP-DB erlaubt ca. 320 gleichzeitige Threads). Solche Limits sind von Azure verwaltet – man skaliert bei Bedarf in nächsthöhere Stufe. |
Begrenzte Ressourcen pro Instanz: Max. 16 TB pro DB (MI GP; MI BC ~4 TB). Gesamt 128 vCores pro MI. Ca. 100 Databases pro MI (soft limit, erweiterbar). Auch hier gelten interne Limits analog zu einer SQL Enterprise Edition, jedoch kann die zugrundeliegende Hardware Grenzen setzen (z.B. IO/Throughput in GP über Netzwerk). |
Skalierung durch Hardware: Max. DB-Größen nur durch Storage im Server begrenzt (bei Standardedition ggf. lizenzabhängige Limits). CPU/RAM entsprechend Server. Anzahl DBs pro Instanz theoretisch hoch (hunderten), aber praktisch durch Ressourcen begrenzt. |
|
Release-Zyklus |
Kontinuierlich: Azure SQL erhält fortlaufend Updates und neue Features, oft früher als on-prem. (Beispiel: Intelligent Query Processing Verbesserungen erscheinen zeitnah in Azure SQL.) Es gibt keine individuellen Service Packs – der Dienst ist evergreen. |
Evergreen: MI wird von Microsoft aktualisiert (i.d.R. quartalsweise Feature-Upgrades). Kunden können zwischen General Availability oder Preview-„Update Train“ wählen, aber nicht Versionen überspringen. Keine eigene Kontrolle über Patches, aber Zeitfenster planbar. |
Versioniert: Haupt-Releases alle paar Jahre (2016, 2019, 2022, 2025 etc.), dazwischen kumulative Updates, die vom Admin installiert werden müssen. Kunden entscheiden, wann ein Upgrade erfolgt (dafür Ende des Supports nach ~10 Jahren beachten). |
(Tabelle 2: Funktions- und Betriebsunterschiede Azure SQL vs. SQL Server)
Zusätzlich zu obiger Tabelle gibt es einige Generelle Betriebsaspekte zu beachten:
- Automatisiertes Patching & Backups: Wie bereits im Summary und Architektur beschrieben, erfolgt in Azure SQL alles Wichtige automatisch. Daraus folgt: Sie können keine bestimmten SQL Server-KBs auswählen oder Backup-Strategien ändern – Azure macht das nach Best Practices. Ein Vorteil ist die Zeitersparnis und Sicherheit (immer aktuelles System); ein möglicher Nachteil ist die geringere Kontrolle, was für manche konservative Szenarien wichtig sein könnte. In der Praxis funktionieren Azure-Updates sehr zuverlässig im Hintergrund.
- Kein Zugang zur Server- bzw. OS-Ebene: In Azure SQL Database haben Sie nur Zugriff auf die Datenbank selbst und eine logische Serverhülle (für Logins, Firewall etc.). In MI haben Sie Zugriff auf Instanz-Ebene (Master DB, msdb), aber keinen RDP-Zugang oder ähnliches. Systemfunktionen, die OS-Interaktion erfordern, gehen nicht. Auch Tools wie bcp oder sqlcmd laufen nicht „auf dem Server“ (können aber natürlich extern verwendet werden). Für Wartungsskripts, die z.B. Dateien importieren, müssen Cloud-Alternativen genutzt werden (z.B. Azure Logic Apps, Azure Functions, oder Daten via Azure Storage bereitstellen und per BULK INSERT laden).
- Überwachung und Leistungsanalyse: Da Profiler/Trace wegfallen (zumindest in Azure SQL DB), nutzt man primär DMVs, Extended Events und Azure Monitor. Azure stellt ein Query Performance Insight im Portal zur Verfügung, das Top-Queries, ihre Dauer und Resource Use zeigt – basierend auf Query Store. Außerdem kann man Azure SQL Insights oder Azure Monitor Log Analytics verwenden, die Metriken wie DTU/vCore-Nutzung, Deadlocks, Wait Stats etc. sammeln. Entwickler und DevOps-Ingenieure werden sich ggf. umstellen von altbekannten Perfmon-Zählern und Trace-Files hin zu KPI-Dashboards und XEvent-Sessions, die automatisiert laufen. (Siehe Kapitel 7, Beobachtbarkeit.)
- Kompatibilität & Migration: Bei der Migration einer bestehenden Anwendung zu Azure SQL sollte man Kompatibilitätslevel der Datenbank prüfen und ggf. auf den neuesten Stand heben, um von Verbesserungen zu profitieren. Azure SQL unterstützt aber auch ältere Compatibility Levels (z.B. 140 für SQL 2017), um Abfragen unverändert laufen zu lassen. Häufige Migrationsblocker sind die in obiger Tabelle genannten nicht unterstützten Features. Beispielsweise: Eine Datenbank, die SQL CLR oder Service Broker nutzt, kann nicht 1:1 in Azure SQL Database laufen – hier müsste man Code refaktorieren oder auf MI ausweichen. Ebenso müssen SQL Server Agent-Jobs (z.B. Wartung, Batch-Jobs) auf Alternativen umgestellt werden: Azure Data Factory, Elastic Jobs, PowerShell-Automation etc. Linked Servers zu Drittanbieterdatenquellen müssen ersetzt werden (entweder durch Anwendungslogik, Data Integration Services oder MI). Workarounds existieren oft: z.B. für cross-database joins kann man in Azure SQL Database Elastic Query verwenden, d.h. eine externe Datenquelle + externe Tabelle definieren, um eine andere DB zu erreichen (allerdings nur lesend und mit etwas Aufwand; es eignet sich für Reporting über mehrere DBs).
- Versionsunterschiede: Azure SQL ist meist eine halbe Version voraus gegenüber dem on-prem SQL Server. Viele neue Engine-Funktionen (z.B. UTF-8-Unterstützung, Intelligent Query Processing, Ledger Tables, AD-Integration-Verbesserungen) tauchten zuerst in Azure SQL auf oder zeitgleich. In seltenen Fällen kann es auch Exklusiv-Features geben, die es on-prem nicht gibt (z.B. Autoskalierung, Serverless). Umgekehrt sind veraltete Features auf Azure oft nicht mehr vorhanden (Beispiel: Database Mirroring, da Always On verwendet wird; oder alte Systemprocs). Bei Migration muss man daher alte Zöpfe abschneiden und neue Ansätze nutzen – was aber meist Vorteile bringt.
Fazit zu Unterschieden: Azure SQL PaaS entlastet von vielen Infrastrukturthemen und erzwingt Cloud-gerechte Patterns. Für Entwickler bedeutet das, sie können schneller iterieren und müssen sich weniger mit Umgebungspflege aufhalten. Allerdings sollten sie die genannten Einschränkungen kennen, um Anwendungen entsprechend zu gestalten bzw. die passende Azure SQL-Variante auszuwählen (Single vs. MI vs. VM) – dazu mehr in den folgenden Kapiteln.
<br>
4. Lizenzierung & Kostenmodell (entwicklerrelevant erklärt)
Bei der Nutzung von Azure SQL spielen Kostenaspekte eine wichtige Rolle. Entwickler treffen zwar nicht immer die finanzielle Entscheidung, sollten aber die Kostenmodelle und Lizenzierungsoptionen verstehen, um Architekturentscheidungen mit zu beeinflussen (z.B. Wahl des richtigen Service-Tiers, Optimierung von Dev/Test-Umgebungen). Azure SQL bietet hier verschiedene Preis- und Leistungsmodelle:
vCore-Modell (Provisioned Compute): In diesem Modell buchen Sie eine bestimmte Anzahl virtueller Kerne (vCores) sowie einen zugehörigen Arbeitsspeicher und I/O-Leistung, analog zu Hardware-Ressourcen on-prem. Die Abrechnung erfolgt pro Stunde für bereitgestellte vCores, unabhängig davon ob sie ausgelastet sind (ähnlich einer VM). Das vCore-Modell ist flexibel und transparent – es kommt der traditionellen CPU+RAM Zuteilung nahe und erlaubt auch die Nutzung von Azure Hybrid Benefit und Reservierungen (s.u.). Innerhalb des vCore-Modells gibt es verschiedene Service-Tiers und Hardware-Generationen:
- General Purpose (Standard-Tier): Trennung von Compute und Storage, eignet sich für die meisten Alltags-Workloads. Gute Balance aus Kosten und Leistung. Latenzen etwas höher als BC, da Speicherdaten über das Netzwerk von remote Storage gelesen werden. IOPS und Durchsatz sind begrenzt durch das jeweilige vCore-Level (z.B. ca. 5–10 MB/s Log-Throughput pro vCore). Storage ist auf Azure Premium SSD aufgebaut – gute Zuverlässigkeit. Max. 8 TB pro DB (Stand 2025).
- Business Critical (Premium-Tier): Hochleistungs-Tier mit lokalem SSD-Speicher und Always-On 3-Knoten-Cluster. Bietet geringere Latenz, höhere IOPS (im Tausende-Bereich), und enthält eine Read-Only-Replica. Eignet sich für anspruchsvolle OLTP-Workloads mit vielen gleichzeitigen Transaktionen und strengen Latenzvorgaben. Kostet ca. 2–3x mehr pro vCore als General Purpose. Max. DB-Größe meist 4 TB. In Business Critical sind einige Features exklusiv/nur hier sinnvoll (In-Memory OLTP, unverzögertes Failover).
- Hyperscale: Spezielles Tier (nur für Single Database, nicht für MI) mit einer Cloud-nativen Architektur: Der Datenbestand wird auf viele gestückelte Speicherseiten-Server verteilt, so dass nahezu unbegrenztes Wachstum möglich ist (offiziell bis 100 TB). Hyperscale skaliert Storage automatisch mit und erlaubt bis zu 4 sekundäre lesende Replikate. Backup/Restore geht schneller via Snapshots. Dieses Tier ist ideal, wenn eine einzelne DB sehr groß werden könnte oder schnelle viele Reads benötigt. Die Kosten berechnen sich ebenfalls nach vCores (Compute für Primär- und ggf. sekundäre Knoten) plus Storageverbrauch. Hyperscale vCores entsprechen in Performance etwa GP vCores, jedoch mit Unterschied, dass Lesezugriffe aus dem Buffer-Cache auf verteilten Knoten kommen. Hyperscale kann Stand 2025 auch mit Named replicas gezielt für Lastverteilung eingesetzt werden. Hinweis: Hyperscale bietet aktuell keinen Serverless-Betrieb mit Autopause (nur Auto-Scale, aber kein Pausieren).
- Azure SQL Managed Instance Tiers: Bei MI gibt es analog General Purpose (auf Standard-Storage, bis 16 TB, höhere Latenz I/O) und Business Critical (mit 4-Knoten-Cluster und lokalem Storage, bis ~4 TB, hohe IOPS). MI hat zudem Hardwareoptionen (Gen5 als Standard; neuere wie Premium Series mit stärkeren CPUs oder Memory-Optimized Series für mehr RAM pro vCore können verfügbar sein – diese beeinflussen Kosten entsprechend). MI wird immer als vCore-Modell abgerechnet (DTUs gibt es dort nicht).
Serverless (automatisches Compute-Tier): Serverless ist eine besondere Variante für Azure SQL Database (Single) im General Purpose-Tier. Hier muss kein fester vCore-Wert gewählt werden. Stattdessen definiert man einen Bereich an vCores (min und max) und ein Auto-Pause-Intervall. Azure skaliert die tatsächlich zugewiesenen CPU/RAM-Ressourcen je nach aktueller Last automatisch hoch und runter – innerhalb der min-max-Spanne. Abrechnung erfolgt auf Basis der genutzten CPU-Sekunden und des zugewiesenen Arbeitsspeichers, im Sekundentakt. Ist die DB länger als das definierte Intervall inaktiv (z.B. 1 Stunde), wird sie automatisch pausiert: Das bedeutet, es fallen keine Compute-Kosten mehr an (nur minimaler Storage kostet weiter), allerdings steht die DB dann erst nach einigen Sekunden Verzögerung wieder zur Verfügung, wenn eine neue Verbindung sie “aufweckt”. Serverless eignet sich hervorragend für discontinuous workloads – z.B. Entwicklungs-/Testdatenbanken, oder Anwendungen mit stark schwankender Last und langen Leerlaufzeiten über den Tag. Wichtig zu wissen: Im Serverless-Modell gelten einige Limitierungen: Die maximale vCore-Anzahl ist derzeit 40 (GP, Gen5), und Azure Hybrid Benefit sowie Reserved Capacity können hier nicht genutzt werden. Auch in Hyperscale (sofern als Preview) entfällt derzeit das Pausieren. Für Produktionsanwendungen mit konstant hoher Last ist Serverless oft teurer als ein vergleichbares Provisioned (weil der On-Demand CPU-Preis höher ist) und kann Latenz beim Wiederaufwachen hinzufügen. Aber bei unregelmäßiger Nutzung sind erhebliche Einsparungen möglich, da Sie quasi nur “Bezahlen, was Sie verbrauchen”.
Elastic Pools: Anstelle einzelner Datenbanken im vCore- oder DTU-Modell zu betreiben, können mehrere Datenbanken in einem Elastic Pool zusammengefasst werden. Ein Pool hat eine Gesamtzahl an vCores (oder im alten Modell: eDTUs), und alle enthaltenen DBs teilen sich diese Ressourcen. Kosten fallen pauschal für den Pool an. Das Modell ist sinnvoll, wenn viele Datenbanken mit unterschiedlichem Nutzungsverhalten existieren – z.B. in einer SaaS-Anwendung mit 100 Kunden-Datenbanken, die nie gleichzeitig Last erzeugen. Dann könnte ein Pool mit z.B. 20 vCores die Bedarfsspitzen abdecken, anstatt 100 einzelne Datenbanken mit je 2 vCores (wovon 90% ungenutzt bleiben). Pools ermöglichen so Kosten sparen durch Overcommitting der Leistung, aber mit dem Risiko, dass extreme gleichzeitige Last aller DBs zu Engpässen führt. Entwickler sollten Pools vor allem bei Multi-Tenant-Designs in Betracht ziehen (siehe Szenario 2). Hinweis: Die Kosten eines Pools sind fest, auch wenn DBs darin gerade untätig sind (Serverless gibt es innerhalb Pools nicht).
Preismodelle zusammengefasst: Früher gab es auch das DTU-Modell (Basic, Standard, Premium mit festen Leistungsstufen). Dieses ist jedoch eher legacy und für neue Projekte empfiehlt Microsoft das vCore-Modell aufgrund der Transparenz. DTU steht hier nicht im Fokus, wird aber noch von kleinen Anwendungen und manchen Kunden genutzt.
Preis- und Lizenzhebel:
- Azure Hybrid Benefit (AHB): Wie erwähnt, erlaubt AHB die Mitnahme vorhandener SQL Server-Lizenzen in die Cloud. Praktisch bedeutet das: Wenn Sie z.B. SQL Server Standard Edition Lizenzen on-prem mit Software Assurance haben, können Sie eine Azure SQL Instanz im Lizenzfrei-Modus betreiben (nur Grundkosten). In Azure-Preislisten gibt es deshalb oft zwei Preise: “License Included” vs. “Base Rate (AHB)”. Der Rabatt ist beträchtlich: Für Standard-Edition-Lizenzen spart man ca. 30% und für Enterprise-Edition (insbesondere bei genutzten Enterprise-Funktionen wie mehr als 4 vCores oder DBs/Instanz) sogar ~40-50%. Zu beachten: AHB gilt nur für vCore provisioned Modelle (Serverless ist davon ausgeschlossen). Außerdem muss die Lizenz entsprechend der Azure-Regeln ausreichen – bei Enterprise Edition gibt es z.B. das 4:1 Ratio (ein on-prem Core kann für vier vCores General Purpose oder einen vCore Business Critical eingesetzt werden, da Enterprise leistungsfähiger ist).
- Reserved Capacity: Azure bietet die Option, Compute-Ressourcen für 1 Jahr oder 3 Jahre im Voraus zu reservieren (mit Vorauszahlung oder monatlicher Zahlung, aber bindender Vertragslaufzeit). Im Gegenzug erhält man einen erheblichen Rabatt auf den vCore-Preis – z.B. etwa 33% für 1 Jahr, um 50-60% für 3 Jahre (gegenüber Pay-as-you-go). Combinebar mit AHB – was die größten Einsparungen ergibt. Eine 3-Jahres-Reservierung mit AHB kann insgesamt bis ~70-80% günstiger sein als spontane Einzelstunde mit Lizenz. Allerdings bindet man sich damit an eine bestimmte Konfiguration (z.B. “8 vCores Business Critical in Region West Europe” reserviert). Reservierungen lohnen also für stabile dauerhafte Prod-Workloads. Für volatile oder Testumgebungen eher nicht. Tipp: Entwickler in frühphasigen Projekten sollten vorsichtig mit Reservierungen sein – erst testen, dann optimieren und wenn klar ist, was langfristig gebraucht wird, kann man reservieren.
- Storage- und Backup-Kosten: Neben Compute fallen Kosten für Datenbankspeicher an. Im vCore-Modell wird pro GB pro Monat abgerechnet (z.B. ~0,115 € pro GB/Monat in GP, Stand heute). In vielen Tiers sind einige GB inklusive (z.B. 32 GB oft gratis). Backup Storage über die PITR-Aufbewahrung hinaus (Differenz zwischen DB-Size und dem was an Logs/Backups anfällt) wird ebenfalls berechnet – Langzeitbackups kosten extra je GB/Monat auf günstigem Storage. Diese Posten sind meist gering im Vergleich zum Compute, sollten aber bei sehr großen DBs (TB-Bereich) beachtet werden. Für Hyperscale gibt es eine Besonderheit: Der Storage-Snapshot-Mechanismus macht Backups extrem effizient – man zahlt hier im Prinzip nur für zusätzlichen Speicherverbrauch, nicht doppelt für Kopien.
- I/O- und Netzwerk-Kosten: In Azure SQL Database sind IOPS und Throughput durch das Tier abgedeckt – es gibt keine direkte “pro IO” Gebühr. Aber Daten, die Azure verlassen (z.B. wenn ein Client aus einem anderen Rechenzentrum oder On-Premises große Datenmengen abruft), können Egress-Gebühren verursachen. Innerhalb derselben Region sind Zugriffe kostenlos; zwischen Regionen (z.B. App in West Europe, DB in North Europe) fallen Interregion Traffic-Kosten an. Außerdem: Wenn Sie Geo-Replikation nutzen, wird der Traffic zum sekundären Rechenzentrum berechnet (in der Regel minimal, einige Cent, es sei denn extrem viele Datenänderungen). Entwickler sollten also Architektur so planen, dass App und DB in einer Region sind, und nur bewusst Cross-region-Reads machen, wo nötig.
Dev/Test-Aspekte: Für Entwicklungs- und Testumgebungen gibt es einige Besonderheiten in der Abrechnung:
- Azure Dev/Test Rabatte: Für Kunden mit Visual-Studio-Abonnements oder Enterprise Agreements bietet Azure spezielle Abonnements, wo bestimmte Dienste (inkl. SQL DB, MI) vergünstigt sind, weil keine Prod-Workloads erlaubt sind. Beispielsweise entfällt in einem Dev/Test Angebot der Lizenzkostenanteil komplett (ähnlich AHB) und man zahlt nur den Grundpreis. Damit können Entwickler kostengünstiger mit Azure SQL arbeiten. Voraussetzung: Nutzung nur für Entwicklung, Test, nicht für Produktionsbetrieb.
- Serverless-Pausierung: Wie oben erklärt, ist die Serverless-Option ideal, um in nicht-produktiven Umgebungen Kosten zu sparen. Z.B. eine QA-Datenbank, die nur werktags genutzt wird, kann mit Auto-Pause nachts schlafen und kostet dann 0 € in diesen Stunden. Entwickler können auch manuell via Skript eine DB pausieren (ALTER DATABASE … Pause geht im Portal oder via PowerShell), um sie gezielt stillzulegen. Bei Bedarf wird sie wieder resumed. Beachten: Der erste Zugriff nach Pause hat eine Kaltstart-Latenz (paar Sekunden bis die VM springt). Das sollte im Dev-Betrieb tolerierbar sein.
- Kleinere Leistung für Test: Oft reichen in Dev/Test geringere Leistungsstufen (z.B. 2 vCores statt 8 in Prod). Man kann in Azure schnell eine DB hoch- oder herunterskalieren. Es ist üblich, vor einer Testphase z.B. auf eine kleinere Stufe zu schalten, um Geld zu sparen, und nur wenn man Performance-Tests macht, kurz hoch zu drehen. Ebenso kann man nach Feierabend eine MI oder VM herunterfahren (MI bietet seit 2021 Stop/Start-Funktion, sodass Compute nicht berechnet wird im Stopped-Zustand bis zu 7 Tage).
- Nicht-produktive Umgebungen zusammenlegen: In der Cloud zahlt man pro Ressource. Es kann sinnvoll sein, z.B. für Integrationstests eine einzige MI zu verwenden, die mehrere Test-Datenbanken trägt, statt viele einzelne Azure SQL DBs zu betreiben – je nachdem, was günstiger ist. MI General Purpose mit 4 vCores kann evtl. 10 Test-DBs beherbergen und ist günstiger als 10 getrennte DBs mit je 1 vCore, zumal MI Dev/Test-Lizenz anwendbar. Hier sollte man Kosten vergleichen und auf Flexibilität achten (man verliert z.B. die Auto-Pause-Möglichkeit in MI).
- Azure SQL Edge/Local Emulator: Für wirklich isoliertes Entwickeln (z.B. auf dem eigenen Laptop oder CI-Pipeline) gibt es auch die SQL Server Developer Edition oder Azure SQL Edge (Container). Diese kosten nichts und erlauben lokalen Test gegen eine ähnliche Engine. Allerdings unterscheiden sie sich etwas (Azure SQL Edge ist abgespeckt). Die Developer Edition entspricht einer Enterprise SQL Server und kann zur Entwicklung genutzt werden, darf aber nicht produktiv eingesetzt werden.
Beispielhafte Kostenbetrachtung: Zwei typische Szenarien sollen verdeutlichen, wie sich die Kosten je nach Modell unterscheiden können. (Anmerkung: Preise geschätzt, fiktiv, zur Illustration – Stand Ende 2025, Region Westeuropa, Währung €.)
- Szenario A – „API-Dienst 24/7“: Eine ständig laufende Produktionsanwendung mit konsistenter Last, z.B. ein zentrales Modul mit einer Datenbank. Angenommen, es werden ~2 vCores Performance benötigt. Option: Azure SQL Database General Purpose, 2 vCores, 32 GB, 100 GB Storage. Pay-as-you-go (lizenzinkl.) würde ca. 400 € pro Monat kosten. Mit Azure Hybrid Benefit (eigene Lizenz) reduziert sich das auf ~250 €. Wenn man zudem 3 Jahre reserviert, sinkt es weiter auf etwa 150 €/Monat. Über 3 Jahre Laufzeit summieren sich die Einsparungen deutlich. -> Empfehlung: Für so einen dauerhaften Dienst lohnt sich vCore provisioned mit AHB+Reserved. Serverless wäre hier weniger geeignet, da die CPU dauerhaft genutzt wird – man würde fast immer den Maximalwert bezahlen und hat Overhead durch ständig Hochgefahren-Bleiben.
- Szenario B – „Event-getriebene Last mit Serverless“: Stellen wir uns eine Anwendung vor, die unregelmäßig gebraucht wird – etwa ein interner Tool-Service, der tagsüber hin und wieder Queries bekommt und nachts gar nicht. Hier könnte man Azure SQL Database Serverless einsetzen, z.B. mit min 0,5 vCores, max 4 vCores, Auto-Pause nach 1 Stunde. Angenommen, im Schnitt über den Monat ist die DB aktiv für 8 Stunden pro Werktag auf ~2 vCores Auslastung und pausiert sonst. Die Abrechnung würde sich aus tatsächlicher vCore-Zeit (~8h * 21 Tage * 2 vCore = 336 vCore-Stunden) plus Speicher ergeben. Das könnte rund 90 € im Monat ausmachen – im Vergleich zu vielleicht 400 €, wenn man 4 vCores dauerhaft gebucht hätte. Nachts und am Wochenende (ca. 65% der Zeit) werden 0 € Compute fällig. -> Erkenntnis: Bei unstetiger Nutzung spart Serverless massiv Kosten. (AHB/Reservation entfallen hier, aber braucht man auch nicht bei so geringer Grundlast.)
Insgesamt gilt: Sie sollten die Workload-Charakteristik Ihrer Anwendung kennen – Dauerlast vs. Peaklast vs. seltene Nutzung – und daraufhin das Modell wählen. Azure bietet auch einen Kostenrechner und Empfehlungen im Portal (“richtige Größe finden”), die helfen, das optimale Tier zu ermitteln. Für Entwickler heißt das konkret: Bei Architektur- und Deployment-Entscheidungen stets auch die Kostenimplikationen im Hinterkopf behalten. Eine gute Zusammenarbeit mit FinOps/IT-Management ist sinnvoll, um nicht nur technisch, sondern auch wirtschaftlich die beste Lösung zu bauen.
<br>
5. Fünf typische Szenarien
In diesem Kapitel werden fünf häufige Einsatzszenarien für Azure SQL skizziert. Jedes Szenario beschreibt ein Zielbild, die empfohlene Azure SQL-Variante/Tier, Hinweise zur Architektur und – wo passend – Code-/Konfigurationsbeispiele. Außerdem werden besondere Betriebs- und Kostenaspekte sowie mögliche Fallstricke (Anti-Pattern) erwähnt.
5.1 Cloud-native Microservices mit Datenbank pro Service
Szenariobeschreibung: Ein Unternehmen entwickelt eine Cloud-native Anwendung nach dem Microservices-Architekturmuster. Jeder Microservice besitzt seine eigene Persistenz (Datenspeicherung), um Entkopplung und unabhängiges Deployment zu gewährleisten. Die Services werden in Azure (z.B. als Azure Kubernetes Service oder App Service) betrieben. Für die Datenbanken möchte man ebenfalls eine Cloud-Lösung, die minimalen Wartungsaufwand hat, skalierbar ist und sich nahtlos in CI/CD-Pipelines einfügt.
Zielbild: Pro Microservice wird eine Azure SQL Database (Single) bereitgestellt. Diese liegt idealerweise auf einem gemeinsamen logischen SQL-Server (für administrative Einfachheit), jedoch streng isoliert auf Datenebene (keine Cross-DB-Queries). Die Services kommunizieren über APIs; direkte DB-übergreifende Calls sind vermieden – das entspricht Domain-Driven Design, wo jeder Service seine eigene Datenbank hat. Im Deployment-Aspekt heißt dies: Bei Bereitstellung eines neuen Microservice wird via Script oder Terraform eine neue Azure SQL DB angelegt und das Schema ausgerollt (z.B. via EF Core Migrations oder DACPAC).
Empfohlene Tier/Optionen: Oft reicht für einzelne Microservices eine General Purpose-Datenbank mit wenigen vCores. Je nach Lastprofil könnte auch Serverless in Frage kommen – z.B. wenn der Service nur sporadisch genutzt wird oder über Nacht idle ist. Alternativ, wenn extreme Performance nötig, könnte ein Service auf BC oder Hyperscale wechseln (aber das wäre eher Ausnahme). Wichtig ist: Die Wahl pro Service kann individuell sein. Azure ermöglicht es, unterschiedliche Datenbanken auf einem Server mit unterschiedlichen Tiers zu betreiben. Für Microservices, die stark unterschiedlich kritisch sind, kann man maßgeschneidert zuteilen (z.B. Order-Service auf Business Critical 4 vCores wegen hoher Transaktionsrate, Reporting-Service auf GP 2 vCores). Falls sehr viele Microservices existieren (hunderte), sollte man gruppieren – vielleicht pro Domäne einen Azure SQL-Server oder Pools verwenden.
Architektur-Skizze: Jeder Microservice läuft unabhängig. Der Connection-String zum eigenen Datenbank steht typischerweise in der jeweiligen Service-Konfiguration (idealerweise im Key Vault hinterlegt). Kommunikation zur DB erfolgt über ADO.NET/EF Core. Es gibt keine direkten Verbindungen von einem Service auf die DB eines anderen. Dadurch kann jeder Service auch separat skalieren (auch die DB). Beispielsweise könnte man temporär den vCore einer Engpass-Datenbank hochsetzen, ohne die anderen zu beeinflussen. Hochverfügbarkeit kommt out-of-the-box durch Azure SQL, also kein gemeinsames Failover-Szenario über Services nötig. Jeder Datenbank schreibt in eigene Logs, Query Store etc., sodass auch Observability pro Service getrennt möglich ist.
Minimale Code-/Konfigurationsbeispiele: Im Microservice-Code wird EF Core häufig benutzt. Die Migrationen sind service-spezifisch. Ein Beispiel für eine Migration (Code-First) aus Sicht eines Microservices:
// Im Startup des Microservice oder Deployment-Script:
using var db = new ServiceXDbContext();
db.Database.Migrate(); // wendet neueste EF Core Migrationen auf Azure SQL DB an
// Alternativ, in CI/CD Pipeline via dotnet ef CLI:
// dotnet ef database update –connection „<Azure SQL ConnectionString>“ –context ServiceXDbContext
Dieses kurze Snippet zeigt, wie ein Service beim Start automatisch sein Schema aktualisieren kann. Allerdings muss man vorsichtig sein: In Produktion will man das kontrollierter handhaben (z.B. via Pipeline), um Downtime zu vermeiden. Daher oft Migrationen separat ausführen vor dem Hochfahren des neuen Service-Codes (um sog. rolling updates zu ermöglichen ohne Schema-Konflikte).
Eine weitere Überlegung ist Verbindungsverwaltung: In .NET sind Connection Pools per Default aktiviert, man sollte diese nutzen und nicht pro DB-Operation eine neue Verbindung aufbauen. Der Microservice sollte zudem resilient sein: Wenn Azure SQL mal einen Failover hat, erleidet die DB kurz (<5s) einen Aussetzer – mittels Retries im Code (z.B. wie oben EnableRetryOnFailure) übersteht der Service das ohne Ausfall.
Betriebs- und Kostennoten: Mit einem DB-pro-Service-Ansatz können sich schnell viele Datenbanken ansammeln. Azure SQL erlaubt z.B. 5000 DBs pro Server, was reichlich ist, aber man sollte ggf. pro Projekt/Team trennen. Kosten: Jede DB verursacht mindestens Grundkosten (auch wenn klein). Für 50 Microservices je 5 € kann das summieren. Hier kann man überlegen, ob Elastic Pools sinnvoll wären, um Ressourcen zu konsolidieren. Pools machen Sinn, wenn Lastspitzen sich nicht bei allen Services gleichzeitig zeigen. Ansonsten, bei unabhängigen Workloads, kann auch Serverless per DB eine einfache Lösung sein: dann zahlt jeder Service nur, was er braucht. Monitoring: Es empfiehlt sich, gewisse Standards für alle Service-DBs zentral zu konfigurieren – z.B. Threat Detection aktivieren, Minimale TLS-Version, Geo-Backup aktivieren falls verlangt. Azure Policies können das enforce-en.
Risiken / Anti-Pattern: Man sollte vermeiden, doch wieder feste Kopplungen zwischen den DBs einzuführen – z.B. durch im Code einer Domain auf die DB einer anderen zuzugreifen. Das bricht die Isolation und macht Service-Updates riskant. Besser sind immer API Calls zwischen Services. Weiterhin muss man beim Logging/Tracing über Microservices hinweg aufpassen: verteilte Transaktionen über Services sind anti-pattern – stattdessen Saga/Choreography-Muster nutzen. Mit Azure SQL pro Service hat man diese Möglichkeit ohnedies nicht (keine cross-db trans), was aber gut ist, da es zu moderner Architektur passt.
Insgesamt ist Azure SQL für Microservices attraktiv, da es robust, vertraut und gut integrierbar ist. Es passt besonders, wenn man primär relationale Daten braucht und nicht auf NoSQL geht. Dank autom. Management skaliert es mit, auch wenn die Anzahl Services wächst.
5.2 SaaS-Multi-Tenant-Anwendung (Datenbank- oder Schema-Multi-Tenancy)
Szenariobeschreibung: Ein Softwareanbieter baut eine Software-as-a-Service (SaaS)-Plattform, die vielen Kunden (Mandanten) dient. Aus Sicherheits- und Customizing-Gründen sollen die Daten der Mandanten sauber getrennt sein. Es gibt zwei übliche Ansätze: Datenbank-Pro-Mandant (jeder Kunde hat seine eigene DB mit identischem Schema) oder Multi-Tenant-DB (alle Kunden in einer gemeinsamen DB, dort Isolation z.B. via TenantID und Row-Level Security). Azure SQL unterstützt beide Modelle – hier betrachten wir insbesondere die Variante mit separaten Mandanten-Datenbanken, da Azure dafür spezielle Mechanismen (Elastic Pools, etc.) bietet.
Zielbild: Für jeden neu gewonnenen SaaS-Kunden wird automatisiert eine eigene Azure SQL Datenbank bereitgestellt, die das Standard-Schema enthält. Die Anwendungsschicht kennt den jeweiligen Mandantenkontext und leitet Anfragen an die richtige DB weiter (z.B. Connection-String pro Tenant). Option A: Alle diese Mandanten-DBs liegen in einem Elastic Pool zusammen, um Ressourcen zu teilen. Option B: Bei größeren Kunden bekommen manche Mandanten eine dedizierte Datenbank mit eigenen Ressourcen (ggf. sogar in eigenem Pool). Der SaaS-Anbieter kann je nach Kundengröße differenzieren (z.B. Tiered Offering: „Shared DB“ vs „Isolated DB“). Fokus ist auf PaaS-Vorteile – das System soll ideal skalieren, wenn Dutzende oder Hunderte neuer Mandanten dazukommen.
Empfohlene Tier/Optionen: Elastic Pools sind für viele kleinere Mandanten ideal. Man würde z.B. einen Pool mit X vCores definieren und dort bis zu Y Mandanten-DBs reinpacken, wobei alle zusammen X vCores nutzen. Azure sorgt dafür, dass kein einzelner Mandant alles frisst (per interne Fairness-Logik), aber es ist möglich, dass bei ungewöhnlicher Gleichzeitigkeit der Pool voll ausgelastet wird – daher Pools mit Bedacht dimensionieren. Oft wählt man Pools pro „Mandantengruppe“ (z.B. 50 Kunden pro Pool). Wenn ein Mandant wächst und konstant hohe Ressourcen braucht, kann man ihn aus dem Pool herausnehmen und auf eine eigene Single Database (vCore) umziehen, um ihm dedizierte Leistung zu geben. Azure erleichtert das: eine DB kann mit einem einfachen Kommando einem Elastic Pool zugewiesen oder daraus entfernt werden. Bei sehr vielen Mandanten (>1000) kann man Pools hierarchisch managen (z.B. 20 Pools mit je 50 DBs).
Alternative: Bei einer gemeinsamen Multi-Tenant-DB (eine DB, alle Kunden drin), sollte man Row-Level Security aktivieren und darauf achten, dass Abfragen gut mandanten-geeignet sind (z.B. alle relevanten Indizes immer TenantID als erstem Key enthalten). Auch Partitionierung nach Tenant oder separate Schemas pro Tenant können helfen. Diese Alternative ist tendenziell schwieriger in Sachen Data Governance und DB-Wartung (ein riesiger DB mit allen Kunden). Der initiale Ansatz mit DB pro Tenant ist meist sauberer für Isolation (z.B. einfaches Backup/Restore eines Mandanten, keine Risiken, dass man Abfragen vergisst zu filtern etc.).
Mandanten-Onboarding/Deployment: Wichtig ist, das Prozess automatisch zu gestalten. Onboarding eines neuen Kunden sollte z.B. per Script: (1) neue DB erstellen (kann Kopie einer leeren Template-DB sein oder via DACPAC Deploy), (2) Schema up-to-date bringen, (3) initiale Daten (Stammdaten o.ä.) einfügen, (4) Mandant konfigurieren (Connection-Info ins App-Config). Azure bietet hier Hilfen: Mit Azure SQL Deployment API oder ARM/Bicep kann eine DB Ressource angelegt werden. Auch im Code könnte ein Administrations-Service von sich aus CREATE DATABASE … ausführen (erfordert entsprechendes priviligiertes Login). Manche SaaS-Lösungen nutzen Pooling: leere DBs stehen bereit und werden nur noch umbenannt und zugewiesen, um Onboarding in Sekunden zu machen.
Minimale Codebeispiele: Ein T-SQL-Snippet zum schnellen Bereitstellen einer Mandanten-DB könnte so aussehen (ausgeführt auf dem Master der logischen Server):
— Lege neue Mandanten-Datenbank an, mit Basis-Konfiguration
CREATE DATABASE TenantDB_Contoso
( SERVICE_OBJECTIVE = ‚ElasticPool‘, ELASTIC_POOL = [Pool_SaaSKunden] );
GO
— Nach Erstellung könnte man initiales Schema deployen, z.B.:
— EXEC TenantDB_Contoso.sys.sp_executesql N'<Schema-Setup-Script>‘;
In der Anwendung würde die Verbindungslogik je nach Tenant entscheiden:
string tenant = GetTenantFromRequest(request);
using var conn = new SqlConnection(GetConnectionStringForTenant(tenant));
…
Dies kann auf Dauer unübersichtlich werden, daher verwalten SaaS-Anbieter oft eine Mapping-Tabelle Mandant -> ConnectionString, und verwenden Connection Pooling effizient (wichtig: Pools sind pro ConnectionString, d.h. pro Mandant).
Betrieb & Skalierung: Mit dem DB-per-Tenant Ansatz hat man den großen Vorteil, dass Isolation nicht nur sicherheitlich, sondern auch betrieblich da ist: Ein Tenant kann bei Fehlern seine DB „zerstören“ ohne andere direkt zu beeinträchtigen. Und Backups/Wiederherstellungen gehen tenant-spezifisch: Sollte ein Kunde z.B. versehentlich Daten löschen, kann man dessen DB aus Backup auf einen separaten Server restore-n und einzelne Tabellen zurückspielen, alles ohne die Plattform an sich zu gefährden. Auch Updates: Schema-Änderungen müssen zwar in alle DBs ausgerollt werden, aber das kann man mandantenweise tun und notfalls Problemkunden einzeln behandeln. (Automatisierung via Scripting oder Azure Pipelines Release mit parallelen DB Upgrades in Batches ist hier ratsam.)
Kostenaspekt: Pools lohnen sich, wenn Kunden unterschiedlich und eher niedrig lasten. Sollte man viele “Idle” DBs haben (z.B. Testmandanten, kleine Kunden), packen sie zusammen. Für sehr große Mandanten wäre ein eigener Pool oder dedizierte Instanz (z.B. MI für premium Kunden) denkbar – so kann man ein Staffelpreismodell technisch untermauern. Azure erlaubt flexible Moves. Beachte: Jeder Pool hat einen Fixkostenblock (z.B. 50 vCore-Pool = Preis X). Wenn nur 2 DBs drin sind, ist es ineffizient. Also Pools erst ab gewisser Masse nutzen. Für 1–5 Mandanten tut es evtl. eine einzelne Datenbank mit Multi-Tenancy (um Startkosten zu sparen), und später auftrennen.
Risiken/Anti-Pattern: – Unkontrolliertes Wachstum: Wenn pro Kunde eine DB entsteht, hat man schnell sehr viele DBs. Zwar verwaltet Azure das gut, aber Dinge wie monitoring, schema update etc. müssen skaliert werden. Anti-Pattern wäre, man macht Schema-Änderung manuell in 100 DBs – lieber Skripte oder Tools (es gibt z.B. Elastic Jobs Service, der SQL-Commands auf alle DBs in einem Pool ausführt). – Ungleiche Performance: In Pools kann ein “lauter Nachbar”-Effekt auftreten: ein Mandant zieht viel Leistung, andere leiden. Azure Pools haben per-database min vCores (Minimale DTUs) optional, das sollte man ggf. setzen für kritische DBs. Aber zu strenge Isolation widerspricht dem Pool-Gedanken. Anti-Pattern: Alle Mandanten in einem Pool belassen, obwohl ein paar ständig Limits sprengen – besser diese rausziehen auf eigene Ressourcen. – Zuviel Verbindungen: Wenn App-Server pro Tenant z.B. separate connection pools hat, könnte es bei tausenden Tenants zu vielen offenen Verbindungen kommen. Hier auf Limit (Azure SQL erlaubt ~64000 connections per server) achten und z.B. Verbindung nur aufbauen bei Bedarf, wieder schließen (Connection-Pooling vom .NET Framework hält sie ja warm). Usually kein Problem, aber im Extremfall ja.
Im Ganzen bietet Azure SQL hier nahezu perfekte Mandantenisolation und skalierbare Infrastruktur, was ein großer Vorteil gegenüber On-Prem oder Shared-DB-Lösungen ist. Viele SaaS-Anbieter wie z.B. Multi-Tenant ERP-Systeme setzen genau auf diese Strategie.
5.3 Lift-and-Shift einer bestehenden Anwendung mit speziellen SQL-Abhängigkeiten
Szenariobeschreibung: Eine bestehende Unternehmensanwendung (monolithisch oder verteilt) soll in die Cloud migriert werden („Lift-and-Shift“). Diese Anwendung nutzt SQL Server on-premises mit etlichen instanzspezifischen Features: z.B. SQL Server Agent Jobs zur Nachverarbeitung, eventuell Linked Servers zu anderen Datenquellen, Cross-Database Stored Procedures, eventuell CLR-Assemblies für besondere Berechnungen, oder Service Broker für interne asynchrone Verarbeitung. Die Anwendung wurde nicht für Azure PaaS geschrieben, man möchte aber dennoch vom Wegfall des Infrastruktur-Managements profitieren.
Herausforderung: Azure SQL Database (Single) würde viele dieser Features nicht bieten, so dass eine umfangreiche Refaktorisierung nötig wäre. Daher wählt man Azure SQL Managed Instance als Zielplattform, da sie maximale Kompatibilität verspricht und On-Premises-ähnliche Fähigkeiten hat.
Zielbild: Die bestehende SQL Server-Instanz (oder relevante Datenbanken daraus) werden in eine Azure SQL Managed Instance migriert. Möglichst ohne Änderungen sollen die Datenbanken dort laufen. Idealerweise bleiben Verbindungstrings gleich bis auf den Servernamen, und die Applikation merkt kaum einen Unterschied. MI erlaubt Agent-Jobs, Cross-DB Queries, CLR (teilw.) etc., so dass die Anwendung weiterhin funktioniert. Zusätzlich wird die MI ggf. in ein Azure VNet integriert, damit z.B. die App-Server (vielleicht in einer VM oder AKS) im gleichen Netzwerk kommunizieren können – oder falls noch Teile on-prem bleiben (Hybrid), die MI über VPN/ExpressRoute erreichbar ist.
Bedarf an MI: Folgende Abhängigkeiten würden MI erfordern (Beispiele): – Verwendung von SQL Server Agent: z.B. nächtliche Wartungsjobs, E-Mail-Alerts (DB Mail) –> MI hat SQL Agent und DB Mail. – Verteilte Transaktionen oder verteilte Abfragen: z.B. es gibt Prozeduren, die in zwei DBs schreiben, oder eine Synonym auf eine andere DB –> Single Azure SQL geht nicht, MI ja (zumindest innerhalb der MI). – SQL CLR Assemblies: MI erlaubt SAFE assemblies. Wenn App solche nutzt, MI kann es oft ausführen (sofern kein unsicherer Code). – Linked Server zu extern (z.B. zu Oracle oder ein Legacy SQL): MI erlaubt Linked Server zu SQL (ohne DTC), aber NICHT zu OleDB z.B. Oracle (das geht on-prem via OleDB provider). Hier müsste man ggf. anders vorgehen – z.B. App-Layer koppeln. Aber falls nur zu anderen SQL, MI klappt. – Service Broker: MI unterstützt SB, die Anwendung kann also weiterhin DB-übergreifende SB queues nutzen (sofern alle benötigten DBs in der MI sind). – Spezielle Einstellungen: z.B. DB mit Zeitstempel auf US-English (Kollation etc.), oder Applikation nutzt xp_cmdshell um Files zu kopieren (in MI nicht möglich -> Workaround: diese Teile extern ausführen).
Vorgehen Migration: Azure stellt für MI Migration z.B. Backup/Restore bereit: man kann eine .bak vom on-prem DB in Azure Blob Storage ablegen und MI direkt RESTORE DATABASE … FROM URL ausführen (MI exklusives Feature). So kriegt man ein exaktes Abbild rein. Alternativ Azure Database Migration Service kann mit minimalem Downtime über Transactional Replication oder Log Shipping (Log Replay Service) migrieren. Von Applikationsseite ist der Plan, keine Codeänderung oder minimal (vielleicht Connection Strings und eventuelle Pfade, falls bisher lokaler Pfad in Code statt UNC – da MI ja keinen C:\ hat, man muss sowas ändern falls vorhanden).
Empfohlene Tier/Größe: In MI hat man General Purpose vs Business Critical. Meistens, wenn on-prem ein Standard-Edition SQL genutzt wurde, reicht MI General Purpose. Wenn man einen SQL Cluster Enterprise ersetzt, könnte MI Business Critical passend sein (für Performance + HA). Größe in vCores wählt man entsprechend dem on-prem (z.B. OnPrem 8 core -> MI 8 vCore). Hybrid Benefit kann man nutzen (wenn on-prem Lizenz frei wird). Wichtig: MI erfordert VNet, also muss man im Azure Setup ein Subnet bereitstellen und MI erstellen was einige Stunden dauern kann. Das im Migrationsplan bedenken.
Architektur-Notizen: – Die MI agiert wie ein einziger SQL Server: Alle migrierten DBs landen dort. App-Server oder Services bekommen den MI-Endpoint (einen Hostname im Privaten Netz, Port 1433). – Falls die App selbst in Azure VM geht, sie kann denselben AD Domain Join haben etc. – MI unterstützt Azure AD aber auch on-prem AD Integration via Azure AD (man kann Azure AD mit On-Prem AD synchronisieren und MI Windows Auth mit Kerberos Keytab, aber das ist komplex; meist reicht SQL Auth oder Azure AD Auth). – Netzwerk: MI kann optional einen öffentlichen Endpunkt haben, standardmäßig aber nur intern. Sicherheitshalber belässt man es intern und nutzt Private Endpoint/Peering, sodass die Applikation sicher kommuniziert.
Empfohlene Änderungen/Optimierungen bei Migration: Obwohl MI den Lift&Shift erleichtert, sollte man dennoch prüfen: – Verbindungs-Timeouts und Retries anpassen (Cloud-Failover). – Nicht benötigte Altlasten entfernen (z.B. falls die DB immer noch einen veralteten Maint Job hatte – MI hat Azure-automatische Maint). – Überlegen, ob man gleich Managed Service ausnutzt: z.B. statt eigener Backup-Skripte dem MI-Backup vertrauen; statt DBCC CHECKDB via Agent evtl. auf wöchentliche Azure Integrity Checks verlassen (Azure macht intern Checksumming). – Monitoring umstellen: On-Prem SCOM oder Perfmon weicht Azure Monitor/Metrics.
Betrieb und Kosten: MI verursacht laufende Kosten nach vCores. Im Gegensatz zu Single DB kann man mehrere DBs in einer MI betreiben, was für Lift&Shift super ist (eine MI von 8 vCores kann 10 DBs hosten, man zahlt nur die 8 vCores gesamt, nicht pro DB). So gesehen ist MI preislich attraktiv, wenn man bisher einen SQL Server hatte mit vielen DBs – man bekommt PaaS-Mehrwert für alle gleichzeitig. Um Kosten zu sparen, AHB und Reservierungen nutzen. Dev/Test MIs (z.B. Testumgebung) kann man nachts per Stop deallokieren, um Kosten zu reduzieren – neuere MI-Funktion.
Risiken/Anti-Pattern: – Assumption, dass MI = 100% identisch zu on-prem. In der Praxis gibt es Kleinigkeiten: z.B. MI hat minimal höhere Latenz durch Azure Netz, sehr lange transactions könnten Timeout in Gateway riskieren (idle 30min?), oder features wie Filestream nie verfügbar. Wenn App genau so was braucht, müsste man anpassen. – Heterogene Umgebungen: Wenn App neben SQL auch z.B. SSRS (Reporting Services) on-prem hatte, muss man das separat lösen (SSRS läuft nicht in MI; Option: Power BI Report Server oder SSRS auf VM). Oder Integration Services: Azure Data Factory mit SSIS IR kann Pakete aus MI ausführen. Also man muss das Gesamtbild betrachten, MI deckt nur DB-Engine ab, nicht BI-Services. – Security neu konfigurieren: on-prem nutzt Windows Auth mit AD? MI kann Azure AD (empfohlen), d.h. man muss Benutzer zu Azure AD migrieren/synchronisieren. Ein Anti-Pattern wäre hier, alles weiter mit SQL Logins zu machen – besser auf Azure AD umstellen, wenn möglich, um Cloud-Integration zu haben.
Zusammengefasst: Azure SQL Managed Instance ist die Wahl, wenn man schnell in die Cloud möchte, aber Anwendung und DB so belassen wie sie sind. Es minimiert Code-Änderungen und reduziert Betriebsaufwand signifikant (kein Patch, kein Basis-Betrieb). Langfristig kann man dann entscheiden, ob man die App stärker modernisiert (z.B. Zerlegung in Microservices, Nutzung von Single DBs oder Cloud-native Tools). MI kann also auch eine Übergangslösung sein – aber viele bleiben auch dabei, da es bequem ist und ausreichend PaaS-Feeling gibt.
5.4 Analytik und Reporting auf einer OLTP-Datenbank (HTAP-Szenario)
Szenariobeschreibung: Eine operative Anwendung (OLTP-System) erfasst Daten – z.B. Transaktionen, IoT Events, Kundenaktivitäten. Gleichzeitig sollen Analysen und Berichte über diese Daten nahezu in Echtzeit möglich sein, ohne ein separates Data Warehouse mit ETL zu betreiben. Man strebt also eine HTAP-Lösung an (Hybrid Transactional/Analytical Processing): das gleiche System bedient transaktionale Workloads und parallele Analytical Queries. On-Premises war das oft schwierig, oder man hat mit Read-Replikaten gearbeitet.
Zielbild: Azure SQL kann hier mit einigen Features unterstützen: 1. Nutzung der Read-Scale-Fähigkeiten, um analytische Abfragen auf einen lesbaren Sekundärknoten auszulagern. Bei Azure SQL Database (Premium/BusinessCritical) etwa, wo eine High Availability-Replica vorhanden ist, kann man diese als Read-Replica einsetzen. Bei Managed Instance Business Critical ähnlich. Wenn noch mehr Power für Berichte nötig, können zusätzliche Geo-Replicas (in gleicher Region oder anderer Region) erstellt werden, die read-only sind – somit isoliert man Reporting vollkommen vom OLTP. 2. Columnstore-Indizes auf wichtigen Tabellen, um Aggregationen und Scans zu beschleunigen. Diese Indizes kann man auf der Primär-DB anlegen (Kompromiss: Schreiboperationen könnten minimal langsamer werden, aber Lese-Performance für Summen etc. steigt enorm). 3. Synapse Link for SQL: (in Azure SQL DB verfügbar) – das ist ein Feature, um operative Daten fast in Echtzeit in Azure Synapse Analytics bereitzustellen, ohne klassische ETL. Damit könnten Analysen in einem Spark/SQL Pool gemacht werden, parallel zum OLTP. Hier bleibt aber Fokus auf PaaS in Azure SQL selbst.
Empfohlene Architektur: Die OLTP-Datenbank läuft beispielsweise im Business Critical-Tier mit 8 vCores. Dadurch hat sie ein synchrones Sekundär in der Region. Dieses Sekundär wird für Reporting genutzt: Das Berichtstool (z.B. Power BI oder eine Webreport-Funktion) stellt Verbindung mit ApplicationIntent=ReadOnly her. Azure leitet diese an das Read-Only-Replica. Somit stören große SELECTs (wie „Umsatz pro Region über 12 Monate“) nicht die primäre DB. Der Read-Replica hat jedoch denselben Datenstand (max ein paar ms hintendran) und kann deshalb aktuelle Auswertungen liefern. Falls das nicht genug ist, könnte man noch ein Geo-Replica in einer zweiten Region erstellen, welches z.B. für ein Data Science Team genutzt wird, damit selbst bei starker Belastung das primäre System unberührt bleibt.
Query Store und Tuning: In diesem gemischten Szenario ist Query Performance sehr wichtig. Entwickler sollten den Query Store nutzen, um Abfragen zu analysieren. Der Query Store zeigt z.B. welche Reporting-Abfragen besonders viel Ressourcen nehmen. Dann kann man gezielt optimieren: Vielleicht Materialized Views (Azure SQL unterstützt Indexed Views, einschränkt aber Nutzung bei Partitionierung?), oder eben Columnstore anlegen. Parameter Sniffing kann auftreten – OLTP hat andere Parameterverteilungen als OLAP-Query. Hier hilft ggf. Query Store mit Force Plan pro spezifischer Query-ID (z.B. die Reporting-Query soll immer einen bestimmten Plan nutzen, damit OLTP Abfragen davon nicht beeinflusst werden).
Grenzen von HTAP: Man sollte klar benennen: Azure SQL ist primär OLTP. Es kann etwas Analytics aber kein Ersatz für ein dediziertes Data Warehouse, wenn Datenvolumen stark wächst. Grenzen: – Konzurrenz: Trotz Read-Replica, alle Schreibvorgänge müssen synchron auf die Replica (in BC) – sehr aufwändige Lesequeries könnten Indirekt auch die primäre Performance beeinflussen, indem Resourcen (I/O auf replica, die teilt mit primär?) strapaziert werden. In Business Critical sind Primär und Sekundär auf selben Node-Set, können sich CPU streitig machen? Microsoft sagt nein, aber in Praxis spürt man bisschen. – Memory/DW: Für wirklich große analytische Abfragen (die evtl. mehr Memory bräuchten als DB hat), stößt man an Limit. Ein Synapse oder externer OLAP Cube kann besser skalieren. – Parallelität: Azure SQL hat Limits in paralleler Query Execution (max degree, threads). Eine große Query kann auf 8 vCores laufen, aber eine spezialisierte Analytics-Lösung mit MPP (Massively Parallel Processing) skaliert besser horizontal.
Praxis-Empfehlung: – Führen Sie regelmäßige Index-Wartung durch (Azure macht in BC tier Teil davon). Columnstore Indexe brauchen z.B. Reorganisation (Trimming deltastores). – Nutzen Sie Secondary for heavy read – und bedenken Sie, dass dieses Read-Replica im Failover-Fall wegfällt (wenn Failover passiert, wird ehemals Secondary Primär und vice versa, kurz offline die Leseconnects). Aber da Failover selten, ok. – Wenn mit Geo-Replica gearbeitet wird: Abfragen dort sind asynchron behind (Latenz so 5 sec). Das heißt, Echtzeit – 5 sec ist meist okay. Aber wenn absolute Synchronität gebraucht, bleiben Sie in Region. Geo-Replica fürs Reporting toll, aber dann Berichte haben Stand z.B. „bis vor wenigen Sekunden“.
Code-Beispiel Reporting Connection:
var connStr = „Server=myserver.database.windows.net; Database=ProdDB;
Authentication=Active Directory Integrated; ApplicationIntent=ReadOnly;“;
using var conn = new SqlConnection(connStr);
// Diese Verbindung geht automatisch zum Read-Only Secondary (im BC Tier).
Betrieb & Kosten: Ein Business Critical-DB ist teurer, aber hier doppelt nützlich (Performance + HA + Read-Replica “gratis”). Falls Last vor allem lesend ist, könnte man sogar vCores reduzieren dank Columnstore – manchmal sieht man, dass man statt 8 vCores nur 4 brauchte nach Index Tuning, das spart Kosten. Oder Hyperscale als Option: Hyperscale erlaubt bis zu 4 Named Replicas, man könnte 3 davon rein für Reports nutzen, und Hyperscale’s storageseitige Offloading macht Reads sehr skalierbar. Hyperscale hat aber leicht höhere Latenz auf OLTP (eine Layer dazwischen). Es ist Abwägung. Wenn DB > 4TB, Hyperscale quasi Pflicht.
Anti-Pattern: – Alles in einer DB, einfach Berichte drauf ohne Hilfsmittel. Wenn man Columnstore und Read-Replica NICHT nutzt, kann es schlecht enden: Analytical Abfragen blockieren evtl. OLTP (z.B. Shared locks, obwohl SELECT, können noch minimal stören und CPU belegen). – Transaction Isolation: Beachten: Lese-Replica sind read committed mit readable secondaries. Wenn man Analytical Queries auf Primär-DB machen müsste, sollte man READ COMMITTED SNAPSHOT aktiv haben, um keine Blocks auszulösen (Azure SQL DB hat das standardmäßig ON). – Keine Aggregation: Falls Berichte immer wieder Rohdaten summieren, vllt. mal Materialisierte Zusammenfassungen erwägen (z.B. täglich Periode abschließen, Zwischenergebnisse speichern). Sonst rechnet man tausendmal denselben Umsatz.
Fazit: Azure SQL kann moderate HTAP toll unterstützen, aber jenseits eines Punktes muss man eventuell auf Synapse Analytics oder Power BI Data Marts ausweichen, um sehr komplexe Analysen historischer Daten auszulagern. Für Real-Time Reporting aber sehr gut geeignet dank Replikation und Columnstore.
5.5 Entwicklungs- und Testumgebungen effizient betreiben
Szenariobeschreibung: In typischen DevOps-Setups gibt es neben Produktion mehrere nicht-produktive Umgebungen: Entwicklungs-Datenbanken, Continuous Integration (CI) Datenbanken für automatisierte Tests, Staging/UAT-Umgebungen, Demo-Systeme usw. Diese Umgebungen müssen möglichst die Produktionsbedingungen simulieren, aber sollen kostengünstig sein, da sie meist keinen direkten Kundennutzen bringen. Zudem möchte man sie schnell aufsetzen, zurücksetzen und eventuell parallel mehrfach erzeugen können (z.B. jede Feature-Branch baut eigene Test-DB auf).
Zielbild: Azure SQL bietet verschiedene Features, um Dev/Test effizient zu gestalten: – Serverless DBs mit Auto-Pause für Entwicklungs- oder Demo-Datenbanken, die nur sporadisch genutzt werden (Abrechnung nur bei Nutzung). – Klonen bzw. Kopieren von Datenbanken, um z.B. einen aktuellen Produktionsstand in Staging bereitzustellen. – Verwendung von BACPACs oder Dacpacs in CI-Pipelines, um Schemata und kleine Musterdaten leicht einzuspielen. – Eventuell paralleler Betrieb mehrerer isolierter Test-DBs auf einer geteilten MI oder Pool, um Kosten zu drücken. – Azure Dev/Test Pricing: falls lizenziert, über Abonnements nutzen.
Beispiel Dev/QA Workflow: Ein Team möchte Integrationstests gegen eine “echte” SQL DB fahren (anstatt In-Memory-SQL-Emulator). In der CI-Pipeline (z.B. Azure DevOps) kann man mittels Azure CLI ein neues Azure SQL Database (Serverless) erstellen, Schema darauf migrieren und Tests ausführen. Danach wird die DB wieder gelöscht. So hat jeder Pipeline-Run isoliert seine DB. Kosten fallen nur für ~30 Minuten an (Peanuts). Da es parallel laufen muss, kann man pro Pipeline Run einen anderen DB Namen nutzen (oder suffixed) – Azure erlaubt zig parallel DBs. Alternativ: Man nutzt ein festes Test-Datenbank-Setup, die jeweils bereinigt wird nach Tests (Reset der Daten durch Transaction Rollback oder neu laden eines BACPAC mit Known State). Azure SQL unterstützt schnelle DELETE + re-insert Ansätze, aber vllt. ist drop/create schneller.
Schnelle Datenbereitstellung: Für Staging oder Performance-Tests möchte man oft einen möglichst aktuellen Prod-Abzug. Wege: – Azure SQL Point-in-Time Restore: Man kann ein Prod-Backup in derselben Serverinstanz auf einen neuen DB-Namen restoren. Azure Portal/PowerShell bietet Restore-AzSqlDatabase -FromPointInTime. Damit erstellt man z.B. ProdDB_COPY mit Stand von gestern 23:00. Das dauert je nach DB-Größe ein wenig, aber ist bequemer, als irgendwo bak rumzuhantieren. Nach Erstellen sollte man ggf. Maskierungs-Skripts drüber laufen lassen (PII entfernen). – Copy Database: Wie vorhin erwähnt, CREATE DATABASE X AS COPY OF ProdDB. Das ist intern schnell (im selben Datenzentrum per Snapshots). Für große DBs ist das deutlich schneller als BACPAC Import/Export, da es seitenbasiert kopiert. Ein 100 GB DB kann in wenigen Minuten dupliziert werden. – BACPAC: Wenn man Prod nicht direkt anfassen darf, kann man BACPAC (Schema+Data Export) nutzen, aus Storage ziehen und in Azure SQL dev importieren. BACPAC-Import kann aber je nach Datenvolumen langsam sein und VarChar Max etc. stören mit LOB copys. Aber es hat den Vorteil, dass man die BACPAC file manipulieren könnte (z.B. als JSON entpacken, Replace PII). – In Managed Instance: Backup vom Prod (falls Prod on MI oder on-prem) to URL, dann in MI wiederherstellen.
Kosteneffizienz: – So viel wie möglich herunterskalieren in Nicht-Prod: z.B. eine Staging DB braucht oft nicht gleiche vCores wie Prod, außer man macht Lasttests. Man könnte Standard-mäßig Stage mit 2 vCores betreiben, und nur für Performance-Test-Woche mal auf 8 vCores hochskalieren, danach wieder runter. – Auto-Pause Serverless: Entwicklungs- und insbesondere individual developer databases können wunderbar im Serverless mode sein mit 30min Autopause. Ein Entwickler testet was, geht Mittag – DB pausiert, nachmittags resumed in ~10s – fine. So eine DB könnte im Monat <20 € kosten statt 200 € im Provisioned. – Gemeinsame MI für Dev: Wenn mehrere interne Projekte DBs brauchen, kann es günstiger sein, eine MI GP mit 8 vCores zu nehmen und dort 20 DBs reinzutun, als 20 Einzel-DBs 1 vCore. Der Overhead pro DB fällt weg. Nachteil: alle teilen sich Ressourcen, gib ggf. “lärm” Effekte. Kommt drauf an, wie isoliert man sie will. – Kurzlebige Umgebungen zerstören: Nicht vergessen, unbenutzte Umgebungen abzuschalten. Mit Infrastructure as Code kann man testumgebungen bei Bedarf neu hochziehen, also kann man es sich leisten, sie nachts zu löschen und morgens neu zu machen. Oder auto-shutdown (gibt es in VMs, in DB nicht aber man kann using azure automation do drop). – Monitoring budgets: man kann in Azure Budgets definieren: z.B. Test subscription 100 € monatlich, warnt bei 80%. So sieht man, wenn wer versehentlich ne BC-DB laufen ließ.
Risiken/Anti-Pattern: – Prod-Daten in Test ohne Masking: Heikel, aber oft pragmatisch. Falls tun, unbedingt Data Masking oder Anonymisierung (z.B. randomize names) einplanen. Azure’s Dynamic Data Masking ist mehr für laufenden Betrieb, für Staging lieber ein Script, das z.B. alle Email Adressen zu fake@muster.com macht etc. Auch Always Encrypted Felder in Prod muss man beachten – in Testumgebung könnte man mit anderen Schlüsseln arbeiten, oder die Spalten unverschlüsselt führen (sofern das Testen der Encryption nicht Fokus ist). – Testumgebungen vernachlässigen: Anti-Pattern ist, Test-DBs ewig alt, Schema hinkt Prod hinterher – dann taugen Tests wenig. Mit Azure DevOps kann man Schema compare und Synch Steps einbauen, um Stage stets auf Prod-Level zu halten (Migrations sollten auf Stage vor Prod laufen). – Einsparungen vs Realismus: Wenn man zu sehr speckt (z.B. Prod nutzt BC 16 vCore, Stage nur 2 vCore GP), dann Performance-Test auf Stage wenig wert. Also für Performance-Untersuchungen lieber mal hochskalieren. – Viele parallel DBs in CI: Auf DB-Ebene hat Azure Limits (z.B. 300 create/drop pro Stunde?). Meistens egal, aber wenn man bei jedem UnitTest modul ne DB aufreißt, gehts nicht. Besser pro Pipeline oder pro test-scenario einmal DB, darin alle tests.
Azure SQL im DevOps-Kontext zu nutzen bringt Konsistenz (das gleiche DB-Engine wie Prod), und minimiert “it works on my machine, not on server” -Effekte. Durch Automation kann man superbequem damit umgehen – was wiederum für Entwickler die Hemmschwelle senkt, realistische Tests mit DB zu machen, statt in-memory mocks.
<br>
6. Sicherheit, Compliance, Netzwerk (kompakt)
Azure SQL bietet umfangreiche Sicherheitsfunktionen, die in der Cloud bereits integriert sind, sowie Möglichkeiten zur Netzwerkanbindung, um eine abgeschottete Umgebung ähnlich on-prem zu erreichen.
Authentifizierung (AuthN) & Autorisierung (AuthZ): In Azure SQL wird standardmäßig SQL-Login-Authentifizierung und Azure AD-Authentifizierung unterstützt. Es ist empfohlen, Azure AD zu nutzen, wo immer möglich – gerade in Unternehmenskontexten. Sie können etwa einen Azure AD-Sicherheitsgruppenprinzipal als DB-Owner definieren, sodass alle Entwickler via AD-Gruppe Zugriff haben. Kennwortlose Verbindungen sind über Azure-Dienste möglich: z.B. ein Azure Function kann mit seiner Managed Identity direkt an Azure SQL anmelden (Verbindungszeichenfolge mit Authentication=Active Directory Default), wodurch kein Passwort in der Config stehen muss. Auf Datenbank-Ebene funktioniert Autorisierung wie gewohnt über DB-User und Rollen (z.B. db_datareader, db_owner etc.), zusätzlich kann man Azure AD-Gruppen als Benutzer in der DB anlegen (CREATE USER [MeineGruppe] FROM EXTERNAL PROVIDER;) und Berechtigungen vergeben – das erleichtert die zentrale Verwaltung.
Managed Instance erlaubt zusätzlich Windows-Authentifizierung über Azure AD Kerberos, um z.B. Legacy-Apps mit Domänenkonto weiter zu betreiben – aber dies erfordert Azure AD Sync und etwas Konfigurationsaufwand (Azure AD -> Entra, Keytab etc.). Für die meisten Cloud-first-Szenarien reicht Azure AD.
Schlüsselverwaltung & Verschlüsselung: Azure SQL verschlüsselt alle Daten im Ruhezustand per Standard mit Transparent Data Encryption (TDE). Der Standard-TDE-Schlüssel wird von Microsoft gemanagt. Auf Wunsch kann Bring Your Own Key genutzt werden: Sie laden einen Schlüssel in Azure Key Vault hoch und konfigurieren TDE damit (sog. customer-managed key). Damit behalten Sie die Kontrolle – z.B. bei Schlüsselentzug würden die DB-Daten unlesbar. Darüber hinaus sind Backups ebenfalls TDE-verschlüsselt. Für sehr hohe Sicherheitsanforderungen kann man noch Always Encrypted (wie in Abschnitt 2 erwähnt) einsetzen, das selbst bei Verwendung in Memory/Transit Daten verschlüsselt hält (aber erfordert Client-Seitige Schlüssel, meist Key Vault integration).
Daten in Bewegung: Verbindungen zu Azure SQL erfordern SSL/TLS. Der neueste TLS 1.2+ wird erzwungen (man kann noch TLS1.0/1.1 zulassen, aber Standard disallow). Das TrustServerCertificate=False im Connection String sorgt dafür, dass das vom Server präsentierte Zertifikat geprüft wird. Alle Clients sollten das belassen (man hat ja Public CA cert von Azure). Insgesamt ist die Verbindung damit gegen Abhören geschützt. Für wirklich hochsichere Szenarien (z.B. interne App über unsicheres Netz) könnte man noch VPN/Tunnel drüberlegen, aber das ist meist unnötig bei TLS.
Netzwerkzugriff & Isolation: Azure SQL Database ist ein Multi-Tenant Service, d.h. die Datenbankserverendpunkte sind über das Internet adressierbar (Hostname .database.windows.net). Um Zugriffe zu kontrollieren, gibt es Firewallregeln auf Serverebene: Standard ist “Deny All”. Man muss entweder IP-Adressen freischalten oder – besser – komplett auf Private Endpoint setzen. Ein Private Endpoint* erlaubt es, dem logischen SQL-Server eine private IP in Ihrem Azure VNet zuzuweisen. Dann ist die DB nur noch über Ihr internes Netzwerk erreichbar (z.B. via VPN von on-prem oder direkt innerhalb Azure). Externe Versuche kommen gar nicht durch. Viele Unternehmen aktivieren Private Endpoints, um ein Zero-Trust Netzwerk aufzubauen, wo die DB nicht im öffentlichen Netz hängt. Für Entwicklungsdatenbanken oder einfache Projekte reicht oft die Firewall: z.B. “meine Büro-IP” erlauben, damit man mit SSMS ran kann, und “Allow Azure Services” abschalten (das ist ein Schalter, der pauschal alle Azure IPs zulässt – sollte man aus Sicherheitsgründen meist aus lassen und nur gezielt die App-Subnetze erlauben via Service Endpoints).
Netzwerkpfade & Latenz: Wenn App und DB in der gleichen Azure-Region sind und ideal per VNet Integration verbunden, sind Latenzen sehr gering (oft <1 ms für Netzwerk). In der Praxis kommt noch minimal SQL Processing Overhead dazu, aber Roundtrip-Zeiten von 1-2ms sind erreichbar – kaum mehr als on-prem LAN. Bei Cross-region oder gar über Internet können Latenzen natürlich höher sein (z.B. Europa <-> USA ~100ms). Daher Best Practice: App und DB immer co-located deployen. Falls Multi-Region-App (Active-Active) nötig, dann Multi-Region-DB via Failover Group / Active Geo etc. realisieren, aber niemals ständig cross-region Abfragen.
Durchsatz: Eine einzelne DB-Connection in Azure SQL kann viele hundert bis tausend Anfragen pro Sekunde abwickeln (je nach Komplexität), das Netzwerk ist in der Regel nicht der Bottleneck, sondern DB-Engine (oder Applayer). Jedoch, wenn man riesige Resultsets ständig überträgt, spürt man natürlich Bandbreite. Azure Standard 100 egress etc. – in einem Rechenzentrum ist aber intern auch Multi-Gigabit. Im VNet meist 10 Gbit +. Der Engpass kann aber der DB-Service (GP Tier hat max ~250 MB/s?), was aber sehr hoch ist. Für Bulk-Daten sollte man alternative Pfade erwägen (z.B. Export zu Storage).
Compliance & Auditing: Azure SQL ist zertifiziert nach zahlreichen Standards (ISO 27001, PCI DSS, HIPAA BAA etc.). Für konkrete Compliance-Anforderungen kann man in Azure auch Auditing einschalten, das Zugriffe protokolliert (z.B. wer hat welche Tabelle gelesen). Diese Logs können in ein Log Analytics Workspace gehen und von dort via Kusto Queries ausgewertet oder an SIEM weitergeleitet werden. Auch SQL Vulnerability Assessment steht im Azure Portal zur Verfügung: auf Knopfdruck wird die DB auf gängige Sicherheitslücken geprüft (fehlende Princpal of least privilege, alte Logins, unsichere Config). Ergebnisse kann man dokumentieren und nachverfolgen – nützlich um z.B. vor Audits sicher zu sein, dass DB config passt.
Zusätzlich gibt es Advanced Data Security (heute Teil von Defender for Cloud for SQL): das inkludiert Threat Detection (Anomalien) und empfiehlt auch Datenklassifizierung (man kann in Portal markieren, welche Spalten vertraulich sind, und Berichte generieren wer drauf zugegriffen hat). Für Entwickler ist relevant, dies ist da – oft kümmert sich aber ein Security-Admin darum.
Schlüsselverwaltung: Noch zu erwähnen: Azure bietet Managed HSM oder Key Vault, falls man BYOK TDE oder Always Encrypted mit Enclaves nutzen will. Always Encrypted mit Enclaves erlaubt bestimmte Operationen (Sortieren, Vergleichen) auf verschlüsselten Daten, erfordert aber ein spezielles SGX Enclave im Server. Azure SQL as of 2025 hat das in preview/generally (in MI glaube ich GA, in Single maybe preview). Wenn Daten wirklich sehr sensibel, kann man das evaluieren – aber es verkompliziert Entwicklung (Datentyp-Einschränkungen, Performance trade-offs).
Netzwerk-Integration Zusammenfassung: – Azure SQL Database: Standard = public endpoint + Firewall. For private, use Private Endpoint (one per server). – Managed Instance: Standard = im VNet (private IPs), Option auf Public Endpoint (abgeschaltet default). MI sitzt in einem Subnet und benötigt Netz-Konfig (NSGs etc. oft). Für on-prem Zugriff benutzt man in Enterprise meist ExpressRoute/VPN. – Verbindung von on-prem: Wenn direkter DB-Zugriff aus on-prem notwendig ist, sichert man es meist via VPN/ExpressRoute. Über ExpressRoute kann man sogar Microsoft Peering nutzen, um Azure SQL (multi-tenant) über das private MPLS zu erreichen. Oder via Private Endpoint plus ExpressRoute Private Peering – dann hat man wirklich End-to-End privat. – Überlegungen zur Latenz: Sind Workloads latenzempfindlich (viele kleine queries), ist es umso wichtiger, die Netzwerkanbindung optimal (sprich: so nahe wie möglich) zu gestalten. Hohe Latenzen summieren sich bei ORMs, die evtl. chatchen. Daher bei unvermeidbarer Distanz, an fewer calls design denken (Batching).
In Summe erfüllt Azure SQL hohe Sicherheitsstandards, viele Einstellungen sind by default sicher (z.B. SSL required). Entwickler sollten aber unbedingt grundlegende Security-Practices einhalten: keine sa/administrative Logins in Code, individuelle least-privilege Accounts pro Service, regelmäßige Passwortrotation bzw. ideal Passwortverzicht dank AD-Integration. Und natürlich: SQL Injection vermeiden in Code, denn Azure kann nur begrenzt schützen (es gibt zwar Threat Detection, aber das sollte der letzte Alarm sein, nicht die erste Verteidigung).
<br>
7. DevOps & Betrieb
Azure SQL fit zu betreiben erfordert wie on-premises eine gewisse Routine, aber viele klassische DBA-Aufgaben werden durch den Dienst übernommen. Hier fokussieren wir auf Aspekte, die in einem DevOps-Kontext relevant sind: Deployment-Strategien, Monitoring und Performance-Management, sowie Kapazitätsplanung.
Deployment-Strategien (Blue-Green, Rolling, Drift-Kontrolle): Datenbank-Änderungen sind traditionell heikel, da der Zustand (Daten) mit migriert werden muss. In Azure SQL können Sie prinzipiell alle gängigen Strategien anwenden: – Blue-Green Deployment: Dabei existieren zwei Datenbankumgebungen (z.B. DB_A und DB_B). Sie deployen eine neue Version der Anwendung auf eine zweite DB (Green) parallel zur laufenden (Blue). Anschließend schwenkt die App-Konfiguration um, so dass die neuen Instanzen auf die neue DB zeigen. Dies ist in DB-Szenarien schwierig, da die Daten konsistent sein müssen. Oft wird es so umgesetzt, dass die neue DB ein Snapshot/Fork ist und Änderung zwischenzeitlich auf beide geschrieben werden (Dual-write) – sehr komplex. Praktischer in Azure SQL ist Blue-Green eher auf App-Ebene (zwei App Slots) und DB wird inkrementell migriert (siehe Rolling). – Rolling / Incremental Deployment: Hier wird die Datenbank “im Takt” mit der Anwendungsdeployments aktualisiert. Z.B. Phase 1: Schema wird verändert (Migration Script läuft) – dabei bleiben alte und neue App-Version kompatibel (Backward compatibility). Phase 2: App-Code wird aktualisiert, nutzt nun neue Felder. Evtl. Phase 3: alte Artefakte entfernen in DB (wenn alter Code nicht mehr da). Azure SQL unterstützt diese Approach gut, da schema changes in place gemacht werden können (bei Bedarf auch transaktional). Wichtig ist Entwicklungsdisziplin: migrations so schreiben, dass sie keine langen Locks verursachen (Online-Index Rebuild etc. nutzen, Azure SQL supports ONLINE index ops im Premium Tier). Und mit Feature Flags im App-Code arbeiten, falls nötig, um DB-Changes phasenweise auszunutzen. EF Core kann z.B. “idempotente” Migrationen generieren, die safe sind. – Drift-Kontrolle: Wenn DBs in Prod doch manuell geändert werden (Hotfix am Freitag per SSMS), entsteht Drift = Abweichung vom quellcode. Tools wie Schema Compare (in Visual Studio) oder open-source like SchemaHero, Flyway can detect drift. Azure Purview/Arc kann auch config-Drift tracken. DevOps-Pipeline kann z.B. vor Deployment ein Schema Comparison (via SSDT DACPAC) ausführen, der Alarm schlägt falls Prod anders als erwartetes Schema. So verhindert man Überraschungen. – Backout: Wenn Deployment schiefgeht, wie zurück? Azure SQL’s PITR hilft, man könnte DB zu pre-deploy backup zeit wiederherstellen (Downtime in Kauf). Oder man schreibt Downgrade Scripts parallel zu Upgrade Scripts. Oder im Notfall, Quick fix forward.
Beobachtbarkeit (Monitoring): Azure SQL stellt Metriken und Telemetriedaten im Azure Portal (und via Azure Monitor APIs) bereit. Einige wichtige DMVs und sources: – Azure Monitor Metriken: CPU-Auslastung, DTU-Auslastung (falls DTU-Modell), Datendurchsatz, IO-Latenz, Verbindungsanzahl, Deadlock-Zähler etc. Diese können Sie im Portal in Diagrammen sehen und Schwellenwerte für Alerts definieren. Z.B. Alarm, wenn CPU > 80% für 5 Min, oder DTU Auslastung konstant hoch – dann prüfen, ob Upgrade nötig. – Intelligent Insights: Azure SQL DB hat eine eingebaute Analyse, die typische Performance-Probleme erkennt (z.B. “Ihr Index XYZ ist hoch fragmentiert” oder “Abfrage ABC hat seit Update 50x langsameren Plan”). Diese erscheinen im Portal, teils auch als Empfehlungen (“Performance recommendations”). DevOps-Teams können diese prüfen – aber vorsicht mit Auto-Accept, lieber nachdenken, ob der Indexpvorschlag wirklich sinnvoll ist. – Dynamic Management Views (DMVs): Entwickler und DBAs können auf DB-Ebene z.B. sys.dm_db_resource_stats (Verlauf von CPU/IO), sys.dm_exec_query_stats (Leistungsdaten per Query), sys.dm_exec_requests (aktuell laufende Queries) etc. nutzen. Auch sys.dm_tran_locks oder sys.dm_os_wait_stats (in MI) helfen bei Debugging (z.B. viel WAIT_ON_XLOG = IO-bound). – Query Store: Wie erwähnt, Query Store ist extrem hilfreich. Als DevOps-Engineer kann man per Query Store z.B. eruieren: „Welche Queries konsumieren am meisten CPU im Durchschnitt? Haben wir Regressions?“ Microsoft bietet Query-Store-Reports in SSMS oder man schreibt Kusto/TSql-Abfragen gegen die Query Store DMVs. In CI kann Query Store Data auch ausgelesen werden, um Trends zu tracken (gibt Ansätze, Performance budgets in pipeline zu checken). – Extended Events: In Azure SQL Database können Sie XEvents nutzen, um z.B. Deadlocks oder Long Running Queries aufzuzeichnen. Im Portal gibts dafür keine UI, aber via T-SQL Session definieren geht. Ein gängiger Use-Case: Erstellen einer XEvent-Session, die alle Queries > 1 Sekunde Captured. Dann diese Session persistent laufen lassen, und Ergebnisse per Query aus Target (Ring Buffer oder Azure Blob as target) auslesen – so hat man eher low-level Profiler-Ersatz. In MI kann man auch SSMS GUI zum XEvent benutzen. – Azure SQL Analytics (Log Analytics): Ein optionaler Service, der detaillierte Telemetrie (auch Query Store stats) in einen Log Analytics Workspace piped und Visualisierungen plus KQL-Abfragen ermöglicht. Das ist eher was für größere Installationen, aber sehr mächtig, weil man dort z.B. längere History und Korrelation hat. – Custom monitoring: Am Ende kann man immer via PowerShell/CLI/Python Scripte DMVs pollen, wenn man etwas sehr Spezifisches braucht. Aber meiste Standarddinge deckt Azure Monitor.
Wichtige Metriken und Waits: Für Performance-Tuning sollte man Azure-spezifische Patterns kennen: – Wenn CPU ständig hoch: vCores evtl. zu niedrig, oder Abfragen ineffizient – Query Tuning oder skalieren. – Wenn storage throttle Metriken oder WRITE_LOG waits hoch: Das Tier (GP vs BC) eventuell ungeeignet – Business Critical hat viel höhere IOPS, ggf. Wechsel in BC, falls IO-bound. – Wenn DTU Limit (im DTU Modell) oft 100%: höheres SLO buchen. – Lock Waits, Deadlocks: typ. Applogik überdenken (Transaktionen kürzer, Isolation level anpassen, RCSI an). – RESOURCE_SEMAPHORE waits: große Queries brauchen Memory, evtl. zu wenig Memory in Tier oder zu viele parallele heavy queries -> splitting them. – In MI vielleicht PAGEIOLATCH if hitting disk – but MI GP uses remote disk, moderate lat. Possibly scale out read if read heavy.
Automatisierung & Alerting: Ein DevOps-Team sollte Alerts setzen auf: – Ungewöhnlich hohe CPU / länger anhaltende > 90%. – Near storage limit (z.B. 80% of max storage). – Anzahl Deadlocks > 0 (d.h. es kommen Deadlocks vor, muss man fixen). – DTU consumption events for DTU model. – Also auf Azure side: Kredit-Auslastung falls per Subscr. relevant. – Azure Service Health: Falls Azure Incidents in Region, Info bekommen.
Leistungs- und Kosten-Baseline: Bevor man in Produktion geht, ist es ratsam eine Baseline zu definieren: Also z.B. “Normale CPU < 30%, typ. Lese-Schreibrate X, durchschnittl. Query Response Y”. Diese baseline kann aus Lasttests oder initial Prod-Phase gewonnen werden. Dann kann man SLOs definieren: z.B. 99th percentile query time < 500ms. Über Monitoring kann man diese Metrik tracken. Azure Monitor kann Workbooks erstellen, die Trends zeigen – das hilft zu sehen, wenn Performance langsam driftet (z.B. datenwachstum->Abfragen langsamer). Auch Kosten-Baseline: Cloud rechnet laufend ab, es ist gut zu wissen: unser Service kostet uns ~500 € pro Monat an DB. Wenn plötzlich 700, ist das Indikator dass vielleicht ein ineffizientes Query reingekommen ist, oder Auslastung stieg – was Monitoring decken sollte. Tools wie Azure Cost Management können Ausreißer schnell zeigen. DevOps kann Alerts definieren (Tageskosten > normal etc., falls z.B. Script in Endlosschleife gelaufen, schießt RU usage hoch).
Kapazitätsplanung: In der Cloud traditionell weniger wichtig, weil man ja “einfach” skaliert wenn nötig. Dennoch: – Storage Kapazität: Monitoren und vorausschauend erhöhen (GP tier kann storagesize online up, gut). – Durchsatz: Wenn absehbar saisonale Peak (Weihnachten E-Commerce): vielleicht im Voraus vCores hochstufen (Azure seit neuestem auch Autoscale vCore? Außer serverless gibts kein auto-upsizing, man muss manuell oder via automation event). – Connection Limit: Evtl. muss man mal schauen, wie viele Benutzerpeak – Azure has limit ~30000 sessions in some combos. Meistens ok. – Feature Roadmap: Planen, wann man z.B. auf neue Compatibility Level wechselt um neue Optimierungen zu kriegen (Testen!). Z.B. 2025 kam evtl. compatibility 170 (SQL 2025), man entscheidet wann anheben. – Alternate strategies: Falls latenzkritisch soared, vllt. data in memory caching? Azure SQL can’t scale out writes beyond one node, also if write throughput requirement soared, might need to consider sharding.
Operational Processes: – Always have a Recovery Plan: Testet mal das Point-in-Time Restore (z.B. in Preprod). Weil im Notfall muss es klappen. Azure macht es einfach, but exercise it. – Failover Simulation: Mit geo-secondary, man kann Test-Failover machen (Azure failover groups allow forced test failover), check ob App reconnects gracefully. – Updates: Azure updated DB engine frequently – vllt. bemerkt man geändertes Verhalten (z.B. neue Cardinality estimation in compat level). Keep an eye on release notes, but azure doesn’t announce all minor stuff. So robust code is key.
In DevOps-Kultur verschmelzen Dev und Ops – Azure SQL unterstützt das, indem es via APIs/Automation ansprechbar und stabil im Betrieb ist. Dennoch muss man ein Auge auf Performance und Kosten haben, da “einfach laufen lassen” sonst unschön enden kann (entweder Lags oder Rechnung hoch). Mit obigen Mechanismen ist eine kontinuierliche Überwachung und schnelle Reaktion möglich.
<br>
8. Best Practices & Anti-Pattern (Kurzkapitel)
Abschließend einige kompakte Do’s and Don’ts beim Einsatz von Azure SQL – gesammelt aus den vorigen Kapiteln:
- DO: Nutzen Sie Azure SQL PaaS-Vorteile voll aus – lassen Sie automatische Backups, Patching und Tuning für sich arbeiten, anstatt alles manuell tun zu wollen. Konzentrieren Sie sich auf Schema-Design und Query-Optimierung.
- DON’T: Versuchen Sie nicht, an der verbotenen Schicht (OS, Instanz) herumzubasteln. Z.B. Registry-Hacks, xp_cmdshell oder manuelles DBCC TRACEON von Flags, die in Azure nicht erlaubt sind. Das wird entweder blockiert oder führt zu Unsupported-Status. Halten Sie sich an die dokumentierten Funktionen.
- DO: Entwerfen Sie das Schema cloudgerecht. Das heißt, vermeiden Sie harte Cross-DB Abhängigkeiten (bei Bedarf Managed Instance wählen), planen Sie Partitionierungen für sehr große Tabellen, nutzen Sie Columnstore für analytische Workloads und überlegen Sie Multi-Tenant-Strategien früh (pro Mandant DB vs. Shared mit TenantID – siehe Szenario 5.2).
- DON’T: Überindexieren Sie nicht. Zu viele Indizes schaden Einfüge/Update Performance und bringen wenig Nutzen. Nutzen Sie Query Store oder die azure-Empfehlungen, um die richtigen Indizes zu identifizieren. Entfernen Sie unbenutzte Indizes.
- DO: Implementieren Sie in Applikationen eine robuste Verbindungsverwaltung. Nutzen Sie Connection Pooling (Standard in .NET, Java etc.), halten Sie Transaktionen so kurz wie möglich, und bauen Sie bei transienten Fehlern automatische Retry-Logik ein (z.B. mit Expo-Backoff). Azure SQL kann gelegentlich Verbindungen zurücksetzen (z.B. beim Failover), das muss Ihre Anwendung abfangen, ohne dass gleich Fehler beim Endnutzer landen.
- DON’T: Offene Verbindungen und lange Transaktionen liegen lassen. In Cloud-Umgebung können lange Sperren viel Wirkung haben. Schließen Sie DbConnections ordentlich (bei Pooling werden sie zurückgegeben). Vermeiden Sie Transaktionen, die Benutzereingaben abwarten (klassiker: “begin tran; show confirm dialog; commit” – geht gar nicht verteilt).
- DO: Setzen Sie Timeouts bewusst. Der Standard SqlCommand Timeout ist 30s – das ist okay für OLTP, aber wenn Sie Batchjobs haben, die länger laufen dürfen, setzen Sie höhere Timeouts für diese bewusst. Umgekehrt auf UI-nahe Queries evtl. niedrigere Timeouts, damit hängende Queries nicht UI blockieren. Kombinieren Sie das mit Cancellation-Möglichkeiten (z.B. CancellationToken im .NET, sodass Abbruch im Client auch Query auf Server killt, damit nicht Geister laufen).
- DON’T: Fangen Sie Timeout Exceptions einfach blind und probieren ewig neu. Timeout kann bedeuten echtes Problem (Query hängt wegen Deadlock, falscher Index). Lieber Ursache beheben. Retries nur bei transient network errors (error codes 40613, etc.), nicht bei echten Timeouts wegen schlechter Perf.
- DO: Verwenden Sie Parameter in Queries (gegen SQL Injection, und für Plan-Wiederverwendung). Azure SQL hat ähnliche Parameter Sniffing Themen wie SQL Server – mitigieren via Query Hints oder neuerdings Parameter Sensitive Plan feature (falls aktiviert) kann helfen. Testen Sie Abfragen mit atypischen Parametern um sicher zu sein, dass Plan immer okay.
- DON’T: Bauen Sie Dynamic SQL ohne Notwendigkeit oder fügen Parameter direkt in Strings ein -> Injection-Gefahr! Nutzen Sie sp_executesql mit Param, oder ORMs. Azure’s Threat Detection kann Injection versuchen erkennen, aber verlassen Sie sich nicht darauf – schützen Sie Ihre Queries im Code.
- DO: Überwachen Sie regelmäßig Abfragepläne Ihrer wichtigsten Queries (via Query Store oder Actual Execution Plans). Erkennen Sie, ob Indexe fehlen oder ein Plan plötzlich suboptimal wurde. Azure SQL’s Auto-Plan-Force kann helfen, aber nicht blind drauf verlassen – manchmal muss Entwickler z.B. Code anpassen (Split einer großen Query in zwei kleinere, etc.).
- DON’T: Ignorieren Sie Azure SQL’s Service Limits – beispielsweise Maximale Parallelität in Basic Tiers oder Speicherbeschränkung. Wenn Sie an eine Grenze stoßen (z.B. max 5400 DTUs pro Server), beantragen Sie Erhöhung oder redesign. Standard-Limits (z.B. 4 TB in BC) sind hoch, aber nicht unendlich. Planen Sie Partitioning oder Sharding, bevor Sie hart an physische Grenzen stoßen.
- DO: Machen Sie sich mit dem Azure-Ökosystem vertraut: kombinieren Sie Azure SQL mit anderen Services sinnvoll. Z.B. Caching in Azure Redis for ultra-fast reads, oder Offloading kalter historischer Daten in Data Lake Storage und per PolyBase/External Table anbinden. Nutzen Sie Event Grid + Functions statt heavy SQL polling etc. Azure SQL spielt gut zusammen mit Data Factory (für ETL), Synapse (für BI), Power BI (für Reporting). Architektonisch sollte man die Stärken jedes nutzen – Azure SQL für Kern-Transaktionen, aber keine Bildspeicherung (dafür Blob Storage), etc.
- DON’T: Überfrachten Sie Azure SQL mit Aufgaben, für die es nicht gedacht ist: z.B. keine Files ablegen (nutzen Sie Blob), keine langen Warteschlangen mit Millionen unprocessed Rows (dafür gibt es Service Bus), keine KI-Modelle im SQL (lieber Azure ML Service oder Synapse). Bleiben Sie bei dem, was eine relationale transaktionale DB gut macht – für alles andere hat Azure spezialisierte Bausteine.
Diese Best Practices helfen, häufige Stolperfallen zu vermeiden und Azure SQL optimal einzusetzen. Oft gilt: Die gleichen guten Praktiken wie für eine on-prem SQL Server-Entwicklung gelten auch in Azure (sauberes Schema, Normalisierung wo sinnvoll, Indizes, Sproc wo Performancevorteil, etc.), plus die Cloud-spezifischen Themen (Kosten, begrenzte Admin-Rechte, verteilte Systeme).
<br>
9. FAQ (Häufige Fragen)
Zum Abschluss eine Sammlung von 30 häufigen Fragen rund um Azure SQL aus Entwicklersicht – mit prägnanten Antworten:
Frage 1: Wie verwaltet man effektiv Datenbankverbindungen und Connection Pooling in Azure SQL?
Antwort: Genauso wie bei SQL Server on-prem. Verwenden Sie die Connection-Pooling-Mechanismen der jeweiligen Plattform (.NET SqlClient, JDBC etc.), die standardmäßig aktiv sind. Vermeiden Sie es, für jede Abfrage eine neue Verbindung aufzubauen – stattdessen einmal öffnen, wiederverwenden und schließen. In Azure-Umgebungen besonders wichtig: Implementieren Sie Retry-Logik bei Verbindungsabbrüchen (z.B. über die Bibliotheken oder Polices wie Polly in .NET), da in der Cloud gelegentlich Transienten auftreten (z.B. kurze Netzwerkunterbrechungen oder Failover). Insgesamt gilt: Halten Sie Verbindungen nicht unnötig lange offen (um Ressourcen zu schonen), aber eröffnen Sie auch nicht exzessiv neu – das Pooling regelt das normalerweise optimal.
Frage 2: Welche Timeout-Einstellungen und Retry-Policies sind empfehlenswert?
Antwort: Der Standard-CommandTimeout (30 Sekunden) ist ein guter Ausgangspunkt für die meisten OLTP-Operationen. Falls bestimmte Abfragen länger dauern dürfen (etwa Reports), setzen Sie dafür gezielt höhere Timeouts, aber achten Sie darauf, dass die Anwendung währenddessen responsiv bleibt (Async/Await oder Threads). Implementieren Sie Retries nur für transient error conditions (SQL Errorcodes wie 40613, 40197, „transport communication error“ etc.). In .NET kann SqlConnection mit ConnectionRetry=True konfiguriert werden bzw. EF Core EnableRetryOnFailure(). Nutzen Sie exponentielles Backoff: z.B. bis zu 3–5 Wiederholungen mit wachsender Wartezeit (zunächst 1s, dann 2s, 4s,…). Aber: Retries bei Timeout oder Deadlock können angebracht sein (weil evtl. die zweite Ausführung durch ist), jedoch sollten Sie vermeiden, massiv lange zu loopen – wenn nach einigen Versuchen kein Erfolg, lieber Fehler werfen und Logging machen. Wichtiger Hinweis: Lange Zeitouts plus Retries können zu sehr langen Wartezeiten führen; definieren Sie also auch auf höherer Ebene ggf. ein Gesamt-Timeout (z.B. Cancel der Operation nach 2 Minuten, auch wenn Retries noch laufen). So behalten Sie Kontrolle.
Frage 3: Welche Migrationsstrategie soll man wählen – EF Core Migrations (Code-First) oder SSDT/DACPAC (Schema-First)?
Antwort: Das hängt von Ihrem Entwicklungsansatz ab. EF Core Migrations eignen sich gut, wenn die Datenbankschemas eng mit dem Anwendungs-Code evolvieren und Sie bevorzugt in C# arbeiten. Sie ermöglichen schnelles Iterieren (z.B. Add-Migration in Code) und können bei App-Start oder via CLI applied werden. Für viele agile Teams ist das ausreichend. SQL Projects/SSDT (DACPAC) sind sinnvoll, wenn Sie ein getrenntes DB-Schema-Management wollen, vielleicht sogar ein dediziertes DBA-Team haben, oder sehr komplexe DB-Objekte (Prozeduren, User, etc.) verwalten. DACPACs erlauben deklarative Modelle und einen Drift Check, und passen gut in Azure DevOps Pipelines (Task “Azure SQL Deploy” etc.). Beide Wege funktionieren mit Azure SQL. Wichtig ist, dass Sie Ihre Migrationen automatisiert in die Cloud-DB ausrollen (z.B. Pipeline-Schritt). Mischformen gibt es auch: z.B. EF Core für Grossteile, aber heikle Prozeduren per Hand-Skript. In Azure gibt es keine generelle Präferenz – wählen Sie, was zu Ihrem Team passt. Für große Unternehmen mit getrennten Verantwortlichkeiten werden DACPACs oft bevorzugt, während Startups gerne EF Migrations nutzen.
Frage 4: Wie gehe ich mit Long-Running Queries um (z.B. umfangreiche Reports)?
Antwort: Wenn möglich, vermeiden! 🙂 Scherz beiseite: Lange Abfragen (mehrere Sekunden oder gar Minuten) sollten Sie isolieren, damit sie andere Transaktionen nicht stören. Setzen Sie READ UNCOMMITTED oder READ COMMITTED SNAPSHOT (standard in Azure SQL aktiv), sodass Leselasten Schreibvorgänge nicht blockieren. Nutzen Sie ggf. die Read-Replica (Business Critical Tier oder Geo-Secondary) für solche Abfragen, damit die Haupt-DB entlastet wird. Überlegen Sie, ob sich die Abfrage optimieren lässt – Indexe, Voraggregationen oder Aufteilung in kleinere Happen. Wenn eine Abfrage wirklich sehr lang laufen muss (etwa ein monatlicher ETL-Lauf von 2 Stunden), stellen Sie sicher, dass sie außerhalb der Geschäftszeit läuft und Ressourcenklassen (in MI) bzw. den Service-Tier so wählt, dass sie genügend Ressourcen hat. Azure SQL beendet von sich aus keine Abfrage aufgrund Laufzeit (kein built-in timeout serverseitig, außer Idle-Timeout bei 30 min an Verbindung). Es obliegt Ihrer App, Timeout zu setzen. Falls es legitim ist, dass Query 5 Minuten dauert, erhöhen Sie den Timeout im Client dafür oder erwägen Sie asynchrone Pattern (z.B. user stößt Report an -> Hintergrundtask -> Ergebnis später bereitstellen). Und loggen/überwachen Sie solche Long Queries, damit Sie sicher sind, dass sie noch innerhalb erwarteter Parameter laufen. Gegebenenfalls kann man mit MAXDOP und Query Hints auch steuern, wie viel Ressourcen die Abfrage nimmt, damit der Server nicht komplett monopolisiert wird.
Frage 5: Unterstützt Azure SQL verteilte Transaktionen über mehrere Datenbanken?
Antwort: In Azure SQL Database (Single): nein, Distributed Transactions (DTC) werden nicht unterstützt, da es keine Serverinstanz-übergreifende Koordination gibt. Es gibt auch kein MS DTC in PaaS. In Azure SQL Managed Instance: bedingt ja – innerhalb einer MI können Sie Transaktionen über mehrere DBs führen, analog zu einem on-prem SQL Server (BEGIN DISTRIBUTED TRAN, etc.), da eine MI eine Instanz mit einem DTC-ähnlichen Koordinator hat. Allerdings über Instanzgrenzen hinweg (z.B. MI zu externer SQL VM oder MI zu anderer MI) geht es wiederum nicht offiziell. Workaround in Azure SQL DB-Welt: Ohne DTC muss man entweder auf eventual consistency (zweistufige Commits via App) wechseln oder versuchen, die Logik umzugestalten, sodass alle wichtigen Operationen in einer DB passieren (z.B. mittels Schemakonsolidierung oder durch Service-Aufteilung). Für heterogene Quellen (SQL und Oracle z.B.) bleibt in PaaS nur der Weg über die Applikation (oder Azure Workflows), die die Koordination übernimmt. Kurz: Verteilte Transaktionen wie on-prem sind in PaaS eingeschränkt; wenn unerlässlich, Azure MI wählen – aber auch dort komplexe Cross-System-Szenarien vermeiden.
Frage 6: Welche Features fehlen in Azure SQL im Vergleich zu einem lokalen SQL Server?
Antwort: Die meisten Kernfunktionen sind da, aber es gibt einige wichtige Ausnahmen (siehe Kapitel 3 Tabelle). Kurz gesagt fehlen in Azure SQL Database (Single/Pool) alle instanzbezogenen Dinge: SQL Server Agent, DB Mail, Linked Server zu Fremddaten, PolyBase, Filestream, Service Broker, CLR, Verwendung von Trace Flags, Kontrolle über TempDB-Konfiguration, und allgemein OS-nahe Dinge wie xp_cmdshell. Auch einige ältere Features wie Transparent Data Encryption mit eigenem Zertifikat (geht nur via Azure Key Vault, nicht Filesystem) oder cross-database Ownership-Chaining funktionieren nicht. In Managed Instance ist die Parität viel höher: Agent, DB Mail, Service Broker, CLR (safe) etc. sind vorhanden. Dennoch auch MI hat Limits: z.B. kein PolyBase zu Oracle (nur Azure Storage Quellen), kein SSRS/SSAS integriert (das sind separate Services), und weniger Kontrolle über Wartungsfenster. Zudem sind Hardwarenahe Optionen (Lock Pages in Memory, traceflag tuning) in MI auch nicht verfügbar. Viele dieser Unterschiede haben wir in der Tabelle 2 gelistet. Ein weiteres “Feature”, was fehlt, ist die selbstbestimmte Upgrades: Azure bringt immer die neueste Version, es gibt kein Bleiben auf SQL 2012-Level (Kompatibilitätslevel kann man setzen, aber Engine wird trotzdem modern). Normalerweise aber eher Vorteil. Unterm Strich: 95% dessen, was ein Entwickler in SQL Server nutzt (T-SQL, Procs, Funktionen, Indexe etc.), geht nahtlos in Azure SQL. Spezialsachen muss man checken und ggf. anpassen.
Frage 7: Wie funktioniert automatisches Tuning in Azure SQL genau?
Antwort: Automatisches Tuning umfasst zwei Hauptfunktionen: Automatische Indexverwaltung und Automatische Plan-Korrektur. Bei Azure SQL Database (Single) können Sie im Azure-Portal pro DB aktivieren, dass fehlende Indexe automatisch erstellt werden (CREATE INDEX Vorschläge) und ggf. auch Indexe, die als nicht genutzt identifiziert werden, automatisch gelöscht werden. Die Engine überwacht Query Store und erkennt, wenn z.B. ein empfohlener Index signifikant Abfragen beschleunigen würde – dann legt sie ihn an (in einem Wartungszeitfenster möglichst). Ebenso mit Dropping: sieht sie, ein Index wurde 0-mal in X Tagen genutzt, aber kostet beim Schreiben viel, kann er weg. Diese Aktionen passieren schrittweise und sind rückgängig zu machen, falls nötig (die Plattform überwacht, ob ein auto erstellter Index überhaupt genutzt wird – wenn nicht, entfernt sie ihn wieder). Plan-Korrektur: Hier geht es um Execution Plans. Azure erkennt via Query Store, wenn eine Query plötzlich langsamer wurde als früher (Plan Regression). Ist Automatic Plan Correction aktiv, wird Azure die Query auf einen bekannten guten Plan zurückzwingen (per sp_query_store_force_plan) und später prüfen, ob das hilft. In vielen Fällen stabilisiert das Performance ohne menschliches Eingreifen. In Managed Instance ist Automatic Index nicht auto-ausführend (nur Empfehlung), Plan Forcing kann aber manuell oder via Advisor genutzt werden. Wichtig: Diese Features sind hilfreich, ersetzen aber kein Monitoring. Als Entwickler/DBA sollten Sie die empfohlenen Aktionen zumindest gelegentlich reviewen – gerade automatisches Löschen von Indizes könnte man kritisch prüfen, bevor es aktiviert wird. Standardmäßig ist “Auto Create Index” ON bei neuen Azure SQL DBs, “Auto Drop” OFF (muss man bewusst einschalten). Automatic Plan Correction ist oft ON by default. Alles lässt sich aber fein steuern (auch via T-SQL ALTER DATABASE SCOPED CONFIGURATION).
Frage 8: Welche Kostenfallen gibt es bei Azure SQL? (Beispiel: falsch dimensionierte Tiers)
Antwort: Häufige Kostenfallen sind: – Überprovisionierung: Ein zu hohes Service-Tier oder zu viele vCores reserviert “für alle Fälle”. Das kostet dauerhaft mehr Geld als nötig. Beispiel: Eine kleine App läuft auf Business Critical 8 vCores, nutzt aber nur 5% CPU – da könnte General Purpose oder weniger vCores tausende Euro sparen. Lösung: Messen und anpassen, ggf. nach unten skalieren. Azure Advisor gibt auch Hinweise, wenn Ressourcen unterbelegt sind. – Nicht genutzte DBs laufen lassen: Entwicklungs-/Test-Datenbanken vergisst man gern mal. Die laufen durch und erzeugen Kosten (wenn auch kleine). Bei vielen Projekten summiert sich das. Deshalb: regelmäßig Inventar checken, unbenutzte abschalten/löschen oder auf Pause (Serverless) stellen. – Keine Reservierung/AHB genutzt: Wenn Sie lange laufen, aber Pay-as-you-go zahlen, verschenken Sie Geld. Größere Prod-Workloads sollten praktisch immer AHB (falls Lizenzen vorhanden) und Reserved Capacity ausnutzen. – Falscher Modellwechsel: Z.B. migriert von DTU Basic (5 €/Monat) direkt auf vCore Gen5 2 (150 €/Monat) obwohl es ein kleinstes Projekt war – vCore ist flexibler aber manchmal dtus für mini-sachen billiger. Oder Single DB vs Elastic Pool: Pools haben Mindestpreis, lohnen erst ab bestimmter DB-Anzahl – sonst zahlt man zu viel. – Daten Egress: Das kann ebenso eine Falle sein. Wenn etwa Ihr BI-Tool außerhalb Azure sitzt und jeden Tag 100 GB an Berichten zieht, zahlen Sie für den Datenausgang. Oder ständiges Cross-Region Replizieren (auch Site Recovery, falls genutzt). Diese Netzwerkkosten sieht man nicht direkt in der DB-Rechnung, tauchen aber in Azure Networking auf. Lösung: App nah zu DB bringen, ggf. caching, oder ExpressRoute wo Egress günstiger. – Hochstufen und vergessen zurück zu stufen: Typisches Szenario: Für Lasttest auf 16 vCores skaliert, Test fertig – aber niemand skaliert zurück. Dann läuft Prod noch Monate unnötig groß. Automatisierung/Alert (“Scaling event – check revert”) kann helfen. – Long-term Backup Speicher: Wenn Sie Langzeitaufbewahrung aktivieren (z.B. monatliche Backups 5 Jahre), wächst der Storageverbrauch über Zeit. Das ist beabsichtigt, aber sollte budgetiert sein. Ähnlich, Falls Sie viele Geo-Replicas halten, verdoppeln sich Kosten pro Replica. In Summe: Azure bietet viele Wege zu optimieren, aber man muss sie aktiv nutzen. Andernfalls kann man, wie sprichwörtlich, in Cloud schnell Geld verbrennen.
Frage 9: Worauf muss man bei der Serverless-Option achten (Auto-Pause, Cold Start etc.)?
Antwort: Serverless ist super für intermittierende Last, hat aber ein paar Eigenheiten: – Auto-Pause: Wenn die DB keine Benutzeraktivität hat für definierte Zeit (min 1h, max 7d, je nach Konfig), fährt sie sich herunter. Während Pause zahlen Sie nur Speicher (~0,1 €/GB/Monat). Beim nächsten Verbindungsversuch “wacht” sie auf – das dauert typischerweise 5–30 Sekunden. Dieser Cold Start verursacht für den ersten Benutzer Verzögerung. Deshalb: In produktiven Echtzeit-Systemen, wo jeder Sekunde zählt, ist Auto-Pause eher ungeeignet. Für Dev/Batch aber super. – Minimale vCores: Sie legen Min und Max fest. Während Inaktivität skaliert CPU auf Min, aber Memory bleibt entsprechend Min allokiert und wird auch berechnet. Zu niedriges Min kann bedeuten, dass beim Eintreffen von Last die DB mehr Zeit braucht (muss langsam hochskalieren). Beispiel: min 0,5 vCore und plötzlich komplexe Abfrage -> dauert erst, bis mehr CPU zugeteilt. Daher muss man je nach Workload ein sinnvolles Min wählen, das Grundlast bedienen kann. – Burst-Verhalten: Serverless skaliert im Sekundentakt je nach Bedarf. Es kann einige Minuten dauerhafte Auslastung brauchen, bis es wirklich auf Max hochfährt. Bei kurzzeitigen Spitzenauslastungen kann es also sein, dass es nicht die Peak vCores voll ausschöpft. Das ist i.d.R. okay, die Abfrage dauert dann halt etwas länger, aber bewusst sein. Bei Workloads mit abrupten, sehr hohen Lastspitzen (z.B. tägliche bestimmte Task, die intensiv rechnet) könnte ein Provisioned mit definierter Leistung sinnvoller sein. – Kostenberechnung: Anders als vCore fix, zahlt man hier pro genutzte VM-Sekunde. Das kann schwerer vorhersagbar sein. Monitoring der Metric “CPU_Billed” und “Memory_Billed” hilft, um Schätzung zu haben. Wenn Sie nahe dauernd 100% use haben, kann serverless teurer sein als gleich vCore reserved. Faustregel: Ab ~50%+ Dauerlast lohnt Provisioned eher. – Hyperscale Serverless: Im GP Tier kann autopause, im Hyperscale Tier (sofern serverless support dort) autopause war Stand 2024 nicht unterstützt – Cold Start entfällt also (immer an), aber dafür doch usage-based billing, eher seltene Kombination. – Version/Service Limits: Derzeit ist Serverless nur auf Gen5-Hardware im General Purpose-tier verfügbar, max 40 vCores. Spezielle Hardware (M-Serie, Business Critical) gibt es nicht als serverless. Auch Multi-AZ/Zone Redundanz in Serverless war lange nicht verfügbar (neue Info checken, aber vermutlich noch nicht). In der Praxis: Planen Sie Cold-Start Workarounds, z.B. ein warm-up Ping am Morgen (Azure Runbook, das einfach SELECT 1 auslöst, um DB vor Arbeitsbeginn zu wecken). Und kommunizieren Sie an Entwickler/Nutzer, dass nach langen Idle-Zeiten eine kurze Wartezeit normal ist – dann ist es kein Problem.
Frage 10: Was ist bei Hyperscale-Datenbanken besonders zu beachten?
Antwort: Hyperscale bricht mit ein paar traditionellen Annahmen: – Architektur: Es gibt ein Konzept von Page Servers, Log Service etc. Dadurch sind z.B. Backups quasi “instant” (nur ein Snapshot-Pointer), aber eine Wiederherstellung auf einen früheren Zeitpunkt kann etwas länger dauern, da die Daten dann asynchron eingespielt werden. Praktisch hat Hyperscale keinen DB Größenstress – Sie müssen sich keine Gedanken über 4 TB Limits machen. Sie sollten aber Autogrowth sinnvoll einstellen (Hyperscale wächst on-demand in 10 GB Chunks). – Performance: Lesevorgänge können aus dem Remote Storage kommen, was minimal mehr Latenz hat als Business Critical (wo alles local SSD). Für OLTP mit vielen random reads kann Hyperscale marginal langsamer sein als BC, aber es skaliert eben riesig. Hyperscale glänzt, wenn Sie viele parallele Read-Workloads haben – Sie können mehrere Named Replicas (bis 4 derzeit) erstellen und an verschiedene Zwecke (Reporting, ML, etc.) geben. Jede Replica hat eigene compute, aber denselben Storage. – Failover: Bei Hyperscale gibt es keine Always On 4-Knoten Architektur wie in BC. Der Primärknoten hat keinen voll synchronen zweiten – es gibt Hochverfügbarkeit über Service-Fabric: im Failover wird ein neuer Compute-Knoten gestartet, der sich aus dem Storage bedient. Das macht Failover potenziell etwas langsamer (einige Sekunden mehr) aber immer noch < 1 min normalerweise. – Wartung: Wartungsupdates in Hyperscale können per Rolloing Upgrade stattfinden – Named Replicas nacheinander, etc. Es gab (2024) die Einführung wählbarer Wartungsfenster. Trotzdem passiert viel im Hintergrund automatisch (z.B. die Checkpointer Threads etc.). Meistens merkens Sie nichts – aber es kann sein, dass in Hyperscale Hintergrundprozesse ab und zu Ressourcen nehmen (z.B. ein Long-Term retention backup snapshot wird erstellt – minimaler Impact). – Limitations: Hyperscale unterstützt fast alles, was GP tut, ABER: In-Memory OLTP war Stand 2025 in Hyperscale noch nicht unterstützt (kann sich ändern), und es gibt kein geo-restore (man kann aber Failover Group mit Hyperscale nutzen). Auch gibt es keine Auto-Pause in Hyperscale serverless. Cross-database queries auf demselben server mit Hyperscale DBs geht nach wie vor nicht (Hyperscale DB kann am selben logical server aber ohne elastic query nicht verknüpft). – Migration: Der Wechsel zu Hyperscale ist one-way (Single DB -> Hyperscale geht per konvertieren), zurück geht nur via Export/Import oder so, nicht direkt. Also entscheiden Sie sich bewusst. Hyperscale Instances hat Microsoft noch nicht (also MI hat noch kein Hyperscale tier Stand 2025). Use Cases: Hyperscale ist perfekt, wenn Sie z.B. > 4 TB Daten haben oder viele gleichzeitige leseintensive Analysen auf heißer Datenbasis. Für “normale” Workloads < 1 TB kann BC besser sein (wegen Latenz). – Kosten: Hyperscale Compute ist wie GP, Storage kostet pro GB, plus jeder Named Replica kostet zusätzliche Compute (Storage nicht dupliziert). Kann also teuer werden, wenn Sie mehrere Replicas nutzen. Aber alternativ müssten Sie bei Single DB mehrere verteilte DB pflegen – Hyperscale spart dort Operatiionsaufwand.
Frage 11: Welche Grenzen und Überlegungen gibt es bei der Nutzung von Elastic Pools?
Antwort: Elastic Pools sind toll für Multitenancy, aber: – Grenzen: Jeder Pool hat eine maximale vCore-Anzahl (z.B. 50 vCore) und eine max Anzahl an DBs (standard 100, erweiterbar auf 500). Außerdem pro DB ein optionales eDTU Limit oder Min. Sie müssen Pools in derselben Region wie DB server sein. Pools unterstützen derzeit nicht Hyperscale oder Managed Instances – nur Single DB im vCore oder DTU Modell. Pools gibt’s im General Purpose und Business Critical Flavour, aber meist nimmt man GP Pools. – Balancing: Stellen Sie sicher, dass die DBs im Pool auch zusammenpassen. Wenn Sie eine sehr “laute” DB mit vielen kleinen reinstecken, kann die eine den ganzen Pool saturieren. Sie können mit Pool-Einstellungen steuern: z.B. per DB min vCore (garantiert jeder kriegt z.B. 0.5 vCore immer) und max vCore (damit einer nicht mehr als z.B. 4 vCores zieht, auch wenn Pool 20 hat). Diese Einstellungen helfen Fairness, verringern aber die Elastizitätsgewinne. Ohne Limits = jeder kann bis Pool max, first come first serve. – Monitoring Pools: Sie müssen neben DB-Metriken auch Pool Metriken anschauen. Azure Monitor zeigt z.B. Pool CPU % (aggregiert) und ggf. CPU des Top-Benutzers. Etwas tricky kann es sein, einen Engpass zu diagnostizieren: Wenn eine DB langsam ist, weil Pool voll, könnte es so aussehen, als ob DB CPU 100% – tatsächlich ist aber Pool gedeckelt. Azure hat Indikator “Avg vCPU used per db” etc., notfalls muss man mit DMVs (in master DB auf server) die usage rausfinden. – Scaling Pools: Sie können Pools skalieren (vCores rauf/runter) wie Single DB. Das wirkt auf alle DBs – entsprechend planen (ggf. short disconnect). Sie können DBs aus Pools nehmen (Wichtig: Wenn DB aus Pool ins Single wechselt, klemmen Sie kurz). – Costs: Pools rechnen sich, wenn viele DBs niedrig ausgelastet. Wenn aber einige DBs doch dauerhaft hohe Last haben, zahlen Sie evtl. auch für Idle – am Ende wie Flatrate, die man voll ausschöpfen sollte. Falls Pool ständig 90%+ Auslastung, überlegen Sie, ob separate DBs nicht besser, da dort ggf. auto tuning etc. individueller greift. – Azure limitations: Z.Z. (2025) wird Data Sync (veraltetes Azure SQL Feature) für Pools eingestellt – eher unwichtig. – Security/Access: Alle DBs im Pool sind auf einem logical server – gleiche Server-Admin, gleiche AD Admin. Mandanten-übergreifend Pools machen, sollten Sie aufpassen, dass kein Cross-Access möglich (Trennung via Logins). Fazit: Pools sind genial, aber man muss Monitoring und Limit-Management machen. Und immer im Hinterkopf: simpler ist es evtl., gar nicht so viele DBs zu managen – d.h. nicht sinnlos sharden wenn Mandantenzahl klein.
Frage 12: Wie funktioniert die Geo-Replikation und das Failover in Azure SQL?
Antwort: Für Azure SQL Database (Single): Sie können pro DB bis zu 4 aktive Geo-Replicas einrichten. Diese sind asynchron (verwenden Always On Technik). Jeder Replica ist lesbar (ConnectionIntent=ReadOnly) und hat eigene Endpoint (eigener Azure SQL Server in Zweitregion). Failover ist manuell im einfachen Setup: Wenn Primary Region ausfällt, müssen Sie im Portal oder via API die Secondary explizit zum Primary machen. Anwendungen müssen dann auf den neuen Server verbinden. Failover-Gruppen vereinfachen das: Sie definieren einen Failover-Verbund aus DB(s) zwischen zwei Servern. Dieser gibt Ihnen einen sekundären Verbindungsendpunkt + Listener-Name (..database.windows.net bleibt gleich mit “secondary” im name). Bei Ausfall kann die Gruppe automatisch failover (konfigurierbar z.B. nach 1h RTO oder so) – oder manuell schwenken. Im Failover-Fall ändert sich intern, wer Primary ist, und Client kann denselben Listener ( z.B. myapp.database.windows.net ) nutzen – der zeigt dann auf die andere Region. Lesezugriff im Normalbetrieb geht über myapp.secondary.database.windows.net. Für Managed Instance: Kein Active Geo mit mehreren, aber Failover Group von MI-Paar. Hier kann man die ganze MI (alle DBs) auf eine zweite MI in anderer Region replizieren (asynchron). Zugriff analog mit listener. In MI FG kann Auto-Failover eingestellt werden (z.B. bei Region Down, nach X min). Failover Ablauf: Failover ist Datenverlust möglich, da asynchron. RPO in Azure SQL geo ist meist < 5 sec, aber garantieren tun sie < 1h (worst-case netz partition). Nach Failover wird vorherige Secondary Primary. Wenn ursprüngliche Region wieder da, kann man manuell re-tunen oder es bleibt swapped. Pitfall: Verbindungen werden beim Failover getrennt. Applikation muss neu verbinden (daher retries!). Testing: Kann man z.B. mit ALTER DATABASE … FAILOVER (in Failover Group context) auslösen. Geo-Restore: Unabhängig von aktiven Replicas: Wenn Region total down und man hatte keine Replicas, kann man trotzdem aus Geo-Redundant Backups die DB in anderer Region wiederherstellen (kann aber 1h+ dauern). Das ist last resort. Multi-Region Design Tipp: Planen Sie, wie App den Region-Wechsel merkt. DNS-Switch oder Traffic Manager für App endpoints plus DB failover group. Session-Failover etc. Summary: Azure SQL hat DR out-of-the-box. Ein Setup gängiges: Prod in West EU, GeoSec in North EU, in FG auto-failover disabled (manuell control). Testfailover jährlich. SLA für regionaler Ausfall damit abgedeckt.
Frage 13: Wie setzt man Always Encrypted in der Praxis ein?
Antwort: Always Encrypted (AE) ermöglicht clientseitig verschlüsselte Spalten – z.B. Personalausweisnummern, Kreditkartendaten. Praxis-Schritte: – Sie definieren in der DB eine Spalte mit ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY=…, ENCRYPTION_TYPE=DETERMINISTIC/Randomized, ALGORITHM=AEAD_AES_256_CBC_HMAC_SHA256). Das geht per T-SQL oder im SSMS UI. Dies muss vor dem Insert passieren, sprich Sie richten Keys ein: – Column Master Key (CMK): Bei Azure Key Vault hinterlegt oder im Windows Zertifikatsspeicher. Der Server kennt diesen nicht, nur ein Metadatum. – Column Encryption Key (CEK): Ein Schlüsselpaar, das in der DB hinterlegt wird (verschlüsselt mit dem CMK). – Die App (Client) benötigt Zugriff auf den CMK (z.B. Azure Key Vault Key, hierzu meist via Azure AD Auth und Key Vault SDK). – Im Connection String der App muss Column Encryption Setting=Enabled gesetzt sein. Dann übernimmt der .NET SqlClient die Ver- und Entschlüsselung: – Bei Insert/Update: Der Parameterwert wird vorm Senden mit CEK verschlüsselt (CEK wiederum aus Key Vault via CMK geholt). – Bei Select: Die DB liefert verschlüsselte Bytes an Client, der Client entschlüsselt transparent und gibt Klartext ins Objektmodell. – Praxis-Tücken: Deterministic Encryption erlaubt Suchen mit Gleichheit (WHERE SSN = @val geht, da verschlüsselte Werte vergleichbar), aber keine Range Queries. Randomized erlaubt gar keine Vergleiche (nur Insert und exact retrieval wenn Key bekannt). Also weniger Abfragemöglichkeiten. Außerdem unterstützt AE nicht alle Datentypen (z.B. keine ntext, image etc., aber wer nutzt die noch). – Performance: Es fallen zusätzliche Latenzen an (Roundtrip zu Key Vault beim ersten Use, dann caching). Und natürlich kann DB kein Index auf Klartext haben – es kann nur auf Ciphertext indexieren bei Deterministic (im Prinzip ok, aber Verteilung random). – In der Praxis legt man AE nur auf wirklich streng vertrauliche Spalten, oft eher wenige. Der Aufwand lohnt nicht für alles. – Testing: Es ist wichtig, End-to-End zu testen, ob die App die Keys auflösen kann. Ein häufiges Problem: Key Vault Firewall blockt DB server – aber hier geht ja Client->Vault, nicht DB->Vault, also relevant ist Client hat Rechte. – Enclaves: Neuere Variante (Always Encrypted with secure enclaves) erlaubt sogar bestimmte Operationen auf Serverseite (Sorting, Range filter), indem ein SGX Enclave im Server sensible Operationen übernimmt. Azure SQL (im vNext) unterstützt das in Preview. Dafür muss man einen Attestation-Dienst etc. einrichten. Noch advanced, aber kann potentielle Einschränkungen mindern. In 2025 noch nicht breiter Einsatz, aber zukünftig relevant. In Kurzform: AE ist super für Compliance, aber man muss damit leben, dass DB sehend blind ist auf den Inhalt – viele T-SQL-Funktionen (LIKE, > < etc.) gehen nicht auf verschlüsselten Spalten. Meist in Kombination mit nicht verschlüsselten Search-Keys oder separate Search Tables etc. implementiert.
Frage 14: Wie kann Row-Level Security genutzt werden?
Antwort: Row-Level Security (RLS) ermöglicht, auf Tabellebene Filterregeln zu definieren, die pro User/Session variieren. Anwendung: – Sie erstellen eine Inline Table-Valued Function (TVF) die prüft, ob der aufrufende Kontext die Zeile sehen darf. Z.B. CREATE FUNCTION Security.fn_allowedTenants() RETURNS TABLE WITH SCHEMABINDING AS RETURN SELECT 1 AS Allow WHERE DATABASE_PRINCIPAL_ID() = TenantId OR IS_MEMBER(‚GlobalAdmins‘) = 1;. (Pseudo-Logik: prüft ob aktueller DB-User zu Tenant passt oder Admin ist). – Dann definieren Sie eine Security Policy: CREATE SECURITY POLICY Security.TenantFilter ADD FILTER PREDICATE Security.fn_allowedTenants() ON dbo.SomeTable, WITH (STATE = ON);. – Ergebnis: Jedes SELECT/UPDATE/DELETE auf SomeTable hat implizit diesen Filter an. Benutzer sehen nur erlaubte Zeilen. – Praxis: Oft setzt man SESSION_CONTEXT-Werte statt DATABASE_PRINCIPAL_ID, v.a. wenn mit zentraler App Anmeldung: z.B. die App, die mit einem technischen Login auf DB geht, ruft zu Beginn EXEC sp_set_session_context ‚TenantId‘, @tid. Dann nutzt die TVF SESSION_CONTEXT(N’TenantId‘) in der Filterbedingung. So steuert die App welcher Tenant gerade “aktiv” ist. – Performance: RLS-Filter ist wie ein zusätzliches Where, sollte also indexgerecht sein (daher gut, TenantId in Index included). – Verwaltung: Der Vorteil ist, man spart überall im Code das manuelle WHERE Tenant = X. Weniger Fehler und man kann nicht versehentlich auf alle Tenants abfragen, es sei denn man deaktiviert Policy (was nur ein Admin könnte). – Features: RLS funktioniert auch mit SELECT INTO, etc. Mit careful: RLS greift nicht bei INSERT – Inserted Rows sind immer “sichtbar” für Insert selbst, aber könnte Sinn machen separate Blocker zu definieren (es gibt auch BLOCK PREDICATE um z.B. Updates die Tenant wechseln zu verhindern). – Multi-Tenant SaaS oft RLS in Kombi mit eine Spalte TenantId. Admin-Abfragen kann man lösen indem der Admin-User in der Policy ausgenommen ist (z.B. IS_MEMBER(‚Admins‘) override). – RLS greift je nach user context; so kann man auch z.B. Abteilungsdaten filtern basierend auf USER_NAME etc. – Für sehr hohe Sicherheit (Trennung, wo Admins auch nicht einfach aushebeln sollen), RLS ist eine zusätzliche Schicht. Aber note: A user with CONTROL permission on table or db could disable policy – aber normal app user hat das ja nicht. RLS in Azure SQL identisch wie on-prem (Feature existiert seit SQL 2016). Kein Unterschied. Implementation erfordert ein wenig T-SQL Setup, ist aber dann sehr mächtig.
Frage 15: Unterstützt Azure SQL parallele Indexerstellung und Online-Index-Operationen?
Antwort: Ja, weitgehend: In Azure SQL Database (vCore Modell) können Sie ONLINE = ON beim Index erstellen oder neu organisieren nutzen (gilt als Enterprise-Funktion, aber Azure SQL entspricht Enterprise Ed.). Das heißt, Ihre Tabelle bleibt während Indexerstellung für Schreiboperationen verfügbar mit minimalen Sperren (nur kurze Schema-Stability Locks). “Parallele Indexerstellung” – der Assistent: Azure nutzt standardmäßig parallele Threads zum Indexaufbau je nach vCores. Also ein großer Index auf 8-Core DB wird mit parallelism erstellt, schneller als seriell. Allerdings: Der Standard S0-S2 oder Basic DTU Tiers (wenn noch wer die nutzt) hatten Einschränkungen – Basic z.B. kann keine online operations. Im General Purpose vCore aber geht online. Business Critical selbstverständlich auch. Managed Instance: analog zu SQL Entperise, also Online Indexing und parallel. INDEX REORG (for fragment removal) war immer nur single threaded on any, aber INDEX REBUILD kann parallel + online, ja. Gleichzeitig mehrere Indizes bauen: In on-prem kann man via “MAXDOP” Instances parallele Indizes etc. Azure begrenzt oft Eh ein Task auf all cores. Man könnte Indizes nacheinander bauen, aber das hat mit Parallell im Befehl vs parallel threads. Wichtiger: Im Serverless Tier hat Online Index Rebuild seit Mitte 2021 Limits? Soviel ich weiß, nein, sollte gehen, aber wenn DB paused, egal. Also: Als Entwickler können Sie ziemlich alles an Enterprise Indexing auch in Azure tun. Vergessen Sie nicht: Online Index creation braucht mehr tempdb + doppelten Speicher etc., also wohlüberlegt anwenden. Azure Portal’s Automatic Tuning (Index Create/Drop) macht im Hintergrund auch online operations. Zusatz: Partition-Switches etc. – Azure SQL DB support Partitioning (GP Tier and up). Online Partition Switch ~ yes, as on prem.
Somit: Sie können 24/7-Betrieb gut mit Online Index Maintenance kombinieren – Standard bei vielen SaaS.
Frage 16: Wie läuft das Backup- und Restore-Modell bei Azure SQL?
Antwort: Azure SQL erstellt automatische Backups: Full einmal/Woche, Differential alle 12-24h (variiert), Transaction Log alle 5-10min. Diese Backups werden sicher in Geo-redundantem Storage gehalten (standard). Der Benutzer muss nichts tun – es läuft continuous. Point-In-Time-Restore: Innerhalb der Aufbewahrungszeit (7 Tage default GP, 35 Tage max wählbar) können Sie im Portal oder via PowerShell eine DB zu einem beliebigen Zeitpunkt zurücksichern. Dies erzeugt eine neue DB (Azure überschreibt nicht die laufende Prod-DB). Man kann so z.B. “DatenbankXY_restore_20231101” anlegen. Langzeitbackup (LTR): Wenn konfiguriert, werden bestimmte Full-Backups (z.B. jeweils erster des Monats) ins Archivspeicher kopiert und man kann bis zu 10 Jahre später daraus wiederherstellen. LTR ist optional pro DB einstellbar, man wählt Retention pro Woche/Monat/Jahr. Das hat separate Kosten (aber günstig). Restore Dauer: Ein PITR aus einem 1TB Backup dauert je nach Tier. Azure kopiert im Hintergrund Daten. In Hyperscale: restore ist sehr fix initial (Hyperscale uses sparse copy), aber die DB ist anfangs “Restoring” und füllt dann Daten lazy. In GP/BC: Wenige Minuten bis eine kleine DB restored, sehr große DB (TBs) evtl. >1h. Der Vorgang ist jedoch völlig automatisch orchestriert. Backup Export: In Azure SQL DB kann man kein natives .BAK erstellen. Sie können aber eine BACPAC (BLOB with schema+data) exportieren. Das ist eher ein logical export (via bacpac, slow for big DB). In Managed Instance: Zusätzlich zu obigem auto-backup kann man Manual Backup to URL nutzen (.bak auf Azure Blob Storage). Und MI kann eine .bak wiederherstellen. Single DB kann .bak NICHT direkt, nur BACPAC. Geo-Restore: Wenn Region weg, Azure kann ein Backup aus Zweitregion auf anderem Server wiederherstellen (auch wenn keine geo-secondary in place war, aber dann Stand max 1h alt). Backup Frequenz fix, aber man kann if needed sofort vorher Export (BACPAC). Wichtig: Testen Sie mal ein Restore, damit Sie Prozedur kennen und um Zeiten zu wissen. Transaction Log Access: Nicht möglich, kein BACKUP LOG Zugriff. Also man kann sich keine log shipping pipeline basteln (außer MI maybe with LRS). Tempdb: ist flüchtig wie immer, wird nach Maint Recycle. In sum: Datensicherung erledigt Azure. Das Modell für uns: im Notfall neue DB aus backup (point in time oder LTR) holen, dann manuell eventuell Daten extrahieren falls nötig. Synthese: “Backup” in Azure ist jetzt “Retention Policy” – der Adminjob wandelt sich vom Täglich Backupscript fahren hin zu “Überprüfen, ob Retention eingestellt, ob LTR gebraucht und ob restore getestet”.
Frage 17: Kann man frühere Zeitpunkte wiederherstellen (Zeitreisen / Point-in-Time-Restore)?
Antwort: Ja, wie soeben beschrieben: Azure SQL erlaubt Point-in-Time Restore innerhalb des Backup-Retention-Fensters (Standard 7 Tage, erweiterbar). Das ist im Prinzip eine “Zeitreise” der gesamten DB. Anders als einige andere DBs bietet Azure SQL allerdings keine temporale Abfrage auf Live-Daten (z.B. SELECT * FROM table FOR SYSTEM_TIME AS OF ‘yesterday’ – sowas gibt es nur, wenn Sie Temporal Tables selber nutzen). Aber um Gesamtsystem auf Zustand X zu bringen, nutzen Sie PITR. Der Ablauf: z.B. jemand hat heute um 10:00 etwas gelöscht. Sie können ein Restore per 09:59:00 heute anstoßen. Wenn fertig, haben Sie eine zweite DB, aus der Sie die verlorenen Daten entnehmen können (z.B. per SELECT oder Export) und wieder in Prod einfügen. Oder Sie entscheiden sich, die Applikation auf diese DB zu schwenken, falls die Prod irreparabel war. Granularität: Minimale Zeiteinheit ist die Log Backup Frequenz (~5 min). Also wenn man 10:03 will, und 10:00 war log, 10:05 das nächste, dann ~ bis 10:03 portion from log backup. Automatik: Nichts von dem ist automatisch sichtbar dem Endbenutzer – man muss bewusst restore anstoßen. Anmerkung: “Zeitreise” wird oft auch mit Temporal Tables assoziiert – Azure SQL unterstützt Temporal Tables (System-Versioned Tables) wie normaler SQL 2016+. Das können Sie auch verwenden, um auf Zeilenhistorien zuzugreifen – das ist aber Applikationsdesign, nicht DB Backup. Fazit: Snapshots im Sinne “Klick revert DB” gibt’s so nicht (in MI kann man evtl. Self-service back). Aber PITR gibt denselben Nutzen mit minimal mehr Schritten. Sehr zuverlässiges Feature – hat schon viele vor Datenverlust bewahrt.
Frage 18: Welche Metriken sollte man beim Monitoring von Azure SQL unbedingt im Blick haben?
Antwort: Wesentliche Metriken: – CPU-Auslastung (oder DTU-Auslastung wenn DTU-Modell) – zeigt, wie ausgelastet die Compute-Ressourcen sind. Dauerhaft hohe CPU > 80% = Warnsignal, evtl. Skalieren oder Query optimieren. – Speicher (Memory usage): Wird als percent of max nicht direkt als Metrik exponiert, aber über “memory pressure” DMVs oder in Azure Portal indicted. Wichtig, weil Memory knapp -> mehr IO, langsam. Im vCore-Modell ist RAM fest pro vCore (z.B. 5GB/vCore GP). – IO-Latenz und Durchsatz: Azure Monitor hat “Log Write percent” und “IO percent” etc. Wenn diese regelmäßig an 100% gehen, stoßen Sie ans Tier-Limit. Auch storage_write_io_sec metric. Hohe Disk Queue in DMVs deutet auf Engpass. – DTU limit (im DTU model) – ob DB oft am Limit throttelt, unbedingt beachten. – Connections: Number of active sessions, um Leaks / Connection explosion zu erkennen. – Deadlocks: Azure Monitor kann Deadlock count tracken (oder XEvent). Besser keine haben – wenn ja, Code anpassen. – Blocked Processes: Indirekt aus DMVs (sys.dm_tran_locks vs waiting tasks) oder XEvent. Das erkennt man am Symptom (Anfragen stuck). – Wait Statistics: Azure Monitor surface das nicht direkt, aber man kann XEvent oder Query Store (neuerdings QS sammelt Waits per query). Wartezeiten wie LCK_M_X, PAGEIOLATCH, CPU SOS_SCHEDULER sind Indikatoren wo’s hapert (Locking, IO, CPU). – Storage Used: Wie viel % des zugewiesenen Speichers belegt. Wenn nahe 100%, DB kann nicht wachsen -> risk. Also Alarm bei 80-90%. – TempDB: In MI kann man TempDB size (and spills) checken, in Single DB gibts pro DB eigenes Temp (32GB per vCore limit). Wenig direct metric, aber if heavy sorts, look at sys.dm_db_session_space_usage. – Failed Connections/Logins: Indikator ob z.B. App falsches PW (Sicherheitsaspekt) oder Frequent reboots (Availability issues). – Auto-tuning actions: im LogAnalytics oder azure notifications sieht man, falls ein Index auto-created/dropped wurde, was evtl. Perf beeinflusst – im Monitoring zumindest nachvollziehen. – Azure Service Health: falls Azure outtage, aber das ist global. Focus auf CPU, IO, Memory, Waits – wie immer. Und Kostenmonitoring (though not a metric on DB itself). Sie können Azure Metric-Alerts auf z.B. CPU > 80% (5min) und storage > x% setzen. Und Query Performance Insight im Portal mal checken (Top CPU queries). Summiert: CPU und IO Bottlenecks sind meist vorrangig. Mit Query Store und Wait Stats kann man dann tiefer einsteigen.
Frage 19: Wie geht Azure SQL mit plötzlichen Lastspitzen um und was sollte man beachten?
Antwort: Azure SQL kann kurzfristige Lastspitzen bis zur maximal bereitgestellten Kapazität verarbeiten. Es gibt kein Auto-Scaling (außer im Serverless-Modell). Wenn eine Lastspitze Ihre vorhandenen Ressourcen überschreitet, werden Anfragen verlangsamt oder ggf. gedrosselt. Im DTU-Modell würde z.B. das Request-Queueing einsetzen (Anfragen warten, bis DTUs frei). Im vCore-Modell gibts ein hartes physisches Limit – Anfragen nutzen alles, aber wenn CPU 100% ist, werden sie einfach langsam, es gibt aber kein spontanes mehr an Leistung. Beachten: – Throttling Mechanismen: Azure SQL begrenzt parallel Tasks/IO etc. Bei extremer Spitze (z.B. tausende Verbindungen auf einmal) können Verbindungsversuche fehlschlagen (throttling). Es gibt Fehlermeldungen wie “service is busy”. Dann sollte App side Retry. – Planen Sie Kopf frei: Eine DB sollte idealerweise <70% normal laufen, damit Spikes auf 100% verkraftbar sind. – Skalierungsdauer: Ein manuelles Hochskalieren (z.B. 4 -> 8 vCores) dauert i.d.R. 1-2 Minuten (in GP online, minimal hiccup). Aber das kriegt man während einer plötzlichen Spitze oft nicht reaktiv hin (Spitze vielleicht in Sekunden). Daher präventiv, wenn absehbar (z.B. Launch Kampagne um 12:00, dann 11:55 hochskalieren). – Serverless-Modell Verhalten: Hier reagiert das System innerhalb von Sekunden/Minuten auf Lastanstieg. Derzeit kein Guarantee, aber oft deutlich spürbar – CPU ramped up. Aber sehr abrupt High CPU kann einen Tacken länger brauchen. – Pooling/Queuing: Der App-tier (z.B. Webserver) sollte ggf. auch Raten begrenzen (z.B. nicht unendlich parallel DB calls erlauben). Patterns wie Bulkheads, Queue in middle-tier etc. können abfangen. – Testen Sie Spikes: Z.B. per JMeter viele parallel user, dann Monitor DB. – Multi-Firewall: Plötzliche Lastspitzen von zig IPs könnte auch an Firewall rules stoßen, aber normalerweise unlimited as long as connections under limit. Im Worst-case, wenn Spike Überlast bringt: App sieht timeouts, DB had 100% CPU – dann entweder Query optimizing (vielleicht ein missing index hat CPU vermehrt), oder vCores erhöhen. Azure hat keinen burst-credit System wie manch Cloud DB (keine CPU Credits – entweder du hast vCore or not). Beispiel: Black Friday, 10x traffic – mit vCore 4 würde es erst saturieren und latenz hoch. Besser paar Tage davor auf vCore 8, danach runter. Zusammenfassend: Azure SQL schützt sich (Stabilität), es wird keine requests “droppen” außer connections refused if too many. Es wird aber auch nicht magisch mehr horsepower geben (außer serverless). Also high spike mgmt = design-time decision (scale up or out via reading replicass if read heavy).
Frage 20: Wie gestaltet man Azure SQL für ein Multi-Region-Szenario?
Antwort: Multi-Region-Szenarien gibt es in zwei Hauptvarianten: Disaster Recovery (passiv) oder Active-Active (aktiv). – Für DR: Wie in Frage 12 besprochen – man nutzt Failover Groups oder Geo-Replication. D.h. Primary Region hostet die R/W DB, Secondary Region hat read-only standby (kann optional genutzt werden fürs Lesen). Im Fehlerfall schaltet um. Das ist der gängigste Multi-Region-Ansatz, um Ausfall einer Region zu überleben. Minimiert Downtime und Datenverlust. Zu bedenken: App-Schicht muss drauf vorbereitet sein (Namensauflösung via global DNS oder Traffic Manager, und ggf. am Client die Server=<fglistener> anstatt fix region server). – Für Active/Active Lese-Szenario: Man kann z.B. eine App in Europa und eine in USA haben, beide lesen viel, schreiben aber lokal. Schreiben kann man nur in einem Azure SQL at a time (kein multi-master direkt). Workaround:
– Aufteilung der Daten (Geo-Sharding): z.B. EU-Kunden in EU-DB, US-Kunden in US-DB. Applikation route requests nach region. Das ist eher Partitionierung nach Region, nicht echte Active-Active auf denselben Daten. – Oder “Active-Active” mit Abgleichen: Das ist tricky – es gibt Azur SQL Data Sync (Hub-Spoke Sync Service), aber das hat Latenz und Complexity, und es ist sogar im Retirement begriffen. Besser: Versuchen, multi-master zu vermeiden auf DB-Level, stattdessen Applikation Partition oder nur read local, write central. – Alternative: Wenn App in beiden Regionen writes braucht und latenzempfindlich: Überlegen Sie, auf Cosmos DB (Multi-master DB) zu gehen für diesen Teil – wenn relational unersetzbar, MI oder SQL on VM with distributed AG? (Nein, Azure SQL DB support multi-write via auto failover groups in „Read/Write Region pairs“ mode? Derzeit FO group is single-write.) – Azure Traffic Manager/Front Door: steuern global user to nearest region. Und auf DB-Seite hat man dann pro Region entweder separate DBs oder read replicas. – If read mostly: Du kannst in West-EU primary, East-US geo-secondary, Clients US connect read-intent to local (fast reads), writes goes still to EU (so cross-latency for writes). – Oder über Failover Group with Multi-region read (so each region app reads local, writes route to primary region always). – Latenz: Minimieren, indem user-> nearest region for reads. Writes wird schwer ohne sacrifice consistency (cap theorem). – Managed Instance Link Feature: brandneu (2024 Preview) – ermöglicht near-real-time replication zwischen on-prem und MI, später MI-MI? Hier Ausblick: vllt. kann man irgendwann mehrere MI aktiv sync cluster (like distributed AG). Aktuell nicht mainstream. – Wenn absolute continuity: Für Lebenskritische Sys kann man noch Zusatz backup in 3. Region etc. – Testing Multi-region: Plan Verbindungsstrings so, dass umschalten einfach (z.B. im config eine “ActiveRegion” toggeln oder so). Ziel: Minimale Änderungen an App bei Failover. Datenbank- und Applikationsentwurf: – Datenspeicherung so gestalten, dass cross region calls minimal. Z.B. global static data replicate in both, dynamic in one, references by key. – Using event-driven eventual consistency: e.g. each region writes to their DB, then an integration pipeline merges daily. Not trivial. In Cloud, Active-Active transaktional is toughest. Many choose one primary region with ability to failover. Wenn wirklich gleichzeitig global writes needed, Azure SQL kann es Stand heute nicht. Fazit: Multi-Region: Meistens Primary + failover plus optional read scaling. App arch muss dieses Patterns adaptieren.
Frage 21: Wie erreicht man Mandantenisolation in Azure SQL (für SaaS)?
Antwort: Dafür gibt es zwei Hauptrichtungen: – Physische Isolation: Pro Mandant eine eigene Datenbank (oder sogar Schema) – damit sind die Daten physisch getrennt. Azure SQL mit Elastic Pools unterstützt das Muster (siehe Szenario 5.2). Isolation ist stark: kein Mandant kann aus seiner DB die eines anderen sehen, es sei denn, die App macht groben Fehler mit falschem Connection String. Dies vereinfacht Compliance (Datenbank = Mandant) und erlaubt individuelle Verwaltung (Backup/Restore je Mandant, performance isoliert, etc.). Nachteil: Overhead bei vielen Mandanten (Verwaltung vieler DBs) und evtl. ineffiziente Ressourcennutzung – darum Pools. – Logische Isolation: Mandanten teilen sich die DB, und Row-Level Security trennt die Sichten (plus im Idealfall separate Logins pro Mandant oder mind. Session Context). Das erfordert absolut korrekte Implementierung – ein Fehler in der WHERE-Klausel oder ein vergessener RLS-Eintrag könnte Daten leaken. Es ist aber ressourcenschonender (eine DB nutzen) und einfacher zu deployen (Schemaänderung betrifft alle auf einmal). RLS und ggf. zusätzliche Prüfsummen (Mandant-ID in jedem Index) müssen sorgfältig aufgesetzt sein. – Kombination: Manche SaaS machen pro Mandant Schema (so tabellen mit SchemaName.Table), isolieren so etwas (eine Mandant kann nur seine Schema nutzen), aber am Ende kommt es dem eigenen DB gleich. Das ist seltener. – Azure Security: Im physischen Isolation Fall kann man pro Mandant optional sogar eigenen SQL Server (logical) mit nur seiner DB und spezifischem admin einrichten – das ist heavy, meist nicht nötig (5000 server for 5000 tenants not realistic). – Empfehlung: Bis mittlere Mandantenzahl (< 1000) und differenzierte Anforderungen -> separate DBs mit Pools, wie in 5.2. Bei sehr vielen kleinst-Mandanten (>1000, wie z.B. Free-tier Tenants) -> ggf. Multi-tenant DB mit RLS für die Masse, und große Kunden isoliert auf eigene DB. – Auf Applikationsebene: Stellen Sie sicher, dass bei physischer Isolation Mandant A niemals Connection-String von B erhält (Trennung in Code/Config, vllt. nach Org). Bei logischer Isolation, konsequent RLS und test with malicious scenarios. – Datenfluss isolieren: Backup/Restore eines Mandanten (bei physisch trivial, bei logisch muss man filtern per Tenant = X, extrahieren). – Azure AD: Evtl. kann man auch Mandanten in AD Gruppen stecken, und RLS per USER aus AD steuern – dann loggen sich user mit OrgA-Konto ein, DB mappt zu user OrgA, RLS filtert OrgA rows. Das ist high-end, aber möglich. – Schutz vor noisy neighbor: Physisch – kann pro Mandant notfalls Tier hoch/runter. Logisch – ein Tenant-Heavy-Query kann DB belasten, alle betroffen. Kann dann nur quellcode-seitig quell quell. Also Mandantenisolation: DB pro Mandant = Maximum isolation, RLS = softer isolation aber simpler infra. Oft nutzt man beides je nach Segment.
Frage 22: Wie lässt sich in Entwicklungs-/Testumgebungen mit Azure SQL Geld sparen?
Antwort: Einige Tipps (vieles auch bei Frage 4. und Szenario 5.5 angesprochen): – Nutzen Sie das Azure Dev/Test Angebot: damit bekommen Sie SQL PaaS ohne Lizenzkosten (nur Azure Infrastrukturkosten), was ~30-40% spart. Erfordert EA oder Visual Studio subscription usage, aber lohnt sich. – Serverless einsetzen: Für alle DBs, die nicht 24/7 aktiv genutzt werden (Dev, Test, QA) – Serverless mit Auto-Pause. So zahlen Sie vielleicht 4-5h am Tag, Rest 0. Speziell Einzelentwickler-DBs ideal. – Kleinere Leistung: Setzen Sie Test-DBs auf das kleinst sinnvolle Tier. Viele Tests gehen auch auf 2 vCore statt 8 vCore wie Prod. Wenn Performance-Test benötigt, kann man vorübergehend hochskalieren. – Teilen statt Duplizieren: Statt für jeden Entwickler eigene komplette MI/Server, überlegen, eine MI mit mehreren Test-Datenbanken, oder ein gemeinsames Integration environment pro Team. Isolation dort aber entsprechend abstimmen (vielleicht separate Schemas oder so). – Zeitgesteuert abschalten: Ist man diszipliniert, kann man mittels Automation off-hours Umgebungen “deallocaten” – Single DB kann man leider nicht Stop (nur MI kann Stop). Aber man kann z.B. per Script nightly copy die DB weg (or drop) und morgens neu deploy. Das ist nur sinnvoll, wenn Aufbau schnell automatisiert. – Aufräumen: Häufig bleiben alte DBs liegen. Setzen Sie Tagging und Lifecycle: z.B. jede CI-Test-DB bekommt Tag “autodelete after 7 days” und ein Script löscht die wöchentlich. – Monitor Kosten pro Ressource: Azure Cost Management nach Kategorie filtern – finden, ob z.B. eine vergessene DB $$$ verbraucht. – Pipelines mgmt: In CI, drop created DB at end of run. In Dev, educate developer to power down what not used. – Alternativen: Für rein funktionale Tests ggf. LocalDB/SQLExpress or In-Memory alternatives falls real DB overhead. Oder z.B. use smaller dataset in test (subscribe, not full prod clone). – Check region pricing: West Europe vs. North Europe teils minimal anders. Dev environment könnte in etwas günstigere Region, sofern Latenz egal – aber in Azure differences minimal, eher in bigger geo (US vs EU). – Reusing licenses: Falls Sie on-prem Developer Edition (kostenlos) nutzen: On Azure, das Pendant ist Dev/Test Subscript. – Consider Paas vs VM: Manchmal für Test könnte ein SQL on VM dev mode with license from MSDN be cheaper if you run heavy but short times – but then losing PaaS comfort. Usually PaaS with auto pause still best.
Frage 23: Wie kann man Datenmaskierung in Staging-Umgebungen umsetzen?
Antwort: Die Frage zielt vermutlich darauf ab: Sie haben Prod-Daten, wollen sie in Staging/Test nutzen, aber vertrauliche Felder sollten verfremdet sein. Lösungsansätze: – Dynamic Data Masking (DDM): Azure SQL feature, wo man auf Spalte eine Maskierung definiert, z.B. Email “xVisiblePart” Funktion, Kreditkartennummer als XXXX-XXXX-####. In Staging könnten Sie DDM aktivieren, so dass z.B. Tester mit leserolle nur maskierte Werte sehen. Problem: DDM ist oberflächlich – die Daten sind in DB noch echt, und wer Masken umgehen kann (z.B. DB-Owner) sieht sie trotzdem. Für Staging, wo man Devs vielleicht Owner gibt, nützt es dann nix. DDM eignet sich mehr für Prod, um ApplicationSupport oder Abfragen über read accounts zu beschränken. – Klonen mit Anonymisierung: Besser: Wenn Sie ein Prod-Backup ins Staging einspielen, führen Sie danach ein Anonymisierungsskript aus. Das Skript könnte z.B.: Setze alle Namen auf “Max Mustermann”, verschiebe Geburtsdaten um zufälligen Wert, löschen/überschreiben aller E-Mail-Felder, etc. So enthält die DB realistische Verteilungen, aber keine echte personenbezogene Info. Das Skript kann Transaktion sein oder via Bulk logic. Das erfordert einmal Aufwand, aber ist zuverlässig. – Verwenden Sie Azure Purview & Data Masking Tools: Es gibt Tools, die Datenklassifizierung und -maskierung orchestrieren. Azure Purview (jetzt Microsoft Purview) kann z.B. sensitive columns entdecken. Es gibt auch Drittanbieter, die Pseudonymisierung pipelines anbieten. – Synthese: The best approach often: – Option 1: in Prod, definieren dass sensitive columns are Always Encrypted in Prod (very heavy approach) – then in staging you simply don’t have keys to decrypt, so testers see gibberish. But that means coding around encryption – heavy. – Option 2: use Dummydaten in Staging by design. Many testcases don’t need full prod, maybe generate synthetic data. – Oft pragmatisch: True Prod duplicates for performance test but w/o PII fields (like clear out personal data columns completely or replace with dummy). – For EU GDPR etc. anonymization is must if using prod data in nonprod. – Also be mindful: possibly restrict who can access staging if it has semi-real data. In sum, there’s no magic “flip mask on staging for all data appropriately” – usually custom scripts or use DDM for some fields if that suffice for testers. Possibly a combination: e.g. you keep phone numbers but mask last 4 digits with DDM – testers see partial but not full. It’s a quick method with minimal overhead. But I’d lean on actual data modification for strong compliance.
Frage 24: Was macht man, wenn man Legacy-Features wie CLR oder Service Broker in Azure SQL braucht?
Antwort: Zwei Möglichkeiten: – Auf Azure SQL Managed Instance wechseln, sofern möglich. MI unterstützt beide: CLR (safe/external without file access) und Service Broker (innerhalb MI). So können Sie den Code mit minimal Änderung betreiben. Evtl. muss man unsichere Assemblies neu kompilieren als safe oder auf Files verzichten. SB Queues laufen analog. Das ist der straightforward Weg, wenn Legacy behalten und cloud vorteile trotzdem will. – Refactoring auf Alternativen: – Für CLR: viele CLR-Funktionen ließen sich evtl. in T-SQL (jetzt mit JSON/Xml support, oder neu mit JavaScript via external language – in Azure not yet available) neu schreiben. Oder im Applikationscode statt im DB. Das erfordert Dev-Aufwand, aber entlastet DB. – Für Service Broker: Falls SB zum Async-Messaging genutzt wurde, kann man über Wechsel zu externen Message Broker (Azure Service Bus, RabbitMQ) nachdenken. Oder wenn es nur innerhalb DB genutzt war, vielleicht simpler via SQL Agent und Status-Tabellen neu implementieren. In Azure DB (Single) gibts aber keinen Agent – Replacement ist tricky: Workaround via Azure Function Timer reading table, etc. – Falls man auf Azure SQL Database (Single) bleiben will: – CLR: Geht garnicht. Workaround: vielleicht via external Web Services or Azure SQL ML Services – not trivial. Besser, Auslagern in an API Service: DB ruft via sp_send_http_request (gibt es auch nicht…) -> DB can’t call out. So App must orchestrate. – Service Broker: auf Single DB: auch nicht vorhanden. Alternative Patterns: Polling table + SignalR or so for decoupling (inefficient). Or upgrade to MI. – In vielen Lift&Shift-Szenarien ist MI der Retter, wie in 5.3. – Another example: CROSS DB transactions – MI. So, if you need legacy, accept a bit less PaaS (MI is fully PaaS though, just more expensive than single DB maybe). Also consider: is the legacy feature maybe not needed? E.g. maybe SB was used for workload that could be replaced by simpler approach in code. Answer TL;DR: Use Managed Instance to keep them, or refactor out of those features towards cloud-friendly services.
Frage 25: Wie geht man mit Batch-Verarbeitungen auf einer OLTP-Datenbank um?
Antwort: Batch-Jobs (Massenupdates, periodische Aggregationen etc.) können OLTP stören, weil sie viele Ressourcen ziehen. Strategien: – Off-peak scheduling: Falls möglich, Batchjobs so timen, dass Hauptlast vorbei (nachts, Wochenende). In PaaS kein explicit maintenance window, aber Sie kennen Ihr usage pattern. – Throttling in Batches: Anstatt 1 Mio Zeilen in einem Statement updaten, machen Sie es in chuncks – z.B. 10000er Runden mit Pause/WAITFOR. So verteilt es Last und blockiert nicht dauerhaft. – Use proper transaction scoping: Verarbeiten in kleineren Transaktionen, um Lock-Eskalation zu vermeiden. – Lock hints: Wenn es rein offline Batch ist, evtl. TABLOCK + minimal logging (in BulkOps) kann schneller sein – aber auf Azure SQL minimal logging nur in certain conditions (bcp to heap with tf610? Not allowed maybe). – Separate compute: Evtl. auslagern: Beispielsweise, extrahieren der relevanten Daten in Azure Databricks/Synapse, dort verarbeiten, Ergebnis zurückschreiben. Spart DB CPU, aber nur lohnen bei heavy transformations. – Scale up for batch: Azure Flex: vor Batch vCores hoch, nachher runter. If daily heavy ETL, maybe cheaper to double power for 2h (with pay by hour) than letting it run 10h on slow tier. – Isolation: If batch can run on second instance of data (like a restored copy), do it offline und then swap needed results in. But often not possible for updates. – Tune queries: Ensure batch queries have indexes to avoid table scans if not needed (though sometimes scanning all is what batch does, then nice if physical order helps). – Check for Resource Governor? In MI, not currently public (not sure, MI might not allow user RG). So, treat batch as special citizen: schedule, chunk, maybe illusions concurrency by splitting tasks. Use logic like: update 100k rows -> commit -> wait 1s -> next 100k. If using Service Broker previously for background tasks – in Azure maybe do an Azure Function triggered by Timer or queue. That moves batch outside DB. One common scenario: reindex or summary nightly – Azure might handle indexing, but summarization tasks maybe better in an ETL pipeline to a small summary table rather than heavy group by on big OLTP table on the fly. Thus, either design OLTP to handle it (maybe partition by date and only process new partition), or offload.
Frage 26: Wie geht Azure SQL mit Parameter Sniffing um bzw. wie kann man stabile Abfragepläne sicherstellen?
Antwort: Parameter Sniffing ist auch in Azure SQL (selbe Engine) ein Thema: Der erste Ausführungsplan für eine Parameterisierte Query wird im Plan Cache/Query Store verwendet auch für andere Parametervarianten, was suboptimal sein kann. Lösungsoptionen: – Query Store zu Hilfe nehmen: Sie können im Portal oder via T-SQL Query Store sehen, wenn eine QueryId stark schwankende Laufzeiten hat. Dann können Sie ggf. manuell einen Plan forcieren, oder – Automatic Tuning – Force Last Good Plan: Azure kann das bei starker Regression tun. Das greift aber erst N Minuten, nachdem Problem auftrat. – Query Hints: Klassiker: OPTION (OPTIMIZE FOR UNKNOWN) neutralisiert Parameter Sniffing, indem DB Standardverteilung annimmt. Oder OPTIMIZE FOR @param = <typical value> if one typical case. – Plan-Guides: in MI or Azure DB can use sp_create_plan_guide to add hints without changing code. (Trickier, but possible). – Newer SQL Features: Azure SQL (Engine vNext) beinhaltet Parameter Sensitive Plan (PSP) Feature (SQL Server 2022). Das erkennt, wenn es verschiedene optimal Pläne für unterschiedliche Parameter gibt, und kann im Query Store mehrere Pläne halten je nach parameter range. Diese Funktion ist Teil von Intelligent Query Processing und sollte in Kompatibilitätslevel 160 aktiv sein. Das kann Parameter Sniffing Probleme automatisch mildern. Prüfen Sie, ob es aktiviert ist (ein Indikator: in Query Store sieht man multiple plans for one query with different parameter ranges). – Worst-case plan via recompile: In manchen kritischen procs setzt man WITH RECOMPILE oder Option (RECOMPILE) auf problem query, damit jede Ausführung eigenen Plan. Das beseitigt Sniffing, kostet aber CPU. – General best practice: If you know some param cause table scan vs index seek etc., you can restructure Query (split logic into two queries based on param ranges, each optimized for scenario). – Azure does nothing magical beyond what SQL Engine does. They did give us quick detection and automation via QDS and PSP. So, stable Pläne: Monitor with Query Store, use forced plan if one plan is overall safer (maybe not absolutely best for some values but good for all). Or adapt code with hints. One extra: ensure statistics up to date, to reduce misestimation. One should also be careful with „local variables vs param“ – using local var triggers sniffing avoidance at cost of generic plan; sometimes helpful if no better route.
Frage 27: Wie sehen die Verbindungszeichenfolgen mit Azure AD Authentifizierung aus bzw. was ist zu beachten?
Antwort: Um mit Azure AD (Z.B. OAuth Bearer Token oder Integrated via Managed Identity) zu verbinden, die Connection Strings weichen leicht ab: – Für Azure AD Benutzer/Passwort (nicht empfohlen für App, besser integrated): Server=tcp:<server>.database.windows.net; Database=<db>; Authentication=Active Directory Password; UID=<user>@<tenant>.onmicrosoft.com; PWD=<password>; – Hier muss man den UPN und PW eines AAD-User angeben. Nicht so toll, da PW im config; man kann aber Azure AD Service Principals similarly: UID=<AppId>; PWD=<ClientSecret>; Auth=Active Directory Password (or integrated? Actually service principal uses „Active Directory Service Principal“ as auth mode). – Für Integrierte Auth (Managed Identity oder AD logged user): Authentication=Active Directory Integrated (works if running on domain-joined or azure VM with AD) oder Authentication=Active Directory Default. Letzteres ist neuere .NET, versucht verschiedene Methoden: environment, MSI etc. In Azure Functions mit MSI z.B. Authentication=Active Directory Default reicht. Alternatively Authentication=Active Directory MSI (older syntax) with User Id=<clientId> if user-assigned identity. Or in connection string you omit user/pw entirely and rely on environment (AzureServiceTokenProvider in code). – Für Active Directory Interactive: interactive flow with popup, not for production usage. Good for dev. – Active Directory DeviceCode: possible variant for tools. – Active Directory Managed Identity: If using system-assigned MI, one can do Auth=Active Directory Managed Identity and optionally specify UID=<clientId> for user-assigned. Beachten: – Die JDBC oder anderen drivers haben jeweils eigene keywords (e.g. JDBC: authentication=ActiveDirectoryIntegrated or …=ActiveDirectoryServicePrincipal). – Azure AD Auth erfordert, dass Azure SQL einen AAD Admin gesetzt hat und der Benutzer entspr. in DB als User vorhanden ist (CREATE USER FROM EXTERNAL). Das Setup muss also einmal erfolgen. – Wenn App mittels Managed Identity: man muss dem MI im SQL als User Rechte geben (e.g. in master: CREATE LOGIN [<Azure AD objectId>] FROM EXTERNAL PROVIDER; in DB: CREATE USER…; then grant roles). – Token-Cache: libraries manage it, but initial token retrieval might cause slight delay on first connection. – If using AAD Password auth, ensure MFA disabled or use interactive flow cause MFA won’t work with direct password. – Use Encrypt=True; TrustServerCertificate=False always (some older doc left them out). – Connection Pooling: If using Integrated mode on Windows, be aware connections in pool cannot be reused across identities, but in server scenario usually one identity anyway. – Tools like EF Core allow .AddAzureADAuthentication(some builder extension) to simplify. Im Endeffekt, key difference in connection string is Authentication=… parameter, and no explicit password for integrated. Also User Id vs UID synonyms etc. Azure AD can sometimes be tricky to configure (SPNs etc.), but once it works, it’s stable. For managed identity, no secrets is big win.
Frage 28: Welche Limits und Quotas gibt es bei Azure SQL?
Antwort: Azure SQL hat diverse Limits, einige wichtigsten: – Max DB Grösse: GP 4/8 TB, BC ~4 TB, Hyperscale 100 TB (Single DB). MI GP 16 TB, MI BC 4 TB. – Max vCores: 128 vCores per DB or MI. Elastic Pool similarly up to some value (GP pool up to 128 total). – Max Databases pro Server: Standard 5000 DBs per logical server for Single/Pool. Pro MI: ~100 DB (GP), ~ 100? MI can be increased to e.g. 400 by request, but performance degrade perhaps. – Max Sessions/Connections: Azure SQL DB: around 30k sessions per DB (also worker threads ~ worker limit e.g. 300 per vCore or similar). MI: more akin to on-prem (somewhere in 32000 connection area). – Max concurrent logins /requests: There’s throttle if too many connect/disconnect per time; roughly documented but seldom hit realistically (< 1s). – Transaction Log throughput: For example GP log 22 MB/s per core cap, BC can go ~ 1 GB/s for high core. It’s in docs (GP ~ 48 MB/s max?). – TempDB: For Single DB, tempdb limit 32GB per vCore up to 2560GB (80 vCores). MI: tempdb limited by instance size (MI GP: entire instance 24GB per vCore total?). – Compute quotas per sub: By default each sub can only create e.g. 5400 DTUs or 50 vCores total in a region. If you need more, raise support ticket (so called subscription quota for SQL). Also 250 servers per sub per region. – Connection Timeout: not a limit, but default 30s. Idle connection is closed after 30 min (I think Azure might reset idle connections eventually). – Rate limits: Manage via some internal QoS if needed. But typically not user facing numbers. Possibly e.g. only 1 restore operation at a time per server etc. Or only 4 concurrent scaling operations per sub. – Encryption keys: e.g. up to 16 key vault integration per server? Something around that. Not usually hit. – Managed Instance: some unique ones: e.g. only 8 TB per DB, only 1 AG group possible (backing HA), etc. – DTU model: if used, certain caps e.g. P15 is highest with 4000 DTUs. – Elastic Jobs preview had some limit number of jobs etc. – Azure Arc: if we mention, but question likely focusing PaaS. Anyway, the main ones: DB size, number of vCores, number of DBs, sessions, memory. These quotas can be found on MS docs. Usually for normal use hardly hit except DB size or performance ones. But at scale SaaS you might hit e.g. server 5000 DB limit. To handle hitting a limit, you often can request raise (like vCore quotas) or scale-out to multiple logical servers if needed.
Frage 29: Welche Metriken sollte man heranziehen, um Service Level Objectives (SLOs) zu definieren?
Antwort: Für Azure SQL, SLOs (die man dem Business verspricht) drehen sich um: – Verfügbarkeit: pro Jahr/Monat uptime (SLA 99.99% from MS, you might promise 99.9 to customers factoring planned maintenances etc.). Metriken: downtime minutes, failover events count etc. – Performance: z.B. < X ms Reaktionszeit für bestimmte Transaktionen im 95. Perzentil. Hier: Query Duration or app-level transaction time. Could measure from App telemetry or at DB e.g. using Query Store Wait Stats. – Throughput: e.g. DB able to handle Y transactions per minute at peak with <Z latency. So metrics: maybe log flush rate or CPU headroom ensure always < 80%. – RPO/RTO (in DR context): If part of SLO, e.g. „At most 5 min data loss (RPO)“ – metric is log backup frequency and confirmed replication, basically under 5 min log shipping gap (not directly a metric but can test). – Security: maybe SLO around data protection, not a metric but yes compliance events (like 0 data breaches). – Support metrics: e.g. time to respond to incidents, relevant if service-internal SLO. Not DB metric though.
Concretely: – For performance SLO, define maybe „average CPU < 70%“ as an internal objective to ensure slack. Or „P99 query duration < 1s“. These come from either DB telemetry or APM (application performance monitor). – So baseline metrics from QPI (Query Performance Insights): if that shows 99% queries < 500ms, you can use that as baseline and commit similar or improved SLO.
Focus on user experience metrics in SLO: e.g. page load times, which depend on DB query times (that’s deeper level though).
But if specifically about DB SLO: – CPU usage below threshold – wait times (like average wait time per query type), – #deadlocks (target 0), – backup age (should never beyond schedule), etc.
So you measure them regularly to ensure meeting SLOs or else scale/have plan B.
Frage 30: Wie trifft man Architekturentscheidungen, die auch zukünftig (mit Blick auf die Roadmap) noch gültig sind?
Antwort: Das ist etwas philosophisch, aber: – Bleiben Sie bei Standard-Services: Verwenden Sie Mainstream Komponenten von Azure SQL (GP/BC Tiers), vermeiden Sie exotische Previews ohne Not. Microsoft’s Roadmap meist beibehalt baseline features. Z.B. Elastic Pools existieren seit Jahren, safe. Aber Data Sync wird retired (d.h. war Nischenfeature). – Entkoppeln Sie Architekturschichten: Wenn Sie Architektur so bauen, dass man Komponenten austauschen kann, macht Sie das zukunftssicher. Bsp: Applikation nicht zu DB-spezifisch (z.B. keine vendor lock-in sprocs, falls Idee war multi-cloud; aber in MS stack ist das okay). Oder: Vermeiden Sie heavy use of soon-to-be-deprecated features (hier hilft Azure Updates info). – Skalierbarkeit einplanen: Wählen Sie Patterns, die erlauben zu wachsen. Roadmap: z.B. Hyperscale emerged – if you foresee potential 10TB, design such that moving to Hyperscale is straightforward (no features not supported there). Or multi-tenant: plan that maybe 100 -> 1000 tenants, initial single DB might fail, so choose pattern which can distribute later (shard key usage etc.). – Verfolgen Sie Cloud Updates: Azure evolves quickly. Keep an eye on Azure announcements (Ignite, Build) for new DB capabilities. Incorporate them if beneficial but also ensure design can adapt. E.g. spate of new index types or geo replication improvements. – Flexibility: Possibly build abstraction in data access layer so if in future you adopt e.g. Cosmos or an event store aside, not entire rewrite. – Simplicity & clarity: Often a straightforward, well-known architecture (like microservice with DB per service) ages better than a hacky complex one. The simpler, the easier to pivot when needed. – Avoid tech dead-ends: If you hear feature „will be retired“ plan migration early (like Data Sync). Or if a on-prem feature is on life support (Service Broker?), maybe not build new things on it, use alternative.
Examples: Instead of relying on cross-db queries (which hamper scale-out), design with integrated or one db, or orchestrate in app. So that in future if you want to move to a sharded model or easier PaaS, you’re not stuck.
Instead of heavily using CLR in DB (which is not cloud-friendly in DB-as-service), keep such logic in service layer. That future-proofs if you move to other DB etc.
I.e. favor loosely coupled, and standards (T-SQL, but portable logic where possible).
In summary, to future-proof: – Keep abreast of Azure Roadmap – e.g. know that azure is pushing toward more PaaS, multi-model integration (like via Synapse Link, etc.), design to leverage them maybe. But don’t adopt anything that isn’t proven unless necessary (avoid „peak of inflated expectations“ tech).
Also, design with modernization in mind – e.g. if using MI as interim for legacy, plan how to eventually break monolith into smaller.
No one can guarantee longevity (maybe in 5 years new DB tech, but SQL likely here to stay), but using widely adopted patterns and staying flexible is key.
Finally emphasize: Cloud architecture is iterative – keep evaluating decisions periodically vs new offerings. For example, maybe in 2025 or 2026, a native PaaS feature covers something custom you built – might simplify then. Remain adaptable.
<br>
10. Fazit
Azure SQL bietet für Entwickler eine leistungsfähige und vertraute Datenbankplattform, die gleichzeitig den Großteil des Betriebsaufwands an die Cloud abgibt. Je nach Reifegrad der Anwendung und Anforderungen an Kompatibilität kann man zwischen Azure SQL Database (ideal für neue Cloud-Anwendungen, Microservices, SaaS mit vielen Mandanten) und Azure SQL Managed Instance (ideal für Cloud-Migration bestehender SQL-Server-Lösungen mit minimalen Änderungen) wählen. Beide PaaS-Formen bringen automatische Hochverfügbarkeit, Backups und Skalierbarkeit – im Gegensatz zum klassischen SQL Server, wo man dies selbst implementieren musste.
Für Cloud-Einsteiger empfiehlt sich oft, zunächst einfach eine Azure SQL Database in kleinem Tier bereitzustellen und Erfahrungen zu sammeln – man bekommt schnell spürbare Vorteile (keine VM, simples Backup, vertraute Tools). Fortgeschrittene Teams werden dann bestimmte Azure-Features gezielt nutzen: etwa automatische Indexoptimierung, Integration mit Azure AD für die Sicherheit, oder Serverless, um Kosten in Dev/Test zu minimieren. Auch komplexere Szenarien wie Multi-Region-Failover oder hyperskalierendes Datenwachstum lassen sich abbilden, wenn man von Anfang an die Architektur darauf vorbereitet (z.B. Design für Partitionierung oder Bereitschaft, Hyperscale zu aktivieren).
In der Praxis hat sich gezeigt, dass die meisten Workloads – von kleinen Web-Apps bis hin zu großen Enterprise-Systemen – auf Azure SQL zuverlässig betrieben werden können. Wichtig ist eine saubere Planung: Auswahl des passenden Service-Tiers, Beachten der kleinen Unterschiede zu on-prem (z.B. was Agent-Jobs angeht) und Implementieren von Cloud-gerechten Mustern (etwa Retries bei Verbindungsabbrüchen). Anti-Pattern wie long-running Transactions oder monolithische SPs mit externen Calls sollten vermieden werden, insbesondere in einer Umgebung, wo man eher mit verteilten Services arbeitet.
Zusammenfassend liefert Azure SQL für Entwickler den besten Mix aus Bekanntem und Innovativem: Man nutzt die bewährte SQL-Server-Technologie mit all ihren Funktionen und dem SQL-Sprachumfang, profitiert aber zusätzlich von automatischen Leistungsverbesserungen, einfacher Skalierung und modernen Sicherheitsintegrationen. Unsere Empfehlung: Für neue cloud-native Anwendungen greifen Sie zu Azure SQL Database, nutzen Sie Single Databases oder Elastic Pools für Mandanten und skalieren Sie bei Bedarf mit Serverless oder Hyperscale. Für bestehende Anwendungen, die Sie ohne große Refactoring in die Cloud bringen wollen, ist Azure SQL Managed Instance oft der richtige Weg – hier behält man fast alle on-premises Features und senkt trotzdem den Administrationsaufwand erheblich. In beiden Fällen gilt: Beobachten Sie die Ressourcenauslastung, implementieren Sie Best Practices für Schema und Code, und Azure SQL wird Ihnen eine stabile, performante Datenbasis für Ihre Applikationen bieten – heute und auch in Zukunft, während Microsoft die Plattform kontinuierlich weiterentwickelt.
Weitere Beiträge zum Thema SQL Server
Azure SQL für IT-Entscheider
1. Management Summary Azure SQL bezeichnet eine Familie von Microsofts Cloud-Datenbankdiensten, die SQL Server-Technologie in Azure als Service bereitstellen. Dazu gehören Azure SQL Database (ein einzeldatenbankbasierter PaaS-Dienst für moderne Anwendungen), Azure SQL...
NUMA – Grundlagen und Anwendung in SQL Server 2022
Grundlagen von NUMA (Non-Uniform Memory Access) Was ist NUMA? NUMA (Nicht-uniformer Speicherzugriff) ist eine Architektur für Mehrprozessorsysteme, bei der jeder Prozessor über einen eigenen lokalen Arbeitsspeicher verfügt. Alle Prozessoren teilen sich zwar...
NUMA, MAXDOP und Co.: Die größten Fehler und Mythen bei der SQL-Server-Konfiguration
Einleitung In der Datenbankadministration von Microsoft SQL Server gibt es eine Reihe von Konfigurationsthemen – insbesondere rund um NUMA (Non-Uniform Memory Access), MAXDOP (Max Degree of Parallelism) und verwandte Einstellungen – bei denen immer wieder typische...
Tutorial: SQL Server-Indizes für Entwickler
Einführung: Dieser Fachartikel richtet sich an Entwickler mit Grundkenntnissen in Microsoft SQL Server und bietet eine umfassende Einführung in das Thema Indizes. Wir beleuchten, was Indizes sind und warum sie für die Performance einer Datenbank entscheidend sind....
Microsoft SQL Server unter Linux – Strategische Analyse und Praxisleitfaden
1. Management Summary Microsofts Entscheidung, SQL Server auch unter Linux anzubieten, markiert einen strategischen Wandel mit weitreichenden Auswirkungen für IT-Entscheider. Erstmals steht damit eine der führenden relationalen Datenbankplattformen...
Blockgröße für SQL Server richtig auswählen (Windows und Linux)
Einleitung: Die Wahl der optimalen Blockgröße (auch Allocation Unit Size oder Dateisystem-Blockgröße genannt) für Datenträger ist ein wichtiger, oft unterschätzter Faktor beim Betrieb von Microsoft SQL Server unter Windows und Linux. Die Blockgröße eines Dateisystems...
Wartungspläne für Microsoft SQL Server
Management Summary Wartung sichert Verfügbarkeit und Datenintegrität: Geplante Wartungsarbeiten in SQL Server zielen darauf ab, die Verfügbarkeit von Datenbanken hoch zu halten und Datenintegrität zu gewährleisten. Sie minimieren Ausfallzeiten und Risiken und...
Virtualisierung von SQL Server, Best Practices
Management Summary Virtualisierung von Microsoft SQL Server ermöglicht es Unternehmen, Datenbank-Workloads effizienter bereitzustellen und zu verwalten. Durch Konsolidierung mehrerer SQL-Server-Instanzen auf weniger Hardware steigern Organisationen die Auslastung und...
SQL Performance-Analyse (hypothetisches Beispiel)
Management Summary Die Performance-Analyse einer Microsoft SQL-Server-Instanz (Version 2019) hat CPU- und I/O-Engpässe als Hauptprobleme identifiziert. In Spitzenzeiten lag die CPU-Auslastung dauerhaft über 90 %, und die Speicher-I/O-Latenz der Datenbanken überschritt...
Indexoptimierung bei SQL Server – Leitfaden für IT-Verantwortliche und DBAs
Einleitung: Wozu dienen Indizes im SQL Server? Indizes sind essenziell, um SQL Server Abfragen zu beschleunigen und die Datenbank-Performance zu verbessern. Ein Index funktioniert ähnlich wie das Inhaltsverzeichnis eines Buches: Anstatt eine Tabelle vollständig zu...