Ja, das ist eine schreckliche Idee.
Anstatt zu gehen:
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
Du musst jetzt gehen:
SELECT Deal.ID, Deal.Name, DealCategories
FROM Deal
WHERE Deal.DealID = 1234
Dann müssen Sie Ihren Anwendungscode bearbeiten, um diese Kommaliste in einzelne Zahlen aufzuteilen, und dann die Datenbank separat abfragen:
SELECT DealCategory.Name
FROM DealCategory
WHERE DealCategory.DealCategoryID IN (<<that list from before>>)
Dieses Design-Antimuster beruht entweder auf einem völligen Missverständnis der relationalen Modellierung (Sie müssen keine Angst vor Tabellen haben. Tabellen sind Ihre Freunde. Verwenden Sie sie) oder auf einer bizarren falschen Überzeugung, dass es schneller ist, eine durch Kommas getrennte Liste zu erstellen und zu teilen im Anwendungscode als es ist, eine Verknüpfungstabelle hinzuzufügen (es ist nie ). Die dritte Möglichkeit ist, dass sie nicht sicher / kompetent genug mit SQL sind, um Fremdschlüssel einrichten zu können. In diesem Fall sollten sie jedoch nichts mit dem Entwurf eines relationalen Modells zu tun haben.
SQL Antipatterns (Karwin, 2010) widmet diesem Antipattern (das er "Jaywalking" nennt) auf den Seiten 15-23 ein ganzes Kapitel. Auch der Autor hat über eine ähnliche Frage bei SO gepostet . Wichtige Punkte, die er notiert (wie auf dieses Beispiel angewendet), sind:
- Das Abfragen aller Deals in einer bestimmten Kategorie ist ziemlich kompliziert (der einfachste Weg, dieses Problem zu lösen, ist ein regulärer Ausdruck, aber ein regulärer Ausdruck ist ein Problem an sich).
- Ohne Fremdschlüsselbeziehungen können Sie keine referenzielle Integrität erzwingen. Wenn Sie DealCategory nr löschen. # 26 müssen Sie dann in Ihrem Anwendungscode jedes Geschäft nach Verweisen auf Kategorie # 26 durchsuchen und diese löschen. Dies ist etwas, das auf der Datenebene gehandhabt werden sollte, und es ist eine sehr schlechte Sache, in Ihrer Anwendung damit umgehen zu müssen .
- Aggregatabfragen (
COUNT
, SUM
usw.) wieder variieren von ‚kompliziert‘ zu ‚fast unmöglich‘. Fragen Sie Ihre Entwickler, wie Sie eine Liste aller Kategorien mit der Anzahl der Deals in dieser Kategorie erhalten. Bei korrektem Design sind das vier Zeilen SQL.
- Aktualisierungen werden viel schwieriger (dh Sie haben einen Deal in fünf Kategorien, möchten jedoch zwei entfernen und drei weitere hinzufügen). Das sind drei Zeilen SQL mit einem richtigen Design.
- Irgendwann stoßen Sie auf
VARCHAR
Längenbeschränkungen für Listen. Wenn Sie eine durch Kommas getrennte Liste mit mehr als 4000 Zeichen haben, analysieren Sie wahrscheinlich, dass das Monster sowieso langsam ist.
- Das Abrufen einer Liste aus der Datenbank, das Aufteilen der Liste und das anschließende Zurückkehren zur Datenbank für eine andere Abfrage ist wesentlich langsamer als eine Abfrage.
TLDR: Es handelt sich um ein grundlegend fehlerhaftes Design, das sich nicht gut skalieren lässt, selbst bei einfachsten Abfragen zusätzliche Komplexität bietet und Ihre Anwendung sofort verlangsamt.