Questo Venerdi' ho avuto una piacevole discussione con uno sviluppatore; la voglio condividere con voi.
Con l' avvento degli ORM e dello sviluppo Domain Driven stiamo lasciando da parte una delle componenti piu' importanti del software. Il contenitore dei dati, il Database.
Vedo sempre piu' Database modellati in maniera errata, solo perche' molti compiti adesso vengono associati al codice. Ma ci stiamo dimenticando perche' usiamo un database e non un semplice file di testo per memorizzare i dati. Vi elenco alcune regole che dovrebbero essere un MUST nella modellazione di un buon database e che spesso vengono prese sottogamba solo perche' l' ORM ci facilita il compito.
- La chiave primaria e l' indice cluster sono la stessa cosa? No la chiave primaria è un vincolo che da univocità nella tabella - un indice clustered è un struttura ad albero che ordina i dati della tabella nelle pagine di dati. Fare una query con un 100% nel full index scan significa che la query e idem la tabella, non stanno sfruttando gli indici. NHibernate le SELECT le fa in questo modo se non usate una query ad HOC e se lasciate che le primary key e l' index clustered siano la stessa cosa. Consiglio questo articolo di Davide Mauri a riguardo.
- Creare un ID univoco di una riga tramite un GUID. Cosa stiamo facendo assegnamo al Database una colonna univoca che occupa la bellezza di 16 bit ed e' una string al posto di un autoincrement int che ne occuperebbe solamente 4!! Perche'? Quale sarebbe lo scopo di una tale progettazione? Sempre Davide qui spiega perche' non va usato il GUID come unique identifier.
- Le foreign key possono tranquillamente essere gestite dall' ORM o dal Domain Model. Cosa? Assolutamente no. L' integrita' e' un compito del Database e non del programmatore. In questo articolo trovate una valida spiegazione degli errori che potremmo avere se non implementiamo delle foreign key.
- Fare le select tramite l' ORM e non usare delle Stored Procedure. Questo mi sembra solo una non-voglia di scrivere codice T-SQL. In SQL 2005 le stored procedure ed il loro execution plan vengono cachati nel database, questo significa che se a priori progetto una Stored Procedure che ottimizza il piano di esecuzione e sfrutta gli indici presenti, sicuramente il carico di lavoro nel DBMS sara' minore. Se lanciate una select prodotta da Nhb in SQL, l' 80% sono dei Full Scan, quindi sono delle SELECT che NON sfruttano un bel niente.
E come queste cose molte altre, come il discorso della denormalizzazione prodotta dal Domain Driven, che sconsiglia l' utilizzo di un many-to-many.
Sono pentito di aver studiato fino ad oggi, codice, pattern e metodologie e adesso che sto approfondendo nel dettaglio la modellazione dei database, mi accorgo che forse il passo dovrebbe essere fatto al contrario. Prima impari bene a progettare, modellare e mantenere il database e poi ti preoccupi di come fare vedere i dati all' utente. Decisamente meglio.
La mia domanda e', in un grosso database di diversi Giga di dati devi preoccuparmi che il codice sia Domain Driven e ben leggibile o forse dovrei prima progettare un database come dio comanda? Io direi la seconda, ma sono sicuro che la maggior parte dei Programmatori DDD non la pensa come me.