Logisches Vorgehen bei MySQL Datenbank

  • hallo zsm,


    ich muss eine datenbank aufbauen die folgende punkte enthalten soll:


    1. Kunden-ID

    2. Kunde vorname

    3. Kunde nachname

    4. anzahl lizenzen

    5. lizenzschlüssel

    6. rechnungsnummer

    7. angebotsnummer

    8. aktiv / deaktiv

    9. techn. ansprechpartner

    10. kaufm. ansprechpartner

    11. rechnungsanschrift

    12. kundenanschrift

    13. kundennummer

    14. wartungsvertrag

    15. kommentare


    klar möchte ich nicht das ihr mir jetzt einen vorkaut aber wie geht man logisch vor, beim erstellen der datenbank?

    Klar sollte man nicht alles in eine tabelle packen aufgrund von redundanzen. Aber jeden einzelnen Punkt natürlich auch nicht in je eine einzelne Tabelle.

    Wie geht man bei der Überlegung am besten vor? wie muss ich vorgehen beim verknüpfen der tabellen und wie kann ich es bestimmen was am besten in eine tabelle zusammen kommt und was man trennen sollte?


    ich hoffe meine frage ist klar geworden vielen dank.


    thx

  • Bei den Infos sage ich mal diese simple Regel: alles was mehrfach vorkommen kann, kommt in eine eigene Tabelle:


    1. Kunden-ID mehrfach: nein

    2. Kunde vorname mehrfach: nein

    3. Kunde nachname mehrfach: nein

    4. anzahl lizenzen mehrfach: nein

    5. lizenzschlüssel mehrfach: eventuell

    6. rechnungsnummer mehrfach: eventuell

    7. angebotsnummer mehrfach: eventuell

    8. aktiv / deaktiv mehrfach: nein

    9. techn. ansprechpartner mehrfach: eventuell

    10. kaufm. ansprechpartner mehrfach: eventuell

    11. rechnungsanschrift mehrfach: nein

    12. kundenanschrift mehrfach: nein

    13. kundennummer mehrfach: nein

    14. wartungsvertrag mehrfach: eventuell

    15. kommentare mehrfach: ja


    Bei "eventuell" musst du wissen, ob es mehrere Daten geben kann, bei "ja" eigene Tabelle, bei "nein" alles in eine Tabelle, wobei auch da du es wissen musst

  • Yap, was m.scatello sagt.

    Im Prinzip kann man es ja schon lesen, ob es eine extra Tabelle geben wird.


    Z.B. "Kommentare" - Mehrzahl. Also viele :)


    Die erste Fragen sind aber immer:

    - wie schnell muss es fertig sein

    - wie viele Einträge werden erwartet


    Man könnte ja ein richtig schönes System aufbauen. Allerdings musste ich lernen, dass man in keine Zeit für schönen Code hat (weil es Dir keiner bezahlt :D ).


    Bsp:

    Ein Ansprechparter ist ein user.

    Er bekommt eine Rolle als Ansrechpartner.

    Er kann mehrere andere user als Kunden betreuen.

    Er kann mehrere Addressen haben.

    Er kann mehrere Telefonnummern haben.

    (...)


    Hier im Bsp wäre es schön, wenn man viele viele Detail-Tabellen hätte.

    Code
    1. tbl user                main table
    2. tbl user_role           1:n (user:user_role)
    3. tbl user_address        1:n
    4. tbl user_telefon        1:n

    Usw.


    Muss es also schnell gehen, dann bau Dir erstmal ein funktionierendes System.

    Aber immer im Hinterkopf, dass Du hier und da module relativ einfach erweitrn kannst.


    Beisp.: addresse erstmal direkt in die user table.

    Beim Laden des users dann aber immer eine Methode (function|class|model|helper) benutzen.

    Sollte man dann doch mehrere Addressen benötigen,

    dann kann man die neue Tabelle erstellen, die Daten rüber kopieren, und die Methode zum Laden erweitern (zB per JOIN).

  • danke für die antwort, habe jetzt eigentlich verstanden worum es geht aber ich denke dann müsste man paar sachen von dir ändern:

    zb hast du gesagt nur einen kunde vorname und einen kunde nachname

    aber es können doch zwei kunden die gleichen vor und nachnamen haben. jedoch gibt es nur eine kunden-id zu einem vor UND nachnamen

    aber ich verstehe worauf die hinaus willst. muss dann halt nur gut überlegen. aber danke

    Yap, was m.scatello sagt.

    Im Prinzip kann man es ja schon lesen, ob es eine extra Tabelle geben wird.


    Z.B. "Kommentare" - Mehrzahl. Also viele :)

    ......

    danke auch für deine antwort.

    im prinzip habe ich schon bissl zeit, denn ich bin "nur" praktikant und will es vernünftig machen, da dies mein projekt für die IHK ist.

  • mit "mehrfach: nein" meinte er,

    dass es für diesen einen user (mit ID x) keine Mehrfachdaten gibt. Also kein Details Table.


    im prinzip habe ich schon bissl zeit, denn ich bin "nur" praktikant und will es vernünftig machen, da dies mein projekt für die IHK ist.

    Na dann ordentlich =)

    Und Du kannst es ja Stück für Stück durchgehen.





    Würde erstal mit dem (logisch) user tbl anfangen,

    dann den address tbl.

    Dann hast Du schon mal ne Basis.

    user.increment (Kundennummer) ist ein spannendes Thema. aber Dazu findest Du recht viel im Netz =)


    Wichtig: egal wie viele Tabellen Du am Ende nutzt - INSERT eines neuen Nutzers (und "größere" UPDATEs) immer per TRANSACTION.

  • Ein Increment Script|Tool schreiben ist spannend, weil Du zB beachten musst,

    dass es gleichzeitige Zugriffe auf die Datenbank gibt.


    Mal angenommen Du hast eine normale Website mit Kunden.

    Jeder Kunde bekommt eine Kundennummer - in etwa: T-0001  (T hat hier keine Bedeutung. Soll nur zeigen, dass es einen Prefix geben können muss).


    Zwei Kd kommen gleichzeitig auf Deine Seite und registrieren sich.

    Nun musste Du sicherstellen, dass die Nummer einmalig bleibt.

    Dass machst Du als erstes hart über einen uidx (unique index) in der Datenbank.

    Es ist jetzt also schon mal nicht möglich, die gleiche Nummer "ausversehen" zu speichern.


    Wie stellst Du nun sicher, dass Du eine eeinzigartige Nummer bekommst?

    Ich gehe im Bsp nur von einer Nummer aus - ohne Prefix.

    Code
    1. // pseudocode
    2. // kunde A registriert sich:
    3. lastNumber = SELECT MAX(`number`) FROM `increment`; // die größte (zu letzt erstellte) nummber laden
    4. newNumber = lastNumber + 1; // eine neue nummer für den neuen kd
    5. // neue nummer für den kd einfügen
    6. INSERT INTO `increment` SET `number` = :new_number; // usw - zB per PHP PDO ...


    Soweit ... easy?

    Nope.

    Der gleiche Ablauf jetzt mit einem dicken fetten Haken:

    Mal angenommen Du hattest als letzte Nummer die 5 in der db,

    dann würdest Du für Kd A auf 6 hochzählen.

    Da aber - bevor Du Kd A gespeichert hast - Kd B sich auch registrieren will,

    bekommst Du für Kd B auch die 6.


    Ich hoffe, ich konnte es einigermaßen verdeutlichen.


    Was kann man da machen?

    Antwort: Die Datenbank hält die Nummer, also zählt die Datenbank die Nummer hoch. Nicht etwa das PHP Script.


    Bsp:

    Per PHP erste Query abschicken, um die Nummer zu erhöhen

    und die neue Nummer in eine Session Variable ablegen (denn UPDATE gibt uns keine Daten zurück):

    SQL
    1. UPDATE `incremnt` SET `number` = @next_session := `number` + 1;

    Jetzt eine zweite Abfrage, um die Session Variable zu lesen:

    SQL
    1. SELECT @next_session;


    Ich hab das Problem (umfangreicher natürlich) für meinen Arbeitgeber gelöst.

    Kann aber den fertigen Code nicht posten (klar).


    Aber aus der docu:


    Das war jetzt nur ein einfaches Beispiel.

    Wenn es nun aber noch mehrere Nummern (increments) geben soll - zB für user, invoice, creditmemo, ... - dann brauchst Du:

    - einen Prefix (zB O-xxx für Order, I-xxx für Invoice, ...)

    - im besten Fall eine Tabelle für alle increments

    - options wie zB Länge


    So hättest Du dann eine Tabelle für mehrere increments.

    Code
    1. beispiele:
    2. O-00054         prefix: O-    "current" or last_increment": 54    length: 7
    3. C-0421          prefix: C- "current" or last_increment": 421 length: 6
    4. K-0000004631    prefix: K- "current" or last_increment": 4631 length: 12


    Spannend =)

    ----


    Über Transactions: was @m.scatello meinte.

    Was in dem Link aber per SQL gemacht wird (START TRANSACTION, COMMIT und ROLLBACK) wird dann aber besser per PHP gesteuert.

    Siehe: https://www.php.net/manual/de/pdo.begintransaction.php

    Die Befehle wie zB "START TRANSACTION" übernimmt dann PDO für Dich.

  • Öhm... unique schön und gut, aber das DBMS kann per LOCK selbst dafür sorgen, dass keine zwei Datensätze konkurrierend zueinander gleichzeitig geschrieben werden. Wenn ich dann zusätzlich zu der Kundennummer, die unique sein soll, eine auto_increment ID mitlaufen lasse, habe ich an allen Enden null Probleme.


    Transactions sind ein anderes Thema, aber natürlich absolut zu empfehlen.