CC: Tabelle normalisieren oder nicht?

Hi,

ich habe unter anderem eine Tabelle mit

id
stadtteil
stadt

hier wiederholt sich halt Stadt öfters. Bei allen Stadtteilen von Berlin steht dahinter Stadt. Ich habe aber ca. 70 Städte, mache ich daraus für jede Stadt eine Tabelle. Hab gehört bei hohem Traffic geht das auf die Abrufzeit (PHP-Tutorial). Ausserdem wären das 70 Tabellen und es könnten noch mehr werden.

*g* CC

  1. Hallo,

    ich habe unter anderem eine Tabelle mit

    id
    stadtteil
    stadt

    [...] Ich habe aber ca. 70 Städte, mache ich daraus für jede Stadt eine Tabelle. [...]

    Ich bin zwar kein absoluter Datenbankspezialist, aber das was Du da meinst, hat nichts mit Normalisieren zu tun.

    Normalisiert wäre es so

    ----------
    Tabelle Stadt:

    stadt_id
    stadt_name

    (eventuell noch Zusatzinformationen wie Bundesland, Staat usw. , wobei diese dann auch normalisiert werden können)
    ----------
    Tabelle Stadtteil:

    stadtteil_id
    stadt_id
    stadtteil_name

    (und ev. wieder zusätzliche Informationen)
    ----------

    Solange du eindeutig bestimmen kannst, daß der Name der Stadt wirklich nur eine Stadt repräsentiert, und daß der Name auch nicht unterschiedlich geschrieben wird, also zwei Namen für eine Stadt, bzw. eventuelle Zusatzinformationen zu einer Stadt gesammelt werden sollen, funktionierts auch mit einer Tabelle.
    Wenn Du jetzt schon unsicher bist, dann mach zwei draus.

    Aber für jede Stadt eine eigene Tabelle finde ich gar nicht gut.

    Grüße
      Klaus

  2. Hallo,

    ich habe unter anderem eine Tabelle mit

    id
    stadtteil
    stadt

    Ich habe aber ca. 70 Städte, mache ich daraus für jede Stadt eine Tabelle.

    Also ich kenne dieses Tutorial ja nicht, aber eine Tabellen-Normalisierung ist eigentlich auch etwas grundsätliches - und siebzig Tabellen wirst Du auch nicht haben, sondern zwei bei optimaler Normalisierung 3 Tabellen:

    Tabelle 1:
    StadtID      ----------|
    Stadt                  |
                           |
    Tabelle 2:             |
    StadtteilID ---------| |=(Verknüpfung)
    Stadtteil            | |
                         | |
    Tabelle 3:           | |
    StadteilID  -------- | |
    StadtID     -----------|

    Viele Grüße aus Köln
    Markus

    1. Tabelle 1:
      StadtID      ----------|
      Stadt                  |
                             |
      Tabelle 2:             |
      StadtteilID ---------| |=(Verknüpfung)
      Stadtteil            | |
                           | |
      Tabelle 3:           | |
      StadteilID  -------- | |
      StadtID     -----------|

      Wo ist der Vorteil, anstelle des Stadtnamens wiederholt sich hier in Tabelle 3 immer die StadtID.

      ich hab's so gemacht:

      Tabelle:
      --------
      ID
      stadtteil
      stadt

      Vor allem, weil die Stadtteile mit weiteren Tabellen verknüpft werden (Shops, die in den Stadtteil liefern).

      *g* CC

      1. Guten Morgen, :-)

        Wo ist der Vorteil, anstelle des Stadtnamens wiederholt sich hier in Tabelle 3 immer die StadtID.

        Redundanz heißt/ist das Zauberwort. Sich wiederholende Stadtnamen und Stadtteile blähen eine Datenbank unnötig auf, erhöhen die Gefahr von Ikonsistenz und vermindern die Performance.

        Zudem ist der Wartungsaufwand deutlich geringer.

        Tabelle:

        ID
        stadtteil
        stadt

        zum Beispiel:

        Köln hat schätzungweise 30 Stadtteile. Bei Deiner Tabelle würdest Du daher den Namen Köln ca. 30 mal eingeben müssen. Für die anderen Großstädte wiederholt sich diese Prozedur. Neben viel Arbeit, stellt diese Variante natürlich eine hohe Gefahr für Tippfehler (Köln,Kölm,Kölln usw.) dar.

        Vernünftige Abfragen und Auswertungen sind auch nicht mehr möglich. Ändert sich ein Stadtname, müsstest Du wiederum jeden Datensatz anpacken und ändern (mit den o.g. Nachteilen).

        Für Stadtteile ist der Arbeitsaufwand noch höher, da sich wahrscheinlich sehr häufig gleiche Stadtteilnamen in unertschiedlichen Städten wiederfinden werden.

        Kurz, eine vernünftige Planung und Architektur einer relationalen Datenbank erspart später erhöhten Wartungsaufwand, steigert die Performance, verhindert Redundanzen (obwohl diese in seltenen Fällen sogar erwünscht sind) und Inkosistenzen.

        Dieses Verhalten steigert unproportinal stark zum Anwachsen Deiner Datensätze.

        Viele Grüße aus Köln
        Markus

        1. Tabelle:

          ID
          stadtteil
          stadt

          zum Beispiel:

          Köln hat schätzungweise 30 Stadtteile. Bei Deiner Tabelle würdest Du daher den Namen Köln ca. 30 mal eingeben müssen. Für die anderen Großstädte wiederholt sich diese Prozedur. Neben viel Arbeit, stellt diese Variante natürlich eine hohe Gefahr für Tippfehler (Köln,Kölm,Kölln usw.) dar.

          Hi, bin leider kein Experte, aber bei deiner Version taucht dann in der drtten Tabelle immer wieder die gleiche StadtID auf. OK mit Änderung und Tipfehlern hast du sicher recht.
          Ist die Performance bei Int (stadtID deine version) besser als bei varchar (stadtnamen).

          Ich habe nämlich noch die Tab.

          shops:
          -----------
          ID
          name
          usw...

          stadtteile:
          -----------
          ID
          stadtteil
          stadt

          zuordnung:
          -----------
          shopID
          stadtteilID
          position

          Aber du würdest die stadtteil-Tabelle wie bereits geraten normalisieren? Du wirst es besser wissen als ich.
          Aber werden nicht die Abfragen und das Eingabeformular zu kompliziert?

          Gruß CC

          1. Ist die Performance bei Int (stadtID deine version) besser als bei varchar (stadtnamen).

            Im Normalfalle ja, da Integervergleiche immer einfacher als Stringvergleiche sind.

            Ich habe nämlich noch die Tab.

            shops:

            ID
            name
            usw...

            stadtteile:

            ID
            stadtteil
            stadt

            zuordnung:

            shopID
            stadtteilID
            position

            Aber du würdest die stadtteil-Tabelle wie bereits geraten normalisieren? Du wirst es besser wissen als ich.

            Eine Normalisierung der Stadtteiltabelle hat ursächlich keine Auswirkung auf die Shops. Lediglich die Abfrage über Shop,Stadtteil und Name der Stadt wäre neu zu schreiben.
            Allgemeiner gesagt, müssen alle Abfragen (und natürlich auch die INSERT bzw UPDATE Statements) geändert werden, in denen eine Stadt angesprochen werden soll.

            Aber werden nicht die Abfragen und das Eingabeformular zu kompliziert?

            Komplizierter ja, aber nicht unlösbar. Und bei einem vernünftige DB-System auch nicht unperformant.
            Mein Tip ist, zuerst die Tabellen vernünftig aufzubauen, sprich zu normalisieren. Dann mit Testdaten füllen, dann Performancetests machen. Erste wenn bei den Tests Performanceprobleme auftauchen, solltest Du Dir zusätzliche Gedanken machen.
            Man sollte sich halt nicht kratzen _bevor_ es juckt. Frau natürlich auch nicht:-)

            Grüße
              Klaus

        2. Hallo,

          Wo ist der Vorteil, anstelle des Stadtnamens wiederholt sich hier in Tabelle 3 immer die StadtID.

          Köln hat schätzungweise 30 Stadtteile. Bei Deiner Tabelle würdest Du daher den Namen Köln ca. 30 mal eingeben müssen. Für die anderen Großstädte wiederholt sich diese Prozedur. Neben viel Arbeit, stellt diese Variante natürlich eine hohe Gefahr für Tippfehler (Köln,Kölm,Kölln usw.) dar.

          Selbst wenn der klassische Tipfehler ausbleibt, gibts immer noch 'Köln' bzw 'KÖLN', welche in einer vernünftigen DB nicht das selbe sind.
          Und, zwei Orte können zwar den gleichen Namen haben aber nicht die gleichen Orte sein:-)

          Für Stadtteile ist der Arbeitsaufwand noch höher, da sich wahrscheinlich sehr häufig gleiche Stadtteilnamen in unertschiedlichen Städten wiederfinden werden.

          Aber, es ist unvernünftig einen Record in Stadtteile mehreren Orten zuzuordnen. Was, wenn ich der Name eines Stadtteils des einen Ortes ändert, der eines anderen nicht. Aus der Traum.

          Besser ist es das Prinzip der Entität zu verfolgen. Jeder Record (Entität) steht für eine einmalige Sache eines bestimmten Typs (Tabelle). Das bedeutet auch, daß zwei stadtteile in verschiedenen Orten auch zwei Entitäten in der Tabelle Stadtteil sein sollen.

          Kurz, eine vernünftige Planung und Architektur einer relationalen Datenbank erspart später erhöhten Wartungsaufwand, steigert die Performance, verhindert Redundanzen (obwohl diese in seltenen Fällen sogar erwünscht sind) und Inkosistenzen.

          Ja, aber über das Ziel hinaus schießen ist ebenso unvernünftig. Normalisieren auf 'Teufel komm raus' kann auch ganz schön nach hinten losgehen.
          Deshalb sind in diesem Falle zwei Tabellen die bessere Wahl. Eine für die Stadt und eine für die Stadtteile.

          Grüße
            Klaus

          1. Hallo Klaus,

            Wo ist der Vorteil, anstelle des Stadtnamens wiederholt sich hier in Tabelle 3 immer die StadtID.

            Und, zwei Orte können zwar den gleichen Namen haben aber nicht die gleichen Orte sein:-)

            Meiune Worte

            Aber, es ist unvernünftig einen Record in Stadtteile mehreren Orten zuzuordnen. Was, wenn ich der Name eines Stadtteils des einen Ortes ändert, der eines anderen nicht. Aus der Traum.

            Besser ist es das Prinzip der Entität zu verfolgen. Jeder Record (Entität) steht für eine einmalige Sache eines bestimmten Typs (Tabelle). Das bedeutet auch, daß zwei stadtteile in verschiedenen Orten auch zwei Entitäten in der Tabelle Stadtteil sein sollen.

            siehe meine Aussage zu gewollten Redundanzen :-)

            Ja, aber über das Ziel hinaus schießen ist ebenso unvernünftig. Normalisieren auf 'Teufel komm raus' kann auch ganz schön nach hinten losgehen.

            Was meinst Du wie wir hier Tabellen normalisieren (müssen). Da gäbe es aber bei gleicher Fragestellung noch mehr Tabellen ;-)

            Und bei Diskussionen um Tabellen-Normalisierung bleibt es IMO eben  nicht aus, wenn man die Normalisierungstheorie zumindest halbwegs in ihren möglichen Ausprägungen aufzeigt.

            Deshalb sind in diesem Falle zwei Tabellen die bessere Wahl. Eine für die Stadt und eine für die Stadtteile.

            Wenn ich mich selbst zitieren darf?

            sondern zwei bei optimaler Normalisierung 3 Tabellen<<

            Viele Grüße aus Köln
            Markus

            1. Hallo Markus,

              Wenn ich mich selbst zitieren darf?

              sondern zwei bei optimaler Normalisierung 3 Tabellen<<

              Aber ich versteh nicht, wozu die dritte Tabelle sein soll. IMHO benötigst Du nur solche Zwsichentabellen, um m:n BEziehungen aufzubauen, also um mehrere Datensätze der einen Tabelle mehreren Datensätzen einer anderen zuzuordnen. Und das ist in diesem Falle nicht notwendig, bzw. nicht gewünscht. Jeder Stadtteil kann immer nur in genau _einer_ Stadt sein.
              Die dritte Tabelle ist daher unvernünftig, da sie eher Schaden anrichten kann, als es zu verbessern.
              Das vermeiden von Redundanzen hat nichts damit zu tun, daß zwei Entitäten zufälligerweise auch die gleiche Ausprägung eines Attributs (Inhalt eines Tabellefelds ist gleich) haben.
              Obwohl mehrer Städte z.B. einen Stadtteil namens 'Innenstadt' haben können, sind es doch unterschiedliche Stdatteile. Diese in der Stdatteiltabelle gemeinsam zu verwalten ist nicht sinnvoll.
              Das ist eigentlich das, was ich sagen wollte.

              Grüße
                Klaus

              1. Hallo Klaus,

                benötigst Du nur solche Zwsichentabellen, um m:n BEziehungen aufzubauen, also um mehrere Datensätze der einen Tabelle mehreren Datensätzen einer anderen zuzuordnen.

                Nein, wir diskutieren IMO vielmehr über den Grad der Normalisierung.  Wir beide (mittlerweile wir drei) sind uns ja einig, daß zumindest 2 Tabellen benötigt werden.

                Unterschiedlicher Meinug sind wir beide, ob sich dadurch die Tabelle bereits in ihrer 3. Normalform befindet.

                <Theorie>
                Eine Tabelle bfindet sich dann in der 3.Normalform, wenn alle Attribute nur vom PrimaryKey abhängig sind.
                </Theorie>

                Die Frage stellt sich doch nun, ist ein Stadtteil als Eigenschaft vom PrimaryKey der Tabelle abhängig dann befindet sich die Tabelle bereits in der 3. Normalform, ist sie von der Stadt abhängig eben erst in der 2.Normalform.

                Und IMO befindet sich diese halt durch die "Zweitabellenlösung" erst in der 2.Normalform. Welche zugegeben schon ausreicht, aber mittlerweile sind wir halt sehr in das Theoretische abgewandert (Sorry CC), mit dazu auch noch unerschöpflichen Argumenten.

                Wir diskutieren uns hier manchmal - bei komplexen DB-Strukturen - die Köpfe wund. Daher würde ich vorschlagen, da CC ja eine ansich brachbare Lösung gefunden hat, dieses theoretische Geplänkel zu beenden.

                Viele Grüße aus Köln
                Markus

            2. Hi,

              also alles in allem ratet ihr mir zu dem ersten Tip von Markus.
              aber stadtteile gibts dann trotzdem doppelt (in verschiedenen städten mit verschiedener ID).

              *g* aus FFM der verwirrte CC

              1. Hallo CC,

                *g* aus FFM der verwirrte CC

                Sorry

                also alles in allem ratet ihr mir zu dem ersten Tip von Markus.
                aber stadtteile gibts dann trotzdem doppelt (in verschiedenen städten mit verschiedener ID).

                Beide Varianten sind lauffähig und vermindern Deinen Arbeits- und Wartungsaufwand erheblich. Für welche der beiden möglichen Varianten Du Dich letztendlich entscheidest ist von Dir abhängig.

                Solltest Du weitere Fragen haben, melde Dich :-)

                Viele Grüße
                Markus

                1. Solltest Du weitere Fragen haben, melde Dich :-)

                  OK, ine Frage, ich hatte ein Pulldownmenu mit den Städten (nicht aus der DB), dann kam auf der nächsten Seite ein Pulldonmenu mit den Stadtteilen der gewählten Stadt.
                  Wenn man einen stadtteil gewählt hat ging die Abfrage in PHP3-script:

                  select s.name, s.adresse, ... from shops s, stadtteile st, zuordnung z where st.stadt="$stadt" and st.stadtteil="$stadtteil" and st.id=z.stadtteilID and s.id=z.shopID order by z.position

                  oder so n der art, sitz grad net davor.

                  shops
                  -----
                  id
                  name
                  usw

                  stadtteile
                  ----------
                  id
                  stadtteil
                  stadt

                  zuordnung
                  ---------
                  shopID
                  stadtteilID
                  position

                  Wenn ich jetzt die stadtteil-Tabelle in 3 Tabellen splitte, wie greif ich in der Abfrage auf den gesuchten Stadtteil zu?

                  *g* CC

                  1. Hallo CC,

                    Wenn ich jetzt die stadtteil-Tabelle in 3 Tabellen splitte, wie greif ich in der Abfrage auf den gesuchten Stadtteil zu?

                    stadt
                    -----
                    ID        ...............
                    stadt                   .
                                            .
                                            .
                    stadteil                .
                    --------                .
                    ID        .........     .
                    stadtteil         .     .
                                      .     .
                                      .     .
                    city              .     .
                    --------          .     .
                    stadtteilID .......     .
                    stadtID..................
                    ID.......................
                                            .
                                            .
                    shop                    .
                    ------                  .
                    ID ...............      .
                    name             .      .
                    usw              .      .
                                     .      .
                                     .      .
                    zuordnung        .      .
                    ---------        .      .
                    ID               .      .
                    shopID ...........      .
                    cityID ..................
                    position

                    Als SQL handelt es sich hierbei um den Klassiker INNER JOIN:

                    SELECT zuordnung.zuordnung, shops.Shopname, Stadt.Stadt, stadtteil.Stadtteil
                    FROM stadtteil INNER JOIN (Stadt INNER JOIN (city INNER JOIN (shops INNER JOIN zuordnung ON shops.ID = zuordnung.ShopID) ON city.ID = zuordnung.cityID) ON Stadt.ID = city.Stadt) ON stadtteil.ID = city.Stadtteil
                    WHERE (((Stadt.Stadt)="$stadt") AND ((stadtteil.Stadtteil)="$stadtteil"));

                    Viele Grüße aus Köln
                    Markus