Es gibt zwei Tabellen: Deal
und DealCategories
. Ein Geschäft kann viele Geschäftskategorien haben.
Daher sollte der richtige Weg darin bestehen, eine Tabelle DealCategories
mit der folgenden Struktur aufzurufen:
DealCategoryId (PK)
DealId (FK)
DealCategoryId (FK)
Unser Outsourcing-Team hat die verschiedenen Kategorien jedoch folgendermaßen in der Deal
Tabelle gespeichert :
DealId (PK)
DealCategory -- In here they store multiple deal ids separated by commas like this: 18,25,32.
Ich habe das Gefühl, dass das, was sie getan haben, falsch ist, aber ich weiß nicht genau, warum dies nicht richtig ist.
Wie soll ich ihnen erklären, dass das falsch ist? Oder vielleicht bin ich derjenige, der sich irrt und das ist akzeptabel?
database-design
foreign-key
Sarawut Positwinyu
quelle
quelle
Antworten:
Ja, das ist eine schreckliche Idee.
Anstatt zu gehen:
Du musst jetzt gehen:
Dann müssen Sie Ihren Anwendungscode bearbeiten, um diese Kommaliste in einzelne Zahlen aufzuteilen, und dann die Datenbank separat abfragen:
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:
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.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.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.
quelle
Das ist eigentlich ein gutes Design, wenn Sie nur die Kategorien für ein bestimmtes Geschäft abfragen müssen.
Aber es ist schrecklich, wenn Sie alle Angebote in einer bestimmten Kategorie wissen wollen.
Außerdem ist es sehr schwierig und fehleranfällig, etwas anderes zu tun - wie Aktualisierungen, Zählungen, Verknüpfungen usw.
Denormalisierung hat ihren Platz, aber Sie müssen bedenken, dass sie für eine Art von Abfrage auf Kosten aller anderen optimiert wird, die Sie möglicherweise für dieselben Daten durchführen. Wenn Sie wissen, dass Sie immer in einem Muster abfragen, bietet es möglicherweise einen Vorteil, das denormalisierte Design zu verwenden. Wenn Sie bei den Abfragetypen jedoch mehr Flexibilität benötigen, sollten Sie sich an ein normalisiertes Design halten.
Wie bei jeder anderen Form der Optimierung müssen Sie wissen, welche Abfragen Sie ausführen werden, bevor Sie entscheiden können, ob die Denormalisierung gerechtfertigt ist.
quelle
select * from DealCategories where DealId in (1,2,3,4,...)
. Sie haben mehr Erfahrung mit Datenbankdesign als ich. Vielleicht haben Sie in einigen Fällen gute Gründe für solch ein "extremes Tuning" in ganz bestimmten Fällen. Meine einzige Idee, dies zu rechtfertigen, ist eine sehr hoheselect
Belastung von Deal / DealCategory. Für mich ähnelt dies einem Outsourcing-Team, das ohne DB-Design-Kenntnisse Tabellen erstellt hat.Mehrere Werte in einer Spalte entsprechen der 1. Normalform.
Es ist auch absolut kein Geschwindigkeitsgewinn, da die Tabellen in der Datenbank verlinkt werden sollen. Sie müssen zuerst eine Zeichenfolge lesen und analysieren und dann alle Kategorien für den "Deal" auswählen.
Die korrekte Implementierung wäre eine Junction-Tabelle wie "DealDealCategories" mit DealId und DealCategoryId.
Schlechte Hierarchieimplementierung?
Außerdem sieht eine FK in DealCategories zu einer anderen DealCategory wie eine schlechte Implementierung einer Hierarchie / eines Baums von DealCategories aus. Die Arbeit mit Bäumen über eine Eltern-ID-Beziehung (so genannte Adjazenzliste) ist ein Schmerz!
Achten Sie beim Implementieren von Hierarchien auf verschachtelte Sets (gut zu lesen, aber schwer zu ändern) und Closure Tables (beste Gesamtleistung, aber möglicherweise hohe Speichernutzung - wahrscheinlich nicht zu viel für Ihre DealCategories)!
quelle