Al dominio o non al dominio


15

Gli standard SQL92 e SQL99 definiscono i costrutti DDL . Non tutti i database lo supportano o hanno un nome diverso (ad esempio, SQL Server ha Tipi definiti dall'utente ).CREATE DOMAIN

Ciò consente di definire un tipo di dati vincolato da utilizzare nel proprio database, per semplificare e applicare le regole relative ai valori consentiti. Tale tipo di dati potrebbe essere utilizzato nelle dichiarazioni di colonna, negli input e output delle stored procedure e funzioni ecc.

Mi piacerebbe sapere:

  • Le persone usano effettivamente i domini nei loro progetti di database?
  • Se così, fino a che punto?
  • Quanto sono utili?
  • Quali insidie ​​hai riscontrato?

Sto cercando di valutare la fattibilità dell'utilizzo di questi nel futuro sviluppo del database.


1
Vorrei sapere anche questo ... Mi interessa sapere cosa hanno da dire le persone.
maple_shaft

Risposte:


2

Come di solito...

Dipende

Hai un'entità di dominio utilizzata in più di un luogo che il supporto nativo richiederebbe altrimenti un notevole sforzo e / o vincoli e comportamenti ridondanti ?

In tal caso, dominio di distanza. Altrimenti, non preoccuparti.

Ho trovato necessario creare un tipo definito dall'utente in SQL Server esattamente una volta, in base all'euristica di cui sopra. Non ricordo nemmeno più di cosa si trattasse, ma ha risparmiato più lavoro di quanto abbia causato.


5

Come utente di SQL Server e C #, non ho usato tipi definiti dall'utente nel database, dal momento che sono piuttosto più potente nel lato dell'applicazione. Evento dopo ORM come LINQ to SQL ed Entity Framework, il mio uso delle funzionalità del server si è molto ridotto.

Ad esempio, stavo usando l'integrazione CLR per caricare alcune funzioni di conversione DateTime in SQL Server per trasferire le date e gli orari gregoriani in altri formati, in base al potere di globalizzazione di .NET. Ma ora le cose sono diverse e non lo faccio più. Carico semplicemente i dati e faccio la trasformazione, direttamente nel mio livello di applicazione.

Quindi, dopo quasi 4 anni di programmazione e ispezione di tutti i team a cui riesco a pensare, non ho trovato alcun esempio di utilizzo dei tipi definiti dall'utente. Inoltre non l'ho visto in azione in molti blog .NET.

Sebbene ciò non significhi che le persone non usano il Dominio database , sicuramente significa che almeno l'utilizzo del Dominio database non è così comune.


"Non ho usato i tipi definiti dall'utente nel database, dal momento che sono piuttosto più potente nel lato dell'applicazione" : quindi usi i vincoli? Non capisco, in cosa differisce dal punto di vista dell'applicazione?
Arseni Mourzenko,

@MainMa, ad esempio, non creo una classe Student nel livello database. Creo semplicemente una tabella di studenti con tutti i tipi di dati primitivi, come numeri interi e stringhe, e quindi utilizzando ORM, associo qualsiasi record a un oggetto nell'applicazione.
Saeed Neamati,

Inteso. Hai ragione.
Arseni Mourzenko,

3

Esiste già una risposta dettagliata su Stack Overflow. Sono principalmente d'accordo con esso, ma non con l'esempio dato, cito:

"Ad esempio, definisco un" GenderType "(char (1), non nullable, tenendo" M "o" F ") che garantisce che siano ammessi solo i dati appropriati nel campo Gender."

Personalmente, mi sento più a mio agio nell'impostazione del char(1)tipo e nella definizione di un vincolo sulla colonna. Quando il vincolo viene violato, so esattamente dove cercare per trovare ciò che ho fatto di sbagliato. È anche più noto dei tipi definiti dall'utente, quindi il database che utilizza solo vincoli sarebbe più facile da capire per un principiante.

Certo, è solo un'opinione personale. Altre persone direbbero che un in ('M', 'F')vincolo non è auto-documentazione e potrebbe essere molto oscuro per un nuovo sviluppatore che scopre il database.

IMO, usa tipi definiti dall'utente per tipi più complicati e vincoli per qualcosa di base. Inoltre, quando non è possibile trovare facilmente un nome esplicito per un tipo, esiste la possibilità che un vincolo si adatti meglio.


E gli ermafroditi?
Wyatt Barnett,

O intersessuati? O persone?
Broam,

1

Non ho usato questa funzione da solo, ma suppongo che sia necessario assicurarsi che:

  1. Se il database viene utilizzato da un singolo sistema, potrebbe essere opportuno non utilizzare questa funzione e aggiungere la logica di controllo nel livello aziendale o equivalente. Ciò ti darà maggiore flessibilità nella validazione (diciamo nell'uso delle espressioni regolari) e ti permetterà di incapsulare tutta la logica di validazione in un unico posto. Se il database è condiviso da più sistemi, è possibile invece utilizzare i trigger adatti a questa attività.

  2. Non sono sicuro che UDT ti consenta di personalizzare i messaggi di errore restituiti al client quando si verifica un errore di convalida.

  3. Gli UDT sono molto utili se la stessa regola di validazione si applica a più colonne. A mio avviso, non vedo questo come un caso molto comune nelle applicazioni aziendali con un design di database normalizzato.

Potresti essere interessato a verificare "Qual è il punto dei tipi definiti dall'utente [SQL Server]?" articolo del blog.


1
+1 per il terzo punto. Scrivere lo stesso vincolo ripetutamente come me non è la cosa migliore da fare, soprattutto quando il vincolo può cambiare nel tempo, richiedendo di cambiarlo in più punti.
Arseni Mourzenko,

0

Quando dici "non tutti i database supportano questo", penso che un modo migliore per dirlo sia il seguente:

Tutti i principali database lo supportano, poiché supportano ampiamente trigger, funzioni e altre funzionalità avanzate.

Questo ci porta alla conclusione che questo fa parte di SQL avanzato e ha senso ad un certo punto.

Do people actually use domains in their database designs?

Meno possibile, a causa dell'ampia copertura richiesta (considerando operatori, indici, ecc.)

If so to what extent?

Ancora una volta, il più limitato possibile, se un tipo esistente combinato con una piccola logica definita aggiuntiva (es. Controlli ecc.) Può fare il trucco, perché andare così lontano?

How useful are they?

Un sacco. Consideriamo per un secondo un DBMS non così buono come MySQL, che ho scelto per questo esempio per un motivo: manca un buon supporto per il tipo inet (indirizzo IP).

Ora vuoi scrivere un'applicazione che si concentri principalmente su dati IP come intervalli e tutto il resto, e sei bloccato con il tipo predefinito e la sua funzionalità limitata, o scriverai funzioni e operatori aggiuntivi (come quelli supportati nativamente in postgreSQL per esempio) o scrivere query molto più complesse per ogni funzionalità di cui hai bisogno.

Questo è un caso in cui giustificherai facilmente il tempo impiegato per definire le tue funzioni (inet >> inet in PostgreSQL: range contenuto in range operator).

A quel punto, hai già giustificato l'estensione del supporto per il tipo di dati, c'è solo un altro passo per definire un nuovo tipo di dati.

Ora torniamo a PostgreSQL che ha un supporto di tipo davvero carino ma nessun int .. senza segno di cui hai bisogno, perché sei davvero preoccupato per l'archiviazione / le prestazioni (chissà ...), bene dovrai aggiungerlo così come il operatori - anche se questo ovviamente deriva principalmente dagli operatori int esistenti.

What pitfalls have you encountered?

Finora non ci ho pensato, non ho avuto un progetto che richiedesse e giustificasse il tempo necessario per questo.

I maggiori problemi che posso vedere che potrebbero essere reinventare la ruota, introducendo bug nel livello "sicuro" (db), supporto di tipo incompleto che realizzerai solo mesi dopo quando il CONCAT (cast * AS varchar) fallisce perché tu non ha definito un cast (newtype come varchar), ecc.

Ci sono risposte che parlano di "non comune" ecc. Sicuramente queste sono e dovrebbero essere non comuni (altrimenti significa che i dbms mancano di molti tipi importanti), ma d'altra parte, si dovrebbe ricordare che un (buono) db è compatibile ACID ( a differenza di un'applicazione) e che tutto ciò che riguarda la coerenza è meglio tenuto lì.

Esistono molti casi in cui la logica aziendale viene gestita nel livello software e può essere eseguita in SQL, dove è più sicura. Gli sviluppatori di app tendono a sentirsi più a loro agio nel livello dell'applicazione e spesso evitano soluzioni migliori implementate in SQL, questo non dovrebbe essere considerato una buona pratica.

Gli UDT possono essere una buona soluzione per l'ottimizzazione, un buon esempio è dato in un'altra risposta sul tipo m / f usando char (1). Se fosse stato un UDT potrebbe invece essere un valore booleano (a meno che non vogliamo offrire la terza e la quarta opzione). Ovviamente sappiamo tutti che questa non è davvero ottimizzazione a causa del sovraccarico della colonna, ma la possibilità è lì.


La funzione specifica (DOMAIN) non è supportata da tutti i database. Sì, utilizzando trigger, vincoli e funzioni è possibile emularlo , ma ciò non lo rende una funzionalità supportata.
Oded,

Tutti i principali database lo supportano, poiché supportano ampiamente trigger, funzioni e altre funzionalità avanzate. Alcuni davvero poco chiari / schifosi non lo fanno, e nessuno che li usa si preoccupa perché i loro limiti si estendono ben oltre i tipi specifici dell'utente;)
Morg.

0

Sulla carta, gli UDT sono un ottimo concetto. Ti consentono di normalizzare veramente il tuo DB (ad esempio quando hai due colonne che dipendono l'una dall'altra) e anche di incapsulare qualsiasi logica correlata al tuo nuovo tipo.

In pratica, il prezzo da pagare (oggi) è troppo alto. Ovviamente c'è il sovraccarico di sviluppo, ma a parte questo perdi il supporto da una varietà di strumenti ORM e di reporting e aumenti un po 'la complessità complessiva della soluzione. Non ci sono troppi sviluppatori là fuori che hanno familiarità con gli UDT e non ho mai visto UDT gestiti usati al di fuori degli esempi.

Uno dei migliori esempi di un tipo che è meglio fare come UDT (se non esistesse già) dovrebbe essere hierarchyid( collegamento MSDN ). Per rimanere efficiente, memorizza il suo valore in un formato binario (al contrario delle solite implementazioni personalizzate varchar), che sarebbe ingombrante da mantenere senza le funzioni del tipo. I circa 10 metodi che il tipo fornisce sono anche meglio forniti come parte del tipo, al contrario delle funzioni esterne. Vorrei prendere in considerazione l'utilizzo dell'UDT gestita su misura in casi come questo, in cui si può ottenere un vantaggio significativo fornendo un'implementazione efficiente e ordinata come tipo separato.


0

Una domanda / risposta più pratica. La tua azienda consente di usarlo?

La tua azienda lavora con diversi marchi DBSQL che gestiscono DDL diversi?

Ogni marchio di database può offrire buone funzionalità aggiuntive, come Tipi definiti dall'utente, ma, se la tua azienda utilizza diversi DB, potresti avere problemi con le funzionalità non standard.

Se la società è solo tua, oppure puoi decidere quali database e funzionalità utilizzerai, puoi utilizzare DDL

Ho lavorato con diversi progetti in cui un tipo definito dall'utente potrebbe essere utile, ma dovrei attenermi a funzionalità più standard, dal momento che abbiamo dovuto gestire diversi DB. (S).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.