Quando si utilizza un ORM, quali sono alcuni aspetti a cui prestare attenzione nella progettazione del database


19

Quali sono alcuni aspetti del design del database a cui prestare attenzione quando si sa che si accederà al database utilizzando un Wikipedia ORM (Object Relational Mapper) ? Vedi anche Entity Framework NHibernate o LLBLGenPro.

Ad esempio, noterò il limite del parametro 2100 sulla chiamata RPC di SqlServer. Questo è un problema quando si utilizza LLBLgen e si uniscono le tabelle quando sono state utilizzate le chiavi primarie composte, consultare l'articolo MSDN per le chiavi composte .


4
Senza offesa, ma "unire le tabelle con più di 1 chiave primaria" .. questo ridefinisce una delle regole di base di una tabella, un singolo PK per tabella. Cosa intendevi esattamente?
Marian,

In che modo questo raggiunge il limite del parametro 2100? Hai delle tabelle con così tante colonne? Inoltre, presumo tu significhi "Mappatura relazionale oggetto" e non "Modellizzazione ruolo-oggetto"
John Saunders,

Il limite di parametri 2100 è talvolta un problema se si passa un ampio elenco di valori a un 'IN' SQL (array LINQ.Contains (membro)). Tuttavia, ciò non ha davvero nulla nella progettazione del database; questo è più un problema di modello di query. La soluzione più semplice per gli ORM che "ne soffrono" è quella di inserire l'elenco in una tabella temporanea [permanente] e unirsi a quello e / o utilizzare una sottoquery che seleziona gli elementi da interrogare da dove provengono. (il passaggio di migliaia di elementi a un "IN" di SQL è comunque generalmente negativo, indipendentemente dal fatto che si stia utilizzando o meno un mappatore OR).
Kristofer,

@John, yes Mappatura relazionale oggetto
BozoJoe

4
@BozoJoe: una tabella può - per definizione - avere solo una chiave primaria. Non esiste un DBMS che ti consenta di definire più di una chiave primaria per una singola tabella.
a_horse_with_no_name il

Risposte:


17

Passare attraverso le tecniche standard di normalizzazione, principalmente alla terza forma normale. Alcuni ORM possono rilevare le relazioni definite a livello di database, quindi non sarà necessario manualmente.

Vorrei davvero andare dall'altra parte e chiedere cosa dovrei sapere sugli ORM. Assicurati di sapere: - Come posso profilare le query? - Come posso ignorare l'ORM e scrivere la mia query? - Posso usare invece i processi memorizzati?

Il database dovrebbe essere indipendente da ORM poiché, molto probabilmente, sopravviverà all'app.


+1: "Il database deve essere agnostico ORM". Attenersi agli standard per la progettazione di database e anche i buoni ORM saranno felici.
MicSim,

12
  1. Non consentire all'ORM di creare o aggiornare lo schema. Usa sempre l'SQL generato come modello, ma esaminalo prima di apportare la modifica (ho visto il nostro ORM creare indici ridondanti, utilizzare tipi di dati errati ... tutta quella roba cattiva)

  2. Sii consapevole di ciò che il tuo ORM non può fare. Django per un po 'non ha supportato il gruppo attraverso l'ORM, il che è stato un dolore (lo è ancora, i sistemi legacy sono divertenti!). Quindi essere consapevoli delle limitazioni dell'ORM è un must per il DBA anche se non sono quelli che scrivono il codice per l'ORM

  3. Periodicamente, prendi i tuoi log lenti, aggregali attraverso mysqlslowlog e guarda i primi 10 o giù di lì. Fondamentalmente ti mostrerà le query che hanno richiesto il tempo complessivo più complesso. Una query che ha richiesto solo 1 secondo in media ma è stata eseguita 50.000 volte nell'ultimo mese si sporgerebbe su quel rapporto aggregato come un pollice dolente;)

Non direi estremo come scaricare completamente l'ORM. Se i tuoi sviluppatori che utilizzano ORM non sono DBA, è probabile che scrivano SQL che è altrettanto cattivo o peggiore di ORM. Quindi alla fine cadrà sul DBA per vedere cosa succede.


1
E considera di inserire una logica molto complessa in un proc memorizzato. Gli ORM possono chiamare proc memorizzati e, per una logica molto complessa, è più facile ottimizzare le prestazioni di un proc.
HLGEM

7

Ci sono alcune cose che noto subito su un database legacy che differisce da un database creato da ORM come Sequel e ActiveRecord per Ruby.

  1. L'uso di una chiave primaria in tutte le tabelle chiamate 'id'. Sì, può essere ignorato, ma idè l'impostazione predefinita.
  2. L'uso di nomi plurali per le tabelle.
  3. L'uso di caratteri di sottolineatura ("snakecase") per separare le parole creando il nome descrittivo delle tabelle e dei campi.
  4. L'uso di _idaccodato a chiavi esterne: il layout è in genere simile referenced_table_id.

Ho scritto il mio SQL a mano per anni perché non mi fidavo di un ORM, ma negli ultimi due o tre ho iniziato a utilizzare i due ORM precedentemente menzionati e sono rimasto colpito dal modo in cui si integrano con i database esistenti, e quanto riescono a decifrare un database se vengono seguite le loro convenzioni, o mi prendo il tempo per dare loro i suggerimenti necessari per comprendere un DB legacy.

Non so se ci sono linee guida comuni per la progettazione di schemi per giocare bene con gli ORM, ma penso che trarremmo tutti dei benefici se avessimo degli standard. C'è sicuramente un momento e un posto per un ORM, specialmente se stai usando un buon linguaggio OO e hai un programma serrato.


1
Cordiali saluti: esistono strumenti per gestire le differenze nella convenzione di denominazione per molti mappatori OR. Ho un componente aggiuntivo per Visual Studio che si occupa di quello per Entity Framework e Linq-to-SQL con denominazione basata su regole; consultare huagati.com/dbmltools per maggiori dettagli al riguardo.
Kristofer,

1
Id è un antipattern SQL per la denominazione del campo ID e non deve essere utilizzato.
HLGEM

Ti interessa spiegare perché? Come gestiamo le relazioni tra le tabelle quando dobbiamo fare ricerche come una-a-molte e molte-a-una? Negli ORM che uso non usare l'ID è decisamente contrario al flusso.
Tin Man,

2

Dipende (:)) un po 'da quale mappatore OR stai usando, quindi dedica un po' di tempo alla ricerca di quali funzioni db il mappatore OR in questione supporta / non supporta.

Ad esempio, i mappatori OR di Microsoft non supportano tutti i tipi di dati incorporati di SQL Server, non supportano alcune delle funzionalità TSQL più recenti / avanzate (query ricorsive, suggerimenti per l'ottimizzazione, ecc.).

In teoria , un buon mappatore OR dovrebbe essere abbastanza flessibile da superare (e consentire di mappare) uno schema di database relazionale ben progettato a un buon modello a oggetti. In realtà, abbiamo ancora un po 'da fare prima che tutti i pezzi del puzzle siano a posto; sebbene molti mappatori OR supportino la mappatura avanzata, spesso viene a scapito di query complesse e problemi di prestazioni.

Per buone prestazioni di db (e per preservare la sanità mentale del dba :)) dovresti comunque seguire le migliori pratiche quando si tratta di progettare schemi di db; normalizzare prima e denormalizzare dove [/ se] necessario. Sul lato del codice, non esagerare con il modello a oggetti ; anche se il mapper OR supporta modelli di ereditarietà complessi ed entità che uniscono più tabelle, queste sono anche le aree in cui si rischia di incorrere in problemi con query eccessivamente complesse che colpiscono il database, ecc. Profilo, profilo, profilo e non solo prendere l'ORM query generate per scontate. Tieni presente che le query generate da OR mapper possono spesso essere modificate proprio come le normali query SQL e che due query funzionalmente equivalenti sul lato oggetto (ad esempio query linq) possono talvolta provocare query SQL molto diverse.

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.