Perché scegliere una tabella specializzata

In SQL Server e Azure SQL una tabella “normale” (rowstore) risolve la maggior parte dei casi, ma l’esame DP-800 verifica se sai riconoscere lo scenario in cui una tabella specializzata è la scelta corretta, e soprattutto se ne conosci i limiti. Il ragionamento è sempre lo stesso: partire dal requisito funzionale (storicità, throughput, relazioni, prova di manomissione, dato esterno, volumi) e mappare su un solo tipo, evitando la soluzione “over-engineered”. Attenzione: molte di queste feature dipendono dal service tier o dalla piattaforma, quindi la disponibilità è essa stessa una discriminante.

Storicità e performance: temporal, in-memory OLTP, partitioning

Le temporal tables (system-versioned) mantengono in automatico la cronologia di ogni riga: una tabella corrente più una history table collegata, con due colonne di periodo. Sono la risposta quando serve audit trail delle modifiche, ricostruzione dello stato a una certa data (query FOR SYSTEM_TIME) o gestione di slowly changing dimensions senza logica applicativa. Limiti: la history cresce e va gestita con una retention policy; alcune operazioni DDL e il TRUNCATE sono vincolati mentre il versioning è attivo.

Le tabelle in-memory OLTP (memory-optimized) vivono in memoria e usano un concurrency control ottimistico multi-versione, senza lock né latch. Sono la scelta per throughput molto alto e bassa latenza con forte concorrenza: ingest rapido, staging/ETL, session state. Abbinate a natively compiled stored procedure spingono ancora di più. Limiti da ricordare: i dati devono stare in memoria, ci sono restrizioni T-SQL nelle procedure compilate nativamente e su Azure SQL Database la feature richiede i tier più alti (Business Critical / Premium). Usano SNAPSHOT come isolation di base.

La table partitioning divide orizzontalmente una tabella grande in partizioni su una colonna chiave (partition function + partition scheme). Il valore principale è la manageability: caricamento e archiviazione quasi istantanei con SWITCH (sliding window), manutenzione mirata degli indici allineati e partition elimination in query filtrate. Non è di per sé un acceleratore generico: se lo scenario chiede “velocizzare tutte le query”, il partitioning non è la risposta automatica.

Relazioni, fiducia e dati esterni: graph, ledger, external

Le graph tables modellano esplicitamente reti tramite node table ed edge table, interrogabili con la clausola MATCH. Convengono per relazioni many-to-many complesse, gerarchie profonde, grafi sociali, motori di raccomandazione, fraud detection e bill of materials, dove le self-join ripetute diventerebbero illeggibili. Restano comunque tabelle relazionali: per dati fortemente tabellari o join semplici, una modellazione classica è preferibile.

Le ledger tables offrono tamper-evidence crittografica: ogni modifica è concatenata in hash verificabili, così puoi provare che i dati non sono stati alterati, senza gestire una blockchain distribuita. Esistono in due forme: updatable ledger table (aggiornabile, con storico protetto) e append-only ledger table (solo insert). Il caso d’uso è la compliance e l’audit ad alta fiducia; il limite tipico è che l’append-only non consente update né delete.

Le external table implementano data virtualization: interroghi dati che risiedono altrove (file in storage, altre origini) senza ingerirli fisicamente, utile per federazione e query on-demand su dati esterni. Limite decisivo per l’esame: le external table non sono supportate da SQL database in Fabric — in quel contesto la virtualizzazione dei dati esterni va ottenuta con altri strumenti della piattaforma, non con external table.

Trappole tipiche d’esame

  • Serve la cronologia completa delle modifiche di riga → soluzione: temporal table system-versioned, non trigger custom né una history table gestita a mano; l’esame propone spesso la soluzione manuale come distrattore.
  • Massimo throughput e concorrenza con dati che stanno in memoria → soluzione: in-memory OLTP, ma verifica il service tier: su Azure SQL Database richiede Business Critical/Premium, quindi in tier Standard la risposta corretta cambia.
  • Prova che i dati non sono stati manomessi senza blockchain esterna → soluzione: ledger table; ricorda che l’append-only ledger non permette update/delete, quindi non usarla dove servono aggiornamenti.
  • Caricare o archiviare enormi volumi quasi istantaneamente → soluzione: partitioning con SWITCH (sliding window); non confonderlo con “rendere più veloci tutte le query”, che non è il suo scopo primario.
  • Interrogare dati esterni da SQL database in Fabric → soluzione: NON le external table (non supportate lì); usa gli strumenti di virtualizzazione della piattaforma Fabric.
  • “Isolation level READ_COMMITTED_SNAPSHOT a livello di sessione” → soluzione: è un tranello: RCSI è un’opzione di database, non un isolation level impostabile per sessione; a livello di sessione esiste invece SNAPSHOT.