Realizzo sia la programmazione orientata agli oggetti sia la progettazione di database (per lo più transazionali, ma alcuni OLAP) e, per le mie circostanze, ci sono molti temi ricorrenti (almeno con OLTP).
Praticare la normalizzazione 3nf mi aiuta a praticare alcune varianti del principio di responsabilità singola. Una tabella dovrebbe rappresentare un concetto nel tuo sistema - e i concetti dovrebbero riguardare l'un l'altro in modo tale che tentano di imitare la realtà; per esempio, se sto costruendo un sistema in cui un cliente può avere 0 o più attività, allora creo una tabella clienti e una tabella attività. La tabella delle attività ha una relazione di chiave esterna con la tabella Cliente. Quando creo procedure memorizzate, mi assicurerei di utilizzare un join esterno per unire Cliente e attività perché il requisito aziendale che un cliente può avere attività 0.
Guardo anche a opportunità di estensibilità usando le tabelle bridge (link). Ad esempio, se cercassi di rappresentare una regola aziendale in cui un libro potesse avere un numero illimitato (variabile) di autori, creerei una tabella di libri, una tabella di autori e una tabella di bridge / link che abbia riferimenti a chiavi esterne a entrambi Libro e autore.
Inoltre, uso le chiavi surrogate su tutte le tabelle (in genere colonne di identità auto-incrementanti, ma forse Guids - il compromesso con i guids nel codice è che occupano più spazio di memoria di un intero semplice) e evito di fare affidamento sul naturale chiavi per le mie ricerche (tranne con Bridge / Link Tables). Per impostazione predefinita, creo anche indici su colonne di chiavi esterne comuni e rivedo le stored procedure / query di sistema di volta in volta per ottimizzare le strategie di indicizzazione. Un'altra strategia di indicizzazione che utilizzo è cercare i luoghi nel mio codice in cui creo una raccolta basata su una colonna di ricerca e aggiungi indici appropriati per cercare le colonne.