flank: Datenbank verkleinern

Hallo,

Wir entwickeln gerade eine KundenDatenbank (unter anderem).
Und ich bin gerade am Überlegen was sinnvoller ist.
Alle Daten in eine Tabelle oder wie folgt auflösen:

kddb:
ID | Vorname | Nachname | Str | PLZ | Ort | etc...
1    1         2          3     4     5
2    6         2          7     4     5

kdkeydb:
ID | VAL
1    Martin
2    Müller
3    Kastanienweg 3
4    60311
5    Frankfurt
6    Markus
7    Bauernstr. 15

So könnte man Redundanzen in der kddb vermeiden, aber die Abfragen werden dann im Programm viel Komplexer.

Was ist also nun sinnvoller?

Kann man die oben beschriebene Idee noch weiter ausarbeiten?

flank

  1. Hi,

    Alle Daten in eine Tabelle oder wie folgt auflösen:
    kddb:
    ID | Vorname | Nachname | Str | PLZ | Ort | etc...
    1    1         2          3     4     5

    [...]

    das ist Relationalität in seiner Reinform: Eine Datenbank besteht aus Verknüpfungen von Mengen von Mengen. Diese Form der Redundanzeliminierung darfst Du aber getrost dem DBMS überlassen - wenn dieses (bzw. deren Entwickler) es für sinnvoll hält, tut sie es. Tut sie es nicht, darfst Du davon ausgehen, dass es nicht sinnvoll ist.

    Kann man die oben beschriebene Idee noch weiter ausarbeiten?

    Du könntest die Redundanz bei den Referenzwerten eliminieren ;-) Nein, ernsthaft: Für die allermeisten Fälle gehst Du bereits einen Schritt zu weit.

    Cheatah

    --
    X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
    X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
    X-Will-Answer-Email: No
    X-Please-Search-Archive-First: Absolutely Yes
  2. Hallo,

    Was ist also nun sinnvoller?

    Ich glaube so wie du es jetzt hast ist es schon wieder übernormalisiert. Nehmen wir zum Beispiel die Straße, die wird nie öfter als einmal in der Datenbank so stehen, vor allem nicht mit der Hausnummer zusammen. also hast du die DB da im Eendeffekt nur um den Platz den die ID benötigt größer gemacht, sonst nichts. Je nach dem wie viele Daten da rein sollen gild das genau so für Vorname, Nachname. Die PLZ könnte da wiederum gleich als ID für den Ort dienen.

    Kann man die oben beschriebene Idee noch weiter ausarbeiten?

    Die Frage ist wo die Grenze ist. Ich denke das geht ziemlich auf die Performance, wenn man das so extrem normalisiert. Aber ich bin kein Datenbankexperte.

    Grüße
    Jeena Paradies

    --
    Modernes Webdesign professionell an den Mann/Frau gebracht | Jlog | Gourmetica Mentiri
    1. Hallo Jeena!

      Ich glaube so wie du es jetzt hast ist es schon wieder übernormalisiert.

      Das habe ich mir nämlich auch gedacht...

      Nehmen wir zum Beispiel die Straße, die wird nie öfter als einmal in der Datenbank so stehen, vor allem nicht mit der Hausnummer zusammen.

      Das wird eine sehr große KundenDatenbank mit ca. 1 Million Einträgen
      da würde es schon sinn machen die Straße und Hausnummer seperat einzugeben, aber da ist dann wieder das Problem bei Importen von gekauften Adressen (zB Klicktel) - da hängen Straße und Hausnummer zusammen und diese via Programm zu trennen fürht bestimmt zu fehlern
      oder?....
      <lautdenk>
      Bsp:
      Am Burgweg 5c
                ^
      Kurt-Schumacher-Straße 172b
                            ^
      Einfach beim letzten leer Zeichen trennen
      </lautdenk>

      ... Vorname, Nachname.

      Ja wie gesagt - viele Daten viele Namen (kombinationen aus Vname und Nname)

      Die PLZ könnte da wiederum gleich als ID für den Ort dienen.

      So kann man sich das feld "ort" sparen.

      hmmmm....

      1. Hi,

        <lautdenk>
        Einfach beim letzten leer Zeichen trennen
        </lautdenk>

        klappt nicht. Vertrau mir :-)

        ... Vorname, Nachname.
        Ja wie gesagt - viele Daten viele Namen (kombinationen aus Vname und Nname)

        Plus Index-Größen.

        Die PLZ könnte da wiederum gleich als ID für den Ort dienen.
        So kann man sich das feld "ort" sparen.

        31832 Springe
        31832 Bennigsen

        Cheatah

        --
        X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
        X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
        X-Will-Answer-Email: No
        X-Please-Search-Archive-First: Absolutely Yes
        1. Hi !

          Die PLZ könnte da wiederum gleich als ID für den Ort dienen.
          So kann man sich das feld "ort" sparen.

          31832 Springe
          31832 Bennigsen

          Du hast noch die Umkehrung vergessen: Wieviele verschiedene Postleitzahlen gibt es für z.B. München ?

          Gruß

          Hans

          1. Hi !

            Die PLZ könnte da wiederum gleich als ID für den Ort dienen.
            So kann man sich das feld "ort" sparen.

            31832 Springe
            31832 Bennigsen

            Du hast noch die Umkehrung vergessen: Wieviele verschiedene Postleitzahlen gibt es für z.B. München ?

            Das ist doch Irrelevant!

            Lösungsvorschlag:

            kddb:
            id | name | str | nr | ort_plz
            1    1      2     15b  1
            2

            kdkeydb:
            id | val
            1    Martin
            2    Fahnenweg

            ort_plz_db:
            id | plz   | ort
            1    31832   Springe
            2    31832   Bennigsen

            oder macht das Probleme?

            1. Hi Flank

              Du hast noch die Umkehrung vergessen: Wieviele verschiedene Postleitzahlen gibt es für z.B. München ?
              Das ist doch Irrelevant!

              also, wenn Du die PLZ als ID fuer den Ort verwenden solltest, dann haettest Du mehrere ID's fuer ein und dieselbe Stadt gehabt. Dies wuerde nicht zu einer Optimierung fuehren !

              Gruß

              Hans

              1. also, wenn Du die PLZ als ID fuer den Ort verwenden solltest, dann haettest Du mehrere ID's fuer ein und dieselbe Stadt gehabt. Dies wuerde nicht zu einer Optimierung fuehren !

                ja das habe ich ja auch nicht vor, Mit dem eben geposteten Beispiel vermeide ich doch diese Redundanzen!

                flank

            2. Hi,

              Lösungsvorschlag:
              id | name | str | nr | ort_plz

              das wäre ein Weg. Allerdings hast Du damit nur in seltenen Fällen Vorteile. Frage Dich: Welches ist die kleinste Information, die nur im Kontext des jeweiligen Datensatzes relevant ist?

              Cheatah

              --
              X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
              X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
              X-Will-Answer-Email: No
              X-Please-Search-Archive-First: Absolutely Yes
        2. Hi,

          <lautdenk>
          Einfach beim letzten leer Zeichen trennen
          </lautdenk>

          klappt nicht. Vertrau mir :-)

          Ich vertrau dir, aber könntest du mir deine Erfahrung, welche ich aus deinem "klappt nicht. Vertrau mir :-)" herausnehme kunt tun :-)

          ... Vorname, Nachname.
          Plus Index-Größen.

          wie meinst du das?

          31832 Springe
          31832 Bennigsen

          (siehe antowrt-Posting auf Hans)

          1. Hi,

            klappt nicht. Vertrau mir :-)
            Ich vertrau dir, aber könntest du mir deine Erfahrung, welche ich aus deinem "klappt nicht. Vertrau mir :-)" herausnehme kunt tun :-)

            es gibt beliebig viele Fälle, in denen innerhalb der Hausnummer Leerzeichen angegeben werden. Und sei es nur als "15 a" oder "23 - 27". Darüber hinaus fehlt das Leerzeichen ganz gerne mal, z.B. bei "Marienstr.17". Gänzlich falsche Ergebnisse bekommst Du dann bei "Berliner Str.18". Nein, die Hausnummer zu ermitteln ist eine echte Aufgabe.

            Plus Index-Größen.
            wie meinst du das?

            Wenn Du die normalisierten Daten vernünftig nutzen möchtest, brauchst Du mindestens einen Index darüber, welcher zusätzlichen Speicherplatz verbraucht.

            Cheatah

            --
            X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
            X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
            X-Will-Answer-Email: No
            X-Please-Search-Archive-First: Absolutely Yes
            1. Hallo

              es gibt beliebig viele Fälle, in denen innerhalb der Hausnummer Leerzeichen angegeben werden. Und sei es nur als "15 a" oder "23 - 27". Darüber hinaus fehlt das Leerzeichen ganz gerne mal, z.B. bei "Marienstr.17". Gänzlich falsche Ergebnisse bekommst Du dann bei "Berliner Str.18". Nein, die Hausnummer zu ermitteln ist eine echte Aufgabe.

              Es gibt in manchen Städten auch Straßen, die heißen 13D oder D13 oder ähnlich... Habe ich damals auch erst nicht glauben mögen.

              Was aber eine Sinngruppe bilden würde, wäre das Objekt

              99500 Irgendwo, Silberstraße 13

              Das könnte man mit einem Schlüssel versehen.
              Nur der Silberstraße 13 einen Schlüssel zu geben, wäre sinnlos, denn es gibt sie bestimmt auch in anderen Orten. Die unterschiedlichen Wntitäten wären dann nicht identisch.

              So wie oben wäre es auch sinnvoll, weil man Verteilungspläne darauf aufbauen könnte.

              LG
              Chris

              1. Moin,

                Es gibt in manchen Städten auch Straßen, die heißen 13D oder D13 oder ähnlich... Habe ich damals auch erst nicht glauben mögen.

                richtig - es gibt z. B. in Berlin Straßen, die haben Nummern. Die Straße heißt z. B. "Straße 2". Da käme dann noch die Nummer hinzu, also "Straße 2 5", also Straße 2, Hausnummer 5.

                Viele Grüße

                Jörg

              2. Glück auf!

                Es gibt in manchen Städten auch Straßen, die heißen 13D oder D13 oder ähnlich...

                Ja, beispielsweise in Mannheim.

                Gruß,
                der Juve

      2. Hi,

        Nehmen wir zum Beispiel die Straße, die wird nie öfter als einmal in der Datenbank so stehen, vor allem nicht mit der Hausnummer zusammen.

        Es soll aber, auch wenn es kaum zu glauben ist, tatsächlich Fälle geben, in denen mehrere Leute im selben Ort in derselben Straße und auch noch unter derselben Hausnummer wohnen.

        Das wird eine sehr große KundenDatenbank

        Ah, eine sehr große.

        mit ca. 1 Million Einträgen

        äh - doch keine große.

        Mal grob gerechnet: 80Mio Deutsche, 1Mio Kunden ==> jeder 80. wäre demnach Kunde.
        Ich kenne viele Wohnblöcke mit 10 oder mehr Stockwerken , jeweils 4 oder 5 Wohnungen pro Stockwerk.
        Wenn da im Durchschnitt 2 Leute drin wohnen, wären das bereits 10*5*2 = 100 Leute. Da ja jeder 80. Kunde ist, müßten dann schon 2 Kunden pro derartigem Wohnblock existieren ...

        da würde es schon sinn machen die Straße und Hausnummer seperat einzugeben, aber da ist dann wieder das Problem bei Importen von gekauften Adressen (zB Klicktel)

        Kundendaten oder gekaufte Adressen - Du widersprichst Dir ...

        da hängen Straße und Hausnummer zusammen und diese via Programm zu trennen fürht bestimmt zu fehlern

        Richtig - das ist nicht ganz einfach

        Einfach beim letzten leer Zeichen trennen

        Blablubbstr. 13 7/5

        Die PLZ könnte da wiederum gleich als ID für den Ort dienen.

        Wie schon erwähnt geht das nicht, da die Beziehung zwischen PLZ und Ort n:m ist - es gibt Orte mit mehreren PLZ und es gibt PLZ, zu denen es mehrere Orte gibt.

        So kann man sich das feld "ort" sparen.

        Nö.

        cu,
        Andreas

        --
        Warum nennt sich Andreas hier MudGuard?
        Schreinerei Waechter
        Fachfragen per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
  3. Hallo,

    kdkeydb:
    ID | VAL
    1    Martin
    2    Müller
    3    Kastanienweg 3
    4    60311
    5    Frankfurt
    6    Markus
    7    Bauernstr. 15

    Du hast ja schon viele gute Tipps bekommen.
    Denke aber bitte auch noch daran, dass es ein wenig kompliziert werden könnte, wenn (es gibt bestimmt mehrere 'Hauptstraßen' in verschiedenen Städten) ein Kunde umzieht und neuere Straße noch nicht enthalten ist.
    Pass auf, dass du das gut schaffst!

    werbeklaus

  4. Hallo,

    Also nach all den guten Tipps (auch von einem Guten Freund von mir) stelle ich mir meine Datenbank so vor:

    CREATE TABLE kd_anrede (
      id INT NOT NULL,
      anrede TEXT NULL,
      PRIMARY KEY(id)
    );

    CREATE TABLE kd_bereich (
      id INT NOT NULL,
      bereich TEXT NULL,
      PRIMARY KEY(id)
    );

    CREATE TABLE kd_firma (
      id INT NOT NULL AUTO_INCREMENT,
      firma TEXT NULL,
      PRIMARY KEY(id)
    );

    CREATE TABLE kd_titel (
      id INT NOT NULL,
      titel TEXT NULL,
      PRIMARY KEY(id)
    );

    CREATE TABLE kd_funktion (
      id INT NOT NULL,
      funktion TEXT NULL,
      PRIMARY KEY(id)
    );

    CREATE TABLE kd_firma_adr (
      id INT NOT NULL AUTO_INCREMENT,
      kd_firma_id INT NOT NULL,
      str TEXT NULL,
      plz TEXT NULL,
      ort TEXT NULL,
      PRIMARY KEY(id),
      INDEX kd_firma_adr_FKIndex1(kd_firma_id)
    );

    CREATE TABLE kd_mitarbeiter (
      id INT NOT NULL AUTO_INCREMENT,
      kd_firma_adr_id INT NOT NULL,
      kd_stamm_id INT NOT NULL,
      kd_funktion_id INT NOT NULL,
      kd_bereich_id INT NOT NULL,
      vorwahl INT NULL,
      tel TEXT NULL,
      fax TEXT NULL,
      mobil TEXT NULL,
      mobil2 TEXT NULL,
      email TEXT NULL,
      email2 TEXT NULL,
      PRIMARY KEY(id),
      INDEX kd_mitarbeiter_FKIndex2(kd_bereich_id),
      INDEX kd_mitarbeiter_FKIndex3(kd_funktion_id),
      INDEX kd_mitarbeiter_FKIndex3(kd_stamm_id),
      INDEX kd_mitarbeiter_FKIndex4(kd_firma_adr_id)
    );

    CREATE TABLE kd_stamm (
      id INT NOT NULL AUTO_INCREMENT,
      kd_anrede_id INT NOT NULL,
      kd_titel_id INT NOT NULL,
      vname TEXT NULL,
      nname TEXT NULL,
      str TEXT NULL,
      plz TEXT NULL,
      ort TEXT NULL,
      vorwahl INT NULL,
      tel TEXT NULL,
      fax TEXT NULL,
      mobil TEXT NULL,
      mobil2 TEXT NULL,
      email TEXT NULL,
      email2 TEXT NULL,
      PRIMARY KEY(id),
      INDEX kd_stamm_FKIndex1(kd_anrede_id),
      INDEX kd_stamm_FKIndex2(kd_titel_id)
    );

    CREATE TABLE kd_combine (
      id INT NOT NULL AUTO_INCREMENT,
      kd_mitarbeiter_id INT NOT NULL,
      combine_id INT NOT NULL,
      PRIMARY KEY(id),
      INDEX kd_combine_FKIndex1(kd_mitarbeiter_id)
    );

    'kd_combine' möchte ich noch erläutern:
    damit möchte ich Kunden/Mitarbeiter verknüpfen (Eine Firma - Vertrieb/Buchhaltung/Produktion)

    MfG
    flank