WernerK: Design, Bigint, char?

Hallo,
ich hätte gerne euren Rat zu einem Datenbankdesign.
Gehen wir von einer Art "Bestellsystem" aus

Die Haupttabelle wäre "tabBestellungen"

bestellid, datum, bestellperson
------------------------------------------

Dann gibt es eine Tabelle "tabBestellArtikel"

artikel, bestellid
------------------------------------------

Die Frage ist nun ob man für die Tabelle "tabBestellArtikel" noch eine zusätzliche "Auto_increment" Spalte machen sollte?
Gehen wir mal von 100000 Inserts am Tag für die Haupttabelle aus. Für jeden Eintrag dort kann es in der  Tabelle "tabBestellArtikel" mehrere Inserts geben. Angenommen es wären 10, dann hätten wir schon 1 Mio.
Im Jahr wären das dann 365000000.
Mit einem BIGINT als "tabBestellArtikel_ID" würde man ja auch in vielen Jahren noch nicht an die Grenze des zulässigen Wertes kommen?

Es könnte nämlich sein, dass noch eine dritte Tabelle "tabBestellPreis" notwendig ist. Dann könnte man die tabBestellArtikel_ID als Foreign Key verwenden.

artikelpreis, tabBestellArtikel_ID

Eine andere Überlegung wäre zusätzlich in die Tabelle  "tabBestellArtikel" noch ne Spalte "artikelpreis" hinzuzufügen.

artikel, bestellid, artikelpreis,

Da es aber nicht immer zwingend einen Preis geben muss, wären hier viele Zeilen mit leeren Spalten. Ich denke dies wäre das ungüstigere Design oder?

