Primary Key - Subkey Auflösungstabelle austauschbar gestalten

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
kaineanung
User
Beiträge: 145
Registriert: Sonntag 5. April 2015, 20:57

Hallo Leute,

ich mache mir gerade Gedanken meine Datenbank abzuändern um flexibel bleiben zu können.
Hintergrund ist folgender:
Ich habe eine Quelle an Daten die ich parse und in die Datenbank einfüge. Diese Quelle kommt mit eigenem 'primary keys' (PK) in entsprechenden Tabellen. Die möche ich so nicht nutzen und habe deshalb meine enstprechende Tabellen mit einer ID-Spalte als PK ausgestattet welche ich mit 'autoincrement' befüllen lasse und somit eigene PKs erhalte. Die fremden PKs habe ich als unique-Spalte (foreign_id) hinzugefügt auf welche ich mich beim 'inserten' beziehe damit die Intigrität gewahrt bleibt (ich also auch die Kontrolle habe keine doppelten Datensätze zu erhalten).

Jetzt ist mir ein Gedanke gekommen: was wenn ich in Zukunft die Quelle wechseln will oder muss? Dann kommen die Daten mit anderen 'fremden' PKs und dann wird es schwer bis unmöglich für mich das anzupassen bzw. dann zu wechseln (wenn sich die PKs überschneiden oder auch nur um zu identifizieren welche Daten ich bereits habe und welche noch nicht -> das habe ich ja mit den foreign_key mit der aktuellen Quelle ja unter Kontrolle).

Eine weitere Überlegung ist sowieso noch andere Quellen hinzuzuziehen und in die DB einzufügen als erweiterte Informationen zu den vorhandenen Daten.
Wegen diesen Gründen ist mir die Idee gekommen eine 'Auflösungstabelle' zu erstellen welche meine PKs mit den verschiedenen Foreign-PKs auflöst.

Die Fragen die sich mir dazu aber stellen sind:
1) ist das sinnvoll?
2) wie gestalte ich so eine 1:1:1 Tabelle wobei der mittlere ODER rechte Wert auch ein NULL enthalten kann in ungünstigen Fällen (2. Quelle hat keine weiteren Daten zu diesem Datensatz)?
3) Hilft mir das überhaupt schnell von einer Quelle auf die andere umzuschalten?

Ich nehme wieder mein Fußballbeispiel:
Ich habe eine Quelle Q1 welche mir alle Daten zu den Ligen, einzelne Spielpaarungen usw. liefert.
Ich habe eine Quelle Q2 die mich zu den Spielen mit ähnlichen Daten beliefert, jedoch noch ein paar Informationen mehr bietet als Q1, an anderer Stelle aber weniger leifert als Q1. Ich brauche im Optimalfall beide Quellen. In ungünstigen Szenarien aber wenigestens die der Q1. Im ganz schlimmen Fall, bei welchem ich die Quellen tauschen möchte/muss, dann ausschliesslich Q2....

Wie ich das praktisch löse habe ich mir so gedacht:
Ich habe einen Datensatz von Q1 mit dessen PK. Beim inserten prüfe ich ob es in der Auflösungstabelle diesen PK als Subkey (foreign_key1 -> fk1) gibt. Wenn ja -> Datensatz bereits vorhanden (also nichts machen), wenn nein -> inserten. Also ganz so wie jetzt wobei lediglich diese Spalte ja in der Haupt-Tabelle enthalten ist).
Ich generiere weiterhin meine PK mit AI und nach dem inserten greife ich die PK ab und füge diese in diese Auflösungstabelle in die Spalte 'MeinPK' (-> mPK) ein und den pk1 eben in seine Spalte. In die Spalte der Q2 kommt ein NULL (ich habe zu diesem Zeitpunkt ja keine Q2-Daten).
Beim parsen der Q2 mache ich das genauso mit der Prüfung und update die 2. foreign-key-Spalte der Auflösungstabelle wenn Datensatz vorhanden.

So, damit könnte ich 2 verschiedene Quellen in meinem Datenbestand zusammenfügen. Beim wechseln der Quellen muss ich lediglich die fk1 und fk2 in den update-scripten vertauschen und die fk2 wird 'führend' und die fk1 sekundär (kann/muss aber nicht vorhanden sein).

Q1 und Q2 haben eine große Schnittmenge auf die ich es abgesehen habe. Somit würde die Kernsache damit nicht beinträchtigt. Nur die Susatzdaten der Q1 finde ich nützlicher, aber meine Meinung kann sich irgendwann mal ändern und ich würde gerne flexibel bleiben können.

Ein weitere Schritt wäre: was wenn ich ganz auf eine neue Quelle (Q3) umsteigen wollen würde? Ich möchte meine DB einfach so flexibel wie möglich gestalten so daß ich 'druchtauschen' könnte wenn es sein müsste.

Ich hoffe hier Tipps zu bekommen ob die Vorgehensweise so ok ist, ob es praktikabel ist, ob es Sinn macht oder ob ich auf dem Holzweg bin. Ob es überhaupt geht oder ob es bessere Lösungen dazu gibt?

Schon einmal vielen Danke im Voraus für eure Hilfe oder zumindest für das Lesen bis hierher.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Ein Unique Constraint der über die Quelle und die foreign_id geht, kommt nicht in Frage weil?
kaineanung
User
Beiträge: 145
Registriert: Sonntag 5. April 2015, 20:57

Also eine Spalte mit dem foreign_key als unique in der (Hapt-)Tabelle selber??
Das habe ich ja momentan. Aber ich möchte die Quelle einfach austauschen können und auch weitere Quellen auf den Datensatz abgleichen können.
Soll ich dann für jede Quelle eine Spalte vorsehen oder soll ich eine Zuordnungstabelle erstellen wo ich das alles auslagern kann und zentral nach belieben weitere Quellen hinzufügen oder tauschen kann?

Aber wenn ich mir das so recht überlege: das kann ich ja in der betreffenden Tabelle ja auch machen.

Hat hier irgendwer schon mal sowas gehabt das er mehrere Quellen miteinander vereinen wollte? Wie hat derjenige das gemacht?
Was ist am einfachsten, was ist zu machen? Was ist quasi Standard bei solchen Vorhaben?

Haupttabelle:
id -> int, ai, pk
foreign_id -> int, unique
_____________________________________________________________
|Tabelle: soccer_matches |
|____________________________________________________________|
| id | foreign_id | LigaID | SeasonID | HomeTeamID | AwayTeamID | ...|
|____________________________________________________________|

Ich habe mir überlegt die foreign_id auszulagern damit die Haupttabelle dann so aussieht:
id -> int, ai, pk
__________________________________________________
|Tabelle: soccer_matches |
|_________________________________________________|
| id | LigaID | SeasonID | HomeTeamID | AwayTeamID | ...|
|_________________________________________________|

Dafür eine 'Auflösungstabelle' wie folgt:
id -> int, pk
q1_id ->int, unique
q2_id ->int, unique
_____________________________
|Tabelle: soccer_matches_pk_fk |
|___________________________|
| id | q1_id | q2_id | ... |
|___________________________|

Wenn ich in der soccer_matches ein Datensatz einfüge, wird ein PK generiert (autoincrement im pk 'id').
Diese id dann in die Auflösungstabelle 'soccer_matches_pk_fk' einfügen in die Spalte 'id' und jeweils die aktuelle 'foreign_id' in 'q1_id' oder 'q2_id', eben je nachdem welche Quelle gerade führend ist und eingefügt wird. Als Beispiel nehme ich jetzt die 'q1_id'.
Dann wird die Quelle 2 geparst und eingefügt in die DB. Mit der foreign_id der Quelle 2 zu den Datensätze 'matches' prüfe ich in der Auflösungstabelle nach ob es den Datensatz bereits gibt mit der foreign_id im 'q2_id'. Wenn doch -> nichts tun (ist ja bereits vorhanden), wenn nicht -> updaten des q2_id-Feldes. Hier ist aber ein weiteres Problem: ich müsste über Umwege herausfinden welche id (also pk der Haupttabelle) nun für diesen Datensatz zählt. Das wäre meine nächste Frage gewesen was und wie ihr dies hier tun würdet?
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

wenn ich das richtig versteht, was du willst, widerspricht sich das, was du willst, in Teilen. Bzw. es lässt sich nicht gut in das fixes Schema eines RDBMS pressen.

Bei einem RDBMS hast du ja nun mal fix definierte Tabellenschema, die man normalerweise auch nicht mehr so ohne weiteres im größeren Maßstab ändern will. Und was man in der Regel auch nicht will ist eine "Monstertabelle", die alle "hätte wäre wenn" abdeckt, wo am Ende dann aber 50% der Werte NULL sind.

Was ich denke ich in deinem Fall machen würde ist, pro Quelle eine Tabelle anzulegen und dann eine weitere Tabelle anlegen, wo hinterlegt es, welche Datensätze aus Tabelle Q1, Q2, Q3, ... zum gleichen Spiel gehören.

Alternativ kann man auch über eine Dokumenten-basierte DB nachdenken, bei der dann pro Dokument / Datensatz alle Daten zu einem Spiel hinterlegt sind. In diesem Fall müsste man aber dann natürlich auch berücksichtigen, ob alle Abfragen, die man machen will, so noch problemlos machbar sind.

Gruß, noisefloor
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

kaineanung hat geschrieben:Also eine Spalte mit dem foreign_key als unique in der (Hapt-)Tabelle selber??
Nein. Ich würde dir Vorschlagen zwei Spalte zu haben, eine um die Quelle zu identifizieren und eine weitere für die foreign_id. Dann setzt du einen unique constraint über beide Spalten, so dass die Kombination aus Quelle und foreign_id nur einmal vorkommen kann.

Auf die Weise kann foreign_id zwar mehrmals vorkommen bleibt aber eindeutig im Bezug auf eine Quelle.
Antworten