Einzelne Tabelle mit zusätzlichen Spalten im Vergleich zu mehreren Tabellen, die das Schema duplizieren

13

Ich arbeite an einem Projekt, bei dem ich zu einem bestimmten Zeitpunkt entscheiden musste, ob in der Datenbank eine einzelne Tabelle mit mehreren Spalten, die nicht von jedem Datensatz verwendet werden, oder mehrere Tabellen mit doppeltem Schema vorhanden sein sollen.

Ich erstelle eine Sportinformationsanwendung, die mehrere Sportarten verarbeiten kann. Wir können zum Beispiel mit NBA, NHL, MLB, NFL umgehen. Jede Sportart hat sehr ähnliche Konzepte - Teams, Zeitpläne, Verletzungen, Spielerinformationen ..

Unsere Datenquelle gibt uns natürlich nicht alle Daten im selben Schema. Jede Sportart hat ein anderes Schema, nach dem wir Daten von unserem Anbieter erhalten.

Da nicht genügend Zeit (Kundenanforderungen) vorhanden war, um die Datenfeeds im Voraus zu analysieren, um Gemeinsamkeiten zu bestimmen, habe ich meine Wette abgesichert und die "sichere Wette" abgeschlossen und für jede Sportart einzelne separate Tabellen erstellt, anstatt nur eine Reihe von Tabellen Sportarten verwendet.

Das Ergebnis ist ein dupliziertes Schema in mehreren Tabellen und damit auch duplizierte Schnittstellen zur Datenbank (z. B. gespeicherte Prozesse). Ich habe so etwas wie NBA_Game, NFL_Game, NBA_Team, NFL_Team usw. Jede Tabelle hat möglicherweise einige Eigenschaften, die die andere nicht hat, und mehrere, die gemeinsam genutzt werden. Es geht beispielsweise um 5-10 Tische in 4 oder 5 Sportarten. Ich bin mir immer noch nicht sicher, ob dies eine ganz schlechte Sache ist - die Alternative, einen einzigen Satz von Tabellen mit Eigenschaften zu haben, die nicht alle Sportarten verwenden würden, könnte auch für sich alleine unhandlich gewesen sein.

Hat jemand, der dies getan hat, auf solche Fallstricke gestoßen und konnte seine Erfahrungen hier teilen? Dinge, die mir helfen könnten, jetzt Bescheid zu wissen, anstatt auf die harte Tour zu lernen? Haben Sie es anders gemacht, mit einer großen Tabelle / einem großen Satz von Tabellen, mit Spalten, die nicht jeder Datensatz verwenden würde? Auf welche Fallstricke sind Sie dabei gestoßen?

Gibt es eine Alternative wie die Tabellenvererbung , die Sie in der Vergangenheit verwendet haben und die besser funktioniert hat?

Vielen Dank

Dferraro
quelle

Antworten:

12

Letztendlich kommt es auf Nutzung und Architektur an.

Die Architektur

Kann das System "jeden Sport" ausführen? Ist die Idee, dass Sie Ihren Architekturastronautenhut aufsetzen und ein generisches System bauen, das für alle zukünftigen Sportarten geeignet ist, die es heute möglicherweise noch nicht gibt?

Wenn dies der Fall ist, ist das Vorhandensein dynamisch benannter Tabellen offensichtlich ein großes Problem. Daher ist es sinnvoll, ein Schema zu verwenden, das bei Bedarf n Sportarten unterstützt.

Trotzdem bin ich sehr stark gegen diesen Ansatz: Das ist fast immer mehr Arbeit und führt zu schlechteren Ergebnissen. Das Erstellen einer separaten Benutzeroberfläche, eines separaten Schemas usw. für jede Sportart führt letztendlich zu einer besseren Benutzererfahrung und einer einfacheren Pflege des Codes, auch wenn dies nur oberflächliche Doppelungen zur Folge hat (wie dies vermieden / minimiert werden kann, ist eine separate Frage).

Wie gehen Sie mit Spielern um, die mehrere Sportarten ausüben? Erhalten sie zwei Einträge (z. B. behandeln Sie sie als unterschiedliche Personen) oder versuchen Sie, mit ihnen etwas Bestimmtes zu tun?

Verwenden

Nehmen wir also an, Sie treiben keinen dynamischen Sport (wenn beispielsweise jemand eine neue Sportart hinzufügen möchte, ist Entwicklungsaufwand erforderlich, um sie hinzuzufügen).

Gibt es jemals eine Zeit, in der Sie Spieler (oder andere von Ihnen erwähnte Objekte) aus mehr als einer Sportart gleichzeitig anzeigen?

Ich könnte dies für eine Suchfunktion sehen, bei der Sie nach Spieler- oder Teamnamen suchen können (unabhängig von der Sportart), aber darüber hinaus kann ich mir viele Anwendungsfälle nicht vorstellen.

Wenn Sie dies niemals tun müssen, ist Ihr Ansatz vollkommen in Ordnung. Sie können hier aufhören zu lesen.

Alternative Schemata

Ansichten

Ich bin ein Fan von KISS. In mehr als 15 Jahren Softwareentwicklung greife ich weiterhin auf die Philosophie zurück, "das einfachste zu bauen, was funktioniert".

Meine anfängliche Reaktion auf die Annahme, dass eine sportübergreifende Suchfunktion der einzige Anwendungsfall ist, besteht darin, Ansichten zu erstellen:

SELECT PlayerName, 'NFL' as [Sport], TeamName FROM NFL_Players JOIN NFL_Teams ... 
UNION  
SELECT PlayerName, 'NHL' as [Sport], TeamName FROM NHL_Players JOIN NHL_Teams ... 
UNION ....

Wenn Sie eine neue Sportart hinzufügen, müssen Sie diese natürlich der Ansicht hinzufügen. Es kann auch nützlich sein, andere gebräuchliche Informationen einzuschließen, aber das hängt wirklich davon ab, was gezeigt werden muss.

Ich würde versuchen, alle sportspezifischen Inhalte in der Ansichtsdefinition zu belassen, sodass der Suchcode nicht viel oder einen bestimmten Code enthalten muss (abgesehen davon, dass Sie möglicherweise wissen, wie Sie auf /nhl/players/player-namevs verlinken sollen, /nfl/...oder wie Ihre App dies tut).

Tabellenvererbung

Tabellenvererbung kann funktionieren, ist aber ziemlich komplex. Ich habe nicht viel Erfahrung damit, und in der Tat denke ich, dass wir jedes Mal, wenn ich daran beteiligt war, etwas Einfacheres gemacht haben (wie ich hier vorschlage).

Ich persönlich muss noch herausfinden, warum dies nützlich ist, aber vielleicht gibt es einen überzeugenden Anwendungsfall (den ich nicht kenne), der die Komplexität rechtfertigt (z. B. löst die Tabellenvererbung den Anwendungsfall besser als jede andere Lösung). .

Separate Tabellen für sportspezifische Attribute

Sie könnten eine einzelne playersTabelle nhl_players_detailserstellen, deren Attribute allen Spielern aller Sportarten gemeinsam sind, und dann eine andere Gruppe von Tabellen , die eine Spieler-ID und Spalten mit zusätzlichen Informationen zum Spieler enthält. Wenn es eine Menge gemeinsamer Attribute gibt oder Sie "alle Spieler aus allen Sportarten" vielfach einsetzen können, ist dies möglicherweise sinnvoll.

Schlüsselwertpaare für sportspezifische Attribute

Völlig alternativer Ansatz: eine hat playersTabelle (wieder mit gemeinsamen Attributen wie Name) und dann eine , player_datadie Tabelle hat PlayerId, Sport, Attribute, Value. Die eingegebenen Attributnamen wären sportspezifisch. Auf diese Weise können Sie im Wesentlichen neue Attribute hinzufügen, ohne das Schema zu ändern (Ihr Code müsste immer noch wissen, um sie zu laden / anzuzeigen). Der Nachteil ist, dass Sie etwas an Integrität verlieren: Der Wert ist normalerweise ein Zeichenfolgenfeld, sodass der Anwendungscode stabil sein und potenzielle Fehler bei der Konvertierung der Zeichenfolge valuein einen bestimmten Datentyp (z. B. eine Ganzzahl) behandeln muss.

Dieses Konzept kann natürlich für Teams, Spiele usw. gelten.

gregmac
quelle
Auf der Suche nach einer Lösung für ein Legacy-Projekt gibt es mehrere authentifizierbare Typen und Tabellen. Die Erwähnung von Ansichten, die ich vergessen hatte, hat mir wirklich geholfen, eine andere mögliche Lösung für meine Forschung anzubieten. Vielen Dank.
FullStackFool
5

Sie sprechen von der Normalisierung der Datenbank . Möglicherweise sind Sie erleichtert, wenn Sie feststellen, dass es kein perfektes Datenmodell gibt und dass eine stärkere Normalisierung nicht immer besser ist. Durch die Normalisierung können Kosten in Bezug auf die Klarheit des Datenmodells und die Datenbankleistung entstehen. Aus diesem Grund hängt die Auswahl des besten Modells von Ihren Verwendungsanforderungen ab.

Auf den ersten Blick scheinen Ihre Beispiele im Konzept ähnlich genug zu sein (X_Game vs Y_Game und X_Team vs Y_Team), dass der zusätzliche Aufwand einiger Spalten nicht unangemessen erscheint. Das heißt, wenn jede Sportart mehrere Dutzend zusätzliche Spalten in die Tabelle aufnehmen würde, wäre dies in der Tat unhandlich.

In diesem Fall möchten Sie möglicherweise ein Hybridmodell in Betracht ziehen, bei dem die gemeinsamen Daten in einer zentralen Tabelle, die sportspezifischen Daten jedoch in einer verknüpften Datenstruktur gespeichert sind. Etwas wie:

table Game {
    gameId int,
    teamId1 int fk,
    teamId2 int fk
}

table HockeyGame {
    gameId int fk,
    penaltyMinutes int
}

table BasketballGame {
    gameId int fk,
    freeThrows int
}
Midnotion
quelle
Dies ist, was ich vorschlagen wollte, plus vielleicht eine Spalte in der Spieltabelle, die den Spieltyp angibt. Mir ist klar, dass man daraus schließen kann, wenn man an den anderen Tischen mitspielt, aber wenn die Anzahl der Spieltypen steigt, wird das langsam langweilig.
Rory Hunter
Auf jeden Fall - dies ist nur ein Skelettmodell zur Veranschaulichung der Kernbeziehungen und einiger Beispiele für möglicherweise häufige Daten im Vergleich zu sportspezifischen Daten.
Midnotion