Sì, è un'idea terribile.
Invece di andare:
SELECT Deal.Name, DealCategory.Name
FROM Deal
INNER JOIN
DealCategories ON Deal.DealID = DealCategories.DealID
INNER JOIN
DealCategory ON DealCategories.DealCategoryID = DealCategory.DealCategoryID
WHERE Deal.DealID = 1234
Ora devi andare:
SELECT Deal.ID, Deal.Name, DealCategories
FROM Deal
WHERE Deal.DealID = 1234
Quindi è necessario eseguire operazioni nel codice dell'applicazione per suddividere l'elenco di virgole in singoli numeri, quindi interrogare separatamente il database:
SELECT DealCategory.Name
FROM DealCategory
WHERE DealCategory.DealCategoryID IN (<<that list from before>>)
Questo design antipattern nasce da un completo fraintendimento della modellazione relazionale (non devi aver paura dei tavoli. I tavoli sono i tuoi amici. Usali), o una convinzione bizzarramente sbagliata è più veloce prendere un elenco separato da virgole e dividerlo nel codice dell'applicazione rispetto ad aggiungere una tabella dei collegamenti ( non lo è mai ). La terza opzione è che non sono abbastanza sicuri / competenti con SQL per essere in grado di impostare chiavi esterne, ma in tal caso non dovrebbero avere nulla a che fare con la progettazione di un modello relazionale.
SQL Antipatterns (Karwin, 2010) dedica un intero capitolo a questo antipattern (che lui chiama "Jaywalking"), pagine 15-23. Inoltre, l'autore ha pubblicato una domanda simile su SO . I punti chiave che nota (come applicato in questo esempio) sono:
- Interrogare per tutte le offerte in una categoria specifica è piuttosto complicato (il modo più semplice per risolvere quel problema è un'espressione regolare, ma un'espressione regolare è un problema in sé e per sé).
- Non è possibile applicare l'integrità referenziale senza relazioni di chiave esterna. Se elimini DealCategory nr. # 26, quindi, nel codice dell'applicazione, devi esaminare ogni affare alla ricerca di riferimenti alla categoria # 26 ed eliminarli. Questo è qualcosa che dovrebbe essere gestito a livello di dati e doverlo gestire nell'applicazione è una cosa molto brutta .
- Le query aggregate (
COUNT
, SUM
ecc.), Di nuovo, variano da "complicate" a "quasi impossibili". Chiedi ai tuoi sviluppatori come ti farebbero ottenere un elenco di tutte le categorie con un conteggio del numero di offerte in quella categoria. Con un design adeguato, sono quattro righe di SQL.
- Gli aggiornamenti diventano molto più difficili (vale a dire che hai un affare che è in cinque categorie, ma vuoi rimuoverne due e aggiungerne altre tre). Sono tre righe di SQL con un design adeguato.
- Alla fine ti imbatterai in
VARCHAR
limiti di lunghezza dell'elenco. Anche se se hai un elenco separato da virgole di oltre 4000 caratteri, è probabile che il mostro stia andando lento come l'inferno.
- Estrarre un elenco dal database, suddividerlo e quindi tornare al database per un'altra query è intrinsecamente più lento di una query.
TLDR: è un design fondamentalmente imperfetto, non si ridimensiona bene, introduce ulteriore complessità anche per le query più semplici e, immediatamente, rallenta l'applicazione.