Normalisieren der Daten#

Unter Normalisierung wird die Aufteilung von Attributen oder Tabellenspalten in mehrere Relationen oder Tabellen verstanden, sodass keine Redundanzen mehr enthalten sind.

Beispiel#

Im folgenden Beispiel normalisieren wir die Sprache, in der die Bücher veräffentlicht wurden.

  1. Hierfür erstellen wir zunächst eine neue Tabelle languages mit den Spalten id und language_code anlegen:

    6cursor.execute(
    7    """CREATE TABLE languages
    8                  (id INTEGER PRIMARY KEY AUTOINCREMENT,
    9                  language_code VARCHAR(2))"""
    
  2. Anschließend legen wir die Werte de und en in dieser Tabelle an:

    12cursor.execute(
    13    """INSERT INTO languages (language_code)
    14                  VALUES ('de')"""
    15)
    16
    17cursor.execute(
    18    """INSERT INTO languages (language_code)
    
  3. Da SQLite MODIFY COLUMN nicht unterstützt, legen wir nun eine temporäre Tabelle temp an mit allen Spalten aus books und einer Spalte language_code, die die Spalte id aus der Tabelle languages als Fremdschlüssel verwendet:

    22cursor.execute(
    23    """CREATE TABLE "temp" (
    24                  "id" INTEGER,
    25                  "title" TEXT,
    26                  "language_code" INTEGER REFERENCES languages(id),
    27                  "language" TEXT,
    28                  "author" TEXT,
    29                  "license" TEXT,
    30                  "release_date" DATE,
    31                  PRIMARY KEY("id" AUTOINCREMENT)
    32                  )"""
    
  4. Nun übernehmen wir die Werte aus der books-Tabelle in die temp-Tabelle:

    35cursor.execute(
    36    """INSERT INTO temp (title,language,author,license,release_date)
    37                  SELECT title,language,author,license,release_date FROM books"""
    
  5. Die Angabe der Sprache in books als id der Datensätze aus der languages-Tabelle in temp übernehmen.

    40cursor.execute(
    41    """UPDATE temp
    42                  SET language_code = 1
    43                  WHERE language = 'de'"""
    44)
    
  6. Nun können wir die Spalte languages in der Tabelle temp löschen:

    55cursor.execute("""ALTER TABLE temp DROP COLUMN language""")
    

    Bemerkung

    Erst ab Python-Versionen ab 3.8, die nach dem 27. April 2021 veröffentlicht wurden, kann DROP COLUMN verwendet werden.

    Bei älteren Python-Versionen müsste eine weitere Tabelle angelegt werden, die nicht mehr die Spalte languages enthält und anschließend die Datensätze aus templ in diese Tabelle eingefügt werden.

  7. Auch die books-Tabelle kann nun gelöscht werden:

    57cursor.execute("""DROP TABLE books""")
    
  8. Und schließlich kann die temp-Tabelle umbenannt werden in books:

    59cursor.execute("""ALTER TABLE temp RENAME TO books""")