Zuallererst besteht die Existenzberechtigung einer relationalen Datenbank darin, Beziehungen zwischen Entitäten modellieren zu können. Verknüpfungen sind einfach die Mechanismen, mit denen wir diese Beziehungen durchlaufen. Sie sind sicherlich mit nominalen Kosten verbunden, aber ohne Joins gibt es wirklich keinen Grund, eine relationale Datenbank zu haben.
In der akademischen Welt lernen wir Dinge wie die verschiedenen normalen Formen (1., 2., 3., Boyce-Codd usw.) und wir lernen verschiedene Arten von Schlüsseln (primär, fremd, alternativ, einzigartig usw.) und wie Diese Dinge passen zusammen, um eine Datenbank zu entwerfen. Und wir lernen die Grundlagen von SQL sowie die Manipulation von Struktur und Daten (DDL & DML).
In der Unternehmenswelt erweisen sich viele der akademischen Konstrukte als wesentlich weniger lebensfähig, als wir angenommen hatten. Ein perfektes Beispiel ist der Begriff eines Primärschlüssels. Akademisch gesehen ist es dieses Attribut (oder diese Sammlung von Attributen), das eine Zeile in der Tabelle eindeutig identifiziert. In vielen Problembereichen besteht der richtige akademische Primärschlüssel aus 3 oder 4 Attributen. Fast jeder in der modernen Unternehmenswelt verwendet jedoch eine automatisch generierte, sequentielle Ganzzahl als Primärschlüssel einer Tabelle. Warum? Zwei Gründe. Das erste ist, weil es das Modell viel sauberer macht, wenn Sie FKs überall migrieren. Die zweite und wichtigste Frage zu dieser Frage ist, dass das Abrufen von Daten über Joins mit einer einzelnen Ganzzahl schneller und effizienter ist als mit 4 Varchar-Spalten (wie bereits von einigen Leuten erwähnt).
Lassen Sie uns nun etwas tiefer in zwei spezifische Subtypen realer Datenbanken eintauchen. Der erste Typ ist eine Transaktionsdatenbank. Dies ist die Grundlage für viele E-Commerce- oder Content-Management-Anwendungen, die moderne Websites antreiben. Mit einer Transaktions-DB optimieren Sie stark in Richtung "Transaktionsdurchsatz". Die meisten Commerce- oder Content-Apps müssen die Abfrageleistung (von bestimmten Tabellen) mit der Einfügeleistung (in anderen Tabellen) in Einklang bringen, obwohl jede App ihre eigenen geschäftlichen Probleme hat, die gelöst werden müssen.
Der zweite Typ einer realen Datenbank ist eine Berichtsdatenbank. Diese werden fast ausschließlich zur Aggregation von Geschäftsdaten und zur Erstellung aussagekräftiger Geschäftsberichte verwendet. Sie sind in der Regel anders geformt als die Transaktionsdatenbanken, in denen die Daten generiert werden, und sie sind in hohem Maße für die Geschwindigkeit des Ladens von Massendaten (ETLs) und die Abfrageleistung bei großen oder komplexen Datenmengen optimiert.
In jedem Fall muss der Entwickler oder DBA sowohl die Funktions- als auch die Leistungskurven sorgfältig abwägen, und auf beiden Seiten der Gleichung gibt es viele Tricks zur Leistungssteigerung. In Oracle können Sie einen sogenannten "Erklärungsplan" ausführen, um genau zu sehen, wie eine Abfrage analysiert und ausgeführt wird. Sie möchten die ordnungsgemäße Verwendung von Indizes durch die DB maximieren. Ein wirklich unangenehmes Nein-Nein ist das Einfügen einer Funktion in die where-Klausel einer Abfrage. Wenn Sie dies tun, stellen Sie sicher, dass Oracle keine Indizes für diese bestimmte Spalte verwendet und dass im EXPLAIN-Plan wahrscheinlich ein vollständiger oder teilweiser Tabellenscan angezeigt wird. Dies ist nur ein konkretes Beispiel dafür, wie eine Abfrage geschrieben werden kann, die langsam ist und nichts mit Joins zu tun hat.
Und während es sich um Tabellenscans handelt, wirken sie sich offensichtlich proportional zur Größe der Tabelle auf die Abfragegeschwindigkeit aus. Ein vollständiger Tabellenscan von 100 Zeilen ist nicht einmal erkennbar. Führen Sie dieselbe Abfrage für eine Tabelle mit 100 Millionen Zeilen aus, und Sie müssen nächste Woche zur Rückgabe zurückkehren.
Lassen Sie uns eine Minute über Normalisierung sprechen. Dies ist ein weiteres weitgehend positives akademisches Thema, das überstrapaziert werden kann. Wenn wir über Normalisierung sprechen, meinen wir meistens die Beseitigung doppelter Daten, indem wir sie in eine eigene Tabelle einfügen und eine FK migrieren. Die Leute überspringen normalerweise die gesamte Abhängigkeitssache, die von 2NF und 3NF beschrieben wird. Und doch ist es im Extremfall durchaus möglich, eine perfekte BCNF-Datenbank zu haben, die riesig ist und gegen die man Code schreiben kann, weil sie so normalisiert ist.
Wo balancieren wir also? Es gibt keine einzige beste Antwort. Alle besseren Antworten sind in der Regel Kompromisse zwischen der einfachen Strukturpflege, der einfachen Datenpflege und der einfachen Codeerstellung / -pflege. Im Allgemeinen ist es umso besser, je weniger Daten doppelt vorhanden sind.
Warum sind Joins manchmal langsam? Manchmal ist es schlechtes relationales Design. Manchmal ist die Indizierung ineffektiv. Manchmal ist es ein Problem mit dem Datenvolumen. Manchmal ist es eine schrecklich geschriebene Anfrage.
Es tut mir leid für diese langwierige Antwort, aber ich fühlte mich gezwungen, einen fleischigeren Kontext für meine Kommentare bereitzustellen, anstatt nur eine 4-Punkte-Antwort abzurasseln.