# Datenmodell und Arbeiten mit JOINs

## Kernmodell

```mermaid
erDiagram
    KONTINENT ||--o{ LAND : Hauptkontinent
    LAND ||--o{ LANDTEIL : umfasst
    LAND ||--o{ STADT : enthaelt
    LANDTEIL o|--o{ STADT : Verwaltungsregion
    STADT ||--o{ STADT_ALIAS : Namen
    LAND ||--o{ LAND_ALIAS : alte_Kuerzel
    LAND ||--o{ LAND_SPRACHE : Sprachcodes
    LAND ||--o{ OBJEKT_LAND : Zuordnung
    GEO_OBJEKT ||--o{ OBJEKT_LAND : Zuordnung
    GEO_OBJEKT ||--o{ OBJEKT_MESSWERT : Messwerte
    GEO_OBJEKT ||--o{ OBJEKT_GEOMETRIE : Geometrien
    GEO_OBJEKT ||--o{ OBJEKT_ALIAS : Namen
    QUELLE ||--o{ OBJEKT_MESSWERT : Herkunft
```

## Die wichtigsten Verknüpfungen

| Beziehung | JOIN-Bedingung |
|---|---|
| Ort zu Land | STADT.L_ID = LAND.L_ID |
| Ort zu Region | STADT.LT_ID = LANDTEIL.LT_ID |
| Land zu Kontinent | LAND.KONTINENT_CODE = KONTINENT.CODE |
| Objekt zu Land | GEO_OBJEKT.ID = OBJEKT_LAND.OBJEKT_ID, dann OBJEKT_LAND.L_ID = LAND.L_ID |
| Kennzahl zu Objekt | OBJEKT_MESSWERT.OBJEKT_ID = GEO_OBJEKT.ID |
| Messwertquelle | OBJEKT_MESSWERT.QUELLE_ID = QUELLE.ID |
| Küstenstadt zu Meer | STADT_MEER.STADT_ID = STADT.ID, STADT_MEER.MEER_ID = GEO_OBJEKT.ID |

Regionen sind über LT_ID wie `DE.15` global eindeutig. Der zusätzliche zusammengesetzte Fremdschlüssel in STADT verhindert, dass eine Stadt einem Land und gleichzeitig der Region eines anderen Landes zugeordnet wird. Alte Terra-Regioncodes wie `NRW` sind nicht dieselben Codes.

GRENZE speichert jedes Landpaar einmal. V_NACHBARN stellt beide Richtungen für einfachere Abfragen bereit. HAUPTSTADT_ZUORDNUNG verbindet Länder und die von GeoNames als Hauptstadt geführten Ortsdatensätze. Die Quellbezeichnung der Hauptstadt steht zusätzlich in LAND.

## Geografieansichten

BERG, FLUSS, SEE, MEER, INSEL, WUESTE und EBENE sind Ansichten, die nach GEO_OBJEKT.TYP filtern. Die bekannten Namensspalten B_NAME, F_NAME, S_NAME, M_NAME, I_NAME, W_NAME und E_NAME sind vorhanden. ID identifiziert den Objektdatensatz. Namen sind ausdrücklich kein Schlüssel.

Bei den Objektansichten bezeichnet **GEO_LAENGE** den geografischen Längengrad eines Lagepunkts. **FLUSS.LAENGE** ist dagegen eine Gesamtlänge in Kilometern, falls bekannt. BREITE/GEO_LAENGE ergänzter Flächen und Linien sind repräsentative Kartenpunkte, keine Quelle, Mündung oder Vermessungsposition. Die ursprünglichen Rohkoordinaten stehen im Originalbestand.

GEO_BERG, GEO_FLUSS, GEO_SEE und die entsprechenden weiteren Ansichten zeigen eindeutige Land-Objekt-Paare. Für die Herkunft der Beziehung auf OBJEKT_LAND zugreifen. Sie enthalten kein LT_ID, da eine alte oder aus Länderpolygonen abgeleitete Zuordnung keine gesicherte Verwaltungsregion des Objekts belegt.

## Änderungen richtig vornehmen

Die SQL-Konsole dient nur zum Lesen. Für Änderungen eine Arbeitskopie in einem Datenbankprogramm öffnen und bei SQLite **für jede Verbindung** `PRAGMA foreign_keys = ON;` ausführen. SQLite speichert diese Einstellung nicht dauerhaft in der Datei. Änderungen in Transaktionen vornehmen. Geografieansichten sind nicht beschreibbar; Einträge in GEO_OBJEKT und ihre Beziehungen ändern.

Zu jedem neuen Messwert Quelle und Einheit eintragen. Falls er den angezeigten Wert ersetzen soll, in derselben Transaktion alle alten BEVORZUGT-Markierungen dieser Objektkennzahl zurücksetzen und den neuen Wert bevorzugen. Nicht mehrere bevorzugte Werte für dieselbe Kennzahl anlegen. Nach Änderungen `python pruefen.py` gegen eine passende Fassung der erwarteten Bestandszahlen ausführen. Die feste Prüfung dieser Ausgabe ist für den mitgelieferten Snapshot geschrieben; eine bewusst erweiterte Datenbank benötigt entsprechend angepasste Sollzahlen.

Einwohnerzahlen aus unterschiedlichen Erhebungsständen sind keine belastbare Zeitreihe. Für Zeitreihen zuerst eine eigene Beobachtungstabelle mit Land-/Ort-ID, Kennzahl, Bezugsjahr und Quelle anlegen.