Gruss
Werner
------------------------------------------

  1. Hello Werner,

    BIGINT ist sicherlich ein passender Datentyp für eine UNIQUE-ID in einer Tabelle, in der so viele Inserts zu erwarten sind. Allerdings muss auch die API, die Du verwenden willst, mit dem Datentyp klarkommen.

    http://de1.php.net/manual/en/mysqli.insert-id.php

    "If the number is greater than maximal int value, mysqli_insert_id() will return a string."

    In wieweit das dann für die weitere Verarbeitung relevant wird, müsstest Du im Auge behalten. Man muss ja nicht unbedingt _in__der__API_ mit der ID rechnen, wenn überhaupt...

    Die Spalte für den Preis ist aber unabdingbar, wenn keine separate Preishistorie programmiert werden soll. Und selbst, wenn die existiert, würde ich hier immer noch die Spalte für den "Snapshot" vorsehen. Der Preis in der Artikel-Tabelle (also derjenigen, die alle angebotenen Artikel führt), kann sich ja schon Millisekunden nach der Bestellungserfassung geändert haben.

    Liebe Grüße aus dem schönen Oberharz

    Tom vom Berg

    --
     ☻_
    /▌
    / \ Nur selber lernen macht schlau
    http://restaurant-zur-kleinen-kapelle.de
    1. Hallo Tom,

      danke für deine Hinweise und Tipps.
      (PS: es handelt sich überigens um kein echtes Bestellsystem von Waren, aber im Prinzip ist der Ablauf ähnlich)

      Noch eine weitere Frage zur Normalisierung:
      Momentan sieht die Haupttabelle "tabBestellArtikel" unter anderem so aus.

      bestellid, datum, seiten, adresse1,adresse2,adresse3,adresse4,adresse5
      -----------------------------------------------------------------------------------
      1, 2013-12-24,3, Werner,wk@email,22333,meinOrt,0511-223

      Nach der Normalform1 soll man ja solche SPalten wie adresse1,adresse2... vermeiden.
      Daher habe ich eine neue Tabelle "bestelluser" angelegt.

      bestellid,uservalue,userindex
      1,        Werner, 1
      1,        wk@email, 2
      1,        22333, 3
      1,        meinOrt, 4

      Jetzt hat man halt die Situation das sich diese Tabelle verfünfacht. Hat die Haupttabelle 100 Zeilen, hat diese nun 500.
      Eine andere Möglichkeit der Tabelle "bestelluser" wäre eventuell

      bestellid,adresse1,adresse2,adresse3,adresse4,adresse5
      ----------------------------------------------------------

      So hätte man weniger Zeilen aber auch leere Spalten wenn bestimmte Adressfelder leer sind.

      Die Frage ist was braucht weniger Speicher? (die Spalte "uservalue" als varchar(200) )

      Es gibt ja eine eigene Tabelle "userdata". Am optimalsten wäre natürlich man würde gleich die "userid" aus dieser Tabelle in die  Tabelle "bestelluser" schreiben. Das geht aber nicht, weil im Programmablauf in bestimmten Situationen vor dem Speichern der Anwender seine Adressfelder ändern kann. Diese geänderten Daten werden dann gespeichert. Diese Änderung ist aber nur einmalig für diese "Bestellung" und nicht dauerhaft in der Tabelle "userdata".

      Welches Design bietet sich an?

      Gruss
      Werner

      1. Hello Werner,

        ich denke, Du könntest auf anderem Wege besser zum Ziel kommen:

        Wir legen die Tabellen

        • Kunde
        • Artikel
        • Bestellung
        • Bestellposition

        an, hier nur erstmal ganz einfach und minimalistisch

        Kunde
        ------------------------
        id
        name
        strasse
        plz
        ort

        Artikel
        ------------------------
        id
        wgr
        artnr
        bezeichnung
        preis
        datum

        Bestellung
        ------------------------
        id
        id_kunde
        bestelldatum

        Bestellposition
        ------------------------
        id
        id_bestellung
        id_artikel
        menge
        bemerkung

        Du musst an dieser Stelle aber bereits festlegen, wann Du an welcher Tabelle Änderungen vornehmen willst und überlegen, wie sich das auf die anderen auswirken könnte.

        Ich habe das hier mal so aufgebaut, dass man in Artikel keine Änderungen an den Datensätzen mehr vornehmen darf. Um z.B. die Bezeichnung zu ändern, oder den Preis, musst Du dann eben einen neuen Datensatz anlegen mit derselben wgr-artnr. Somit ist sichergestellt, dass Bestellungen auch später noch ordnungsgemäß ausgegeben werden können, auch wenn sich der Artikelpreis inzwischen x-mal geändert hat.

        In der Praxis würde man in der Tabelle Bestellposition aber immer eine Kopie von Preis und Bezeichnung hinterlegen. Dann dürfte man auch in Artikel unbesorgt den Preis oder die Bezeichnung ändern...

        Liebe Grüße aus dem schönen Oberharz

        Tom vom Berg

        --
         ☻_
        /▌
        / \ Nur selber lernen macht schlau
        http://bikers-lodge.com
        1. Hallo Tom,

          vielen Dank für deine Mühe und Hilfe.
          Mein Problem ist hier die Tabelle "Bestellung".

          Bestellung
          ------------------------
          id
          id_kunde
          bestelldatum

          Angenommen es gibt den Kunden "Fred Feuerstein"

          Kunde
          ------------------------
          id,name,strasse,plz,ort
          5,'Fred Feuerstein','Feuerstr.3','11111','Feuerort'

          In "Bestellung" wäre es dann so

          id,id_kunde,bestelldatum
          --------------------------------
          1,5,'2013-11-01'

          Wenn ich nur feste, dauerhafte Kunden hätte, wäre das so ok. Aber es handelt sich halt um kein echtes, richtiges Bestellsystem mit Waren.
          Es kann beim "Bestellvorgang" vorkommen, dass vor dem Speichern ein Formular mit Adressfelder eingeblendet wird. Hier kann man dann in Freitextfeldern Daten eingeben. Diesen Kunden muss es aber nicht geben. Auch könnnen bestimmte Felder leer bleiben. Beispiel:

          Name: Herbert
          Strasse:
          Plz:
          Ort: Irgendwo

          Jetzt komme ich halt mit der "id_kunde" nicht mehr weiter.
          Daher meine Überlegung die zusätzliche Tabelle "bestelluser"

          bestellid,adresse1,adresse2,adresse3,adresse4,adresse5
          ----------------------------------------------------------

          Die adress Felder sind als varchar(200) angelegt. Ich denke wenn es hier "Leereinträge" gibt (Leerstring) dürfte das nicht sooo schlimm sein da kein Speicher verbraucht wird?

          viele Grüße
          Werner

          1. Hello Werner,

            Wenn ich nur feste, dauerhafte Kunden hätte, wäre das so ok. Aber es handelt sich halt um kein echtes, richtiges Bestellsystem mit Waren.

            Also wird gar nichts versandt?

            Wozu dann der Aufwand?

            Liebe Grüße aus dem schönen Oberharz

            Tom vom Berg

            --
             ☻_
            /▌
            / \ Nur selber lernen macht schlau
            http://bikers-lodge.com
            1. Hallo Tom,

              Also wird gar nichts versandt?

              Doch, es sind nur keine echten Waren sondern Dateien und Dokumente.
              Der Ablauf ist jedoch wie eine Art Bestellsystem.

              viele Grüße
              Werner

  2. Hi,

    Dann gibt es eine Tabelle "tabBestellArtikel"

    artikel, bestellid

    Die Frage ist nun ob man für die Tabelle "tabBestellArtikel" noch eine zusätzliche "Auto_increment" Spalte machen sollte?

    auto_increment-Spalten nutzt man idR., um auf jeden Fall ein Kriterium zu haben, um einen Datensatz absolut eindeutig zu identifizieren. (Damit man bspw. sicher sein kann, beim Updaten/Löschen auch wirklich nur die beabsichtigten Datensätze zu erwischen.)

    Wenn bei dir aber die Kombination von Artikelnummer und Bestellungs-Id eindeutig ist (und du das auch über einen kombinierten PRIMARY Key oder UNIQUE Index sicherstellst), dann reicht die zur eindeutigen Identifizierung des Datensatzes auch aus.

    MfG ChrisB

    --
    RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
    1. Hello,

      Wenn bei dir aber die Kombination von Artikelnummer und Bestellungs-Id eindeutig ist (und du das auch über einen kombinierten PRIMARY Key oder UNIQUE Index sicherstellst), dann reicht die zur eindeutigen Identifizierung des Datensatzes auch aus.

      Da irrt der Bastler ;-)

      Was Werner hier vorzuhaben scheint, ist die Erstellung eines Bestellsystems (als Bestandteil einer Warenwirtschaft (nebst Faktura?))

      Dazu gehören auch beim Minimalsystem bestimmte Stammdaten-Tabellen:

      Kunde
      (warengruppe)
      Artikel

      und bestimmte Bewegungsdaten:

      Bestellung
      Bestellposition

      Die Bewegungsdateien bilden immer nur einen Snapshot aus der Artikel-Tabelle ab. Da können sich diverse Dinge ändern (Preis, Gebindegröße, Mengenpreise), sogar während der Durchführung eines Bestellvorgangs.

      Wenn man für ein kleines System bei den vier Tabellen bleiben will, sollte jede Tabelle ihre von den Daten unabhängige ID-Spalte haben.

      Es wäre also für die spätere Verarbeitung (Lieferschein, Rechnung, Führung eines Kundenkontos) durchaus richtig, der Tabelle Bestellposition auch eine eindeutige ID zu verpassen.

      Liebe Grüße aus dem schönen Oberharz

      Tom vom Berg

      --
       ☻_
      /▌
      / \ Nur selber lernen macht schlau
      http://bikers-lodge.com