Hilfe für Tabellenstruktur gebraucht

Hallo allerseits,
ich soll eine Literatur-Datenbank in MySQL schreiben. Erste Ansätze stehen schon, aber im Moment komme ich nicht weiter. Unter anderem soll auch abgefragt werden können, welche Schriftsteller in bestimmten Städten geboren bzw. gestorben sind. Klang einfach, deshalb mein erster Ansatz für die Tabelle Autoren in etwa so:

AutorId
Name
Vorname
GebDatum
GebOrt
Nationalitaet

Das ist etwas verkürzt, reicht aber zur Erklärung. Nun mein Problem:
Ortsnamen haben sich im Lauf der Zeit geändert, Grass -> Danzig (jetzt Gdansk), Eichendorff -> Ratibor (jetzt Racibórz) usw. Grass z.B. soll aber gefunden werden, ob der User nun Danzig oder Gdansk eingibt.
Wahrscheinlich müssten die Ortsnamen in eine eigene Tabelle ausgelagert werden, aber wie soll die aussehen? Und wie die SQL-Abfrage, damit ich sowas wie

Ratibor (jetzt Racibórz)

ausgeben kann, denn das kommt ja nicht immer so, Geburtsort Leipzig bleibt eben einfach Leipzig…
Vielleicht ist es ganz einfach, aber irgendwie habe ich im Moment einen Knoten im Hirn.
Ich hoffe, ihr konnt mir helfen.

Schon mal vielen Dank
Marvin

Hallo Marvin,

ich würde dem Ort eine ID verpassen und eine entsprechend historisierte Lookuptabelle hinzufügen.

Tabelle Autor
Autor\_Id
Name
Vorname
GebDatum
GebOrt\_ID
TodOrt\_ID
Nationalitaet

Tabelle Ort
Ort\_ID
Name
gueltig\_von
gueltig\_bis

Die Historisierung sollte lückenlos sein, also zu jedem gueltig_bis, dass nicht das (fiktive) Endedatum ist, muss auch ein Datensatz mit einem entsprechenden Anfangsdatum existieren (Ich oute mich mal, ich musste mich auf http://gov.genealogy.net schlau machen wo Ratibor liegt und wann es um benannt wurde)

4711 Ratibor 01.01.1800 01.01.1945
4711 Racibórz 01.01.1945 31.12.9999

MfG Georg V.

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hi!

Die Historisierung sollte lückenlos sein, also zu jedem
gueltig_bis, dass nicht das (fiktive) Endedatum ist, muss auch
ein Datensatz mit einem entsprechenden Anfangsdatum existieren

Einspruch!
Welcher Name gilt (bei Deinem Beispiel) am 1.1.1945?
Der „alte“ Name ist noch gültig, der „neue“ jedoch auch schon -> je nach Datumsformat muß das vorhergehende Gültig-Bis einen Wert darunter liegen bzw. das nachfolgende Gültig-Von einen Wert darüber (unter Oracle 10g geht das ja bereits in Bruchteile von Sekunden hinein, meist reicht jedoch der Tag)

Zusätzlich muß im „letzten“ Satz KEIN Gültig-Bis vorkommen bzw. _darf_ NULL sein; das kommt jedoch auf die Implementierung an (VORSICHT: Der Satz mit Gültig-Bis = NULL muß nicht der aktuelle sein, da ja die Werte auch in der Zukunft liegen könnten)

So würde meine Tabelle aussehen:

4711 Ratibor 01.01.1800 31.12.1944
4711 Racibórz 01.01.1945

Grüße,
Tomh

PS: Für das ursprüngliche Beispiel könnte aber auch jene Struktur dienen:

Autor (wie gehabt)

Ort:

  • ID (eindeutig)
  • Name (_aktueller_ Name)

Ort_Historisch:

  • ID (nur mehr mit NAME eindeutig)
  • Name

Sodaß es wie folgt aussehen kann:

ORT
ID NAME
1 Chemnitz
2 St. Petersburg
3 Wien
4 Istanbul


ORT\_HISTORISCH
ID NAME
1 Karl-Marx-Stadt
2 Leningrad
4 Konstantinopel
4 Byzanz

Erinnert nur mich das an das „Multiple Identifier“-Problem?

Hallo Georg und Tomh,
erstmal vielen Dank für eure Mithilfe, hat mich ein gutes Stück weitergebracht.
Ich denke, ich werde die zweite Variante von Tomh nehmen, obwohl ich noch drüber nachdenke, ob das nicht doch in einer Tabelle geht, mit zwei zusätzlichen Spalten

heutiger\_Name true | false

und

ID\_heutigerName

als Verweis auf den heutigen Ortsnamen in der gleichen Tabelle…

@Georg
Das mit den Jahreszahlen wäre sicher auch irgendwie machbar, ist aber zu aufwendig, jedesmal recherchieren, von wann bis wann hieß der Ort wie?
Trotzdem vielen Dank für die Antwort

Viele Grüße
Marvin

Einspruch!
Welcher Name gilt (bei Deinem Beispiel) am 1.1.1945?
Der „alte“ Name ist noch gültig, der „neue“ jedoch auch schon
-> je nach Datumsformat muß das vorhergehende Gültig-Bis
einen Wert darunter liegen bzw. das nachfolgende Gültig-Von
einen Wert darüber (unter Oracle 10g geht das ja bereits in
Bruchteile von Sekunden hinein, meist reicht jedoch der Tag)

Zusätzlich muß im „letzten“ Satz KEIN Gültig-Bis vorkommen
bzw. _darf_ NULL sein; das kommt jedoch auf die
Implementierung an (VORSICHT: Der Satz mit Gültig-Bis = NULL
muß nicht der aktuelle sein, da ja die Werte auch in der
Zukunft liegen könnten)

Einspruch abgelehnt! Und Du lieferst die Begründung auch direkt mit…

Da man eben nicht weiss, wie gut ein DBMS die Zeitdifferenzen sich zwei unterschiedlichen Zeitpunkten auflösen kann, sollte man die Differenz nummerisch 0 werden lassen. Die Abfrage für den gültigen Namen muss natürlich lauten

 WHERE untere\_Intervallgrenze \>= Zeitwert
 AND obere\_Intervallgrenze 
Null-Werte sind für Indizes übrigens suboptimal, und da bei historischen Tabellen die häufigste Abfrage ist: "Was ist der letzte gültige Wert?" sollte man auch aus diesen Grund vom Nullwert die Finger lassen.

MfG Georg V.

Hi!

Einspruch abgelehnt! Und Du lieferst die Begründung auch
direkt mit…

Nein, weil …

Da man eben nicht weiss, wie gut ein DBMS die Zeitdifferenzen
sich zwei unterschiedlichen Zeitpunkten auflösen kann, sollte
man die Differenz nummerisch 0 werden lassen.

Es ist egal, ob das DBMS auf Nanosekunden oder Monate den Datums-/Zeitwert auflösen kann, es kommt nur darauf an, das rein datentechnisch zu einem Zeitpunkt KEINE Überschneidungen vorkommen dürfen; die Möglichkeit des

 WHERE untere\_Intervallgrenze \>= Zeitwert
 AND obere\_Intervallgrenze ist nur ein programmtechnisches Hilfsmittel, um Überschneidungen, die aufgrund der Daten vorkommen, auszumerzen -\> solche Daten erst gar nicht zulassen ...



> Null-Werte sind für Indizes übrigens suboptimal


Warum? Das Gültig-Bis kommt ja gar nicht in den Index rein, das Von-Datum reicht vollkommen - im Normalfall; gibt's mehrere Änderungen täglich bei reinen Tages-Werten, ist das Ganze sowieso nicht mehr abbildbar.



> , und da bei  
> historischen Tabellen die häufigste Abfrage ist: "Was ist der  
> letzte gültige Wert?" sollte man auch aus diesen Grund vom  
> Nullwert die Finger lassen.


Hier habe ich in den Datawarehouse-Projekten die Erfahrung gemacht, daß die von-bis-Abfrage nur mehr für historische Daten vorgesehen ist; die aktuell gültige wird mit einem eigenem Indikator versehen, sodaß so eine historisierte Tabelle dann etwa so aussieht:

    
    ID NAME GUELTIG\_VON GUELTIG\_BIS GUELTIG
    1 Byzanz 01.01.0100 31.12.0500 N
    1 Konstantinopel 01.01.0501 31.12.1400 N
    1 Istanbul 01.01.1401 J



Grüße,
Tomh

PS: Ich warte seit 10 Jahren auf eine bessere Lösung, habe aber bisher noch keine gefunden bzw. wurde mir noch keine\_angeboten\_, die wirklich wesentlich perormanter war - bei maximal gleicher Komplexität