Chrisi: DB values trennen ?

Hallo zusammen,

ich sitze gerade an einem DB (MySQL 4.1, wobei die DB möglichst unabhängig sein sollte) Design für eine typische Anbieter Datenbank, kurzes Beispiel:

Tabellen ->

provider: PROVIDER_ID,name,email,etc...
   provider_product: PRODUCT_ID,PROVIDER_ID,VALUE_ID,value
   provider_product_values: VALUE_ID,value

Die Tabelle "provider" enthält die Standartdaten zum Anbieter, "provider_product" enthält die Angaben zu den Produkten die der Anbieter eingetragen hat und "provider_product_values" soll die values enthalten die unter "provider_product.value" gespeichert werden dürfen ;-)

Dazu sei gesagt: "provider" enthält immer einen Datensatz, "provider_product" kann unendlich viele enthalten.

Die Produktvalues unterscheiden sich in Ihrer Form, mal wird nur eine 1 oder 0 benötigt, aber manchmal werden auch Werte oder Worte gebraucht wenn ich z.B. die Bandbreite (56,128,768,1024,etc...) von einem Provider erfassen möchte und im schlimmsten Fall kann ein Provider auch mehr als einen Value auswählen und diesen unter "provider_product.value" abspeichern.

Nun meine Frage an euch: Macht es Sinn bei meinem Vorhaben dieses 3 Tabellen Design anzuwenden ?

Normalerweise sieht so eine Datenbank in 1:n ja etwa so aus:

provider: PID ...
provider_products: id,PID,productname,bandwidth,traffic,email, etc ... Das ganze dann mit ENUM und SET gespickt, wobei ich die beiden Splatentypen irgendwie nicht leiden kann und damit inkompatobel zu anderen Datenbanken werde.

Ich habe mir gedacht ich verzichte auf eine feste Tabelle in der die Produkte erfasst werden, weil nicht jeder Anbieter immer alle Values zu den Produkten benötigt. Dazu kommt das ich gerne die Values vom Design trennen möchte weil dort teilweise Wörter drinnen stehen die ich später evtl. auslagern möchte um die Sprache von den Inhalten der Datenbank ein wenig abzugrenzen.

Genial ist das ich einfach neue Value hinufügen könnte, wenn es z.B. eine Änderung oder eine Erweiterung in der Datenbank gibt würde dies recht schnell und sauber klappen.

Ich sehe aber ein Problem in der Speicherbelegung für die Tabelle "provider_products" im Feld "value" da dort völlig unterschiedliche Werte erfasst werden und ich somit keine eindeutigen Spaltenwerte (smallint,int,varchar,text etc...) festlegen könnte und ich mich wohl oder über für ein varchar entscheiden müsste, was bei manchen Feldern ein große Verschendung wäre und auch die Performance bei Anfragen an die DB sicher drücken würde.

Was haltet ihr davon ? Macht meine Idee überhaupt sinn ? Wie würdet Ihr hier vorgehen ?

Danke für jeden Tipp,

Chrisi

  1. Hi,

    Die Tabelle "provider" enthält die Standartdaten zum Anbieter, "provider_product" enthält die Angaben zu den Produkten die der Anbieter eingetragen hat und "provider_product_values" soll die values enthalten die unter "provider_product.value" gespeichert werden dürfen ;-)
    [...]
    Nun meine Frage an euch: Macht es Sinn bei meinem Vorhaben dieses 3 Tabellen Design anzuwenden ?

    ja. Allerdings ist mir die Verwaltungsfunktionalitaet "zulaessige Werte" ein wenig unklar. (Ist doch moeglicherweise unguenstig aufwendig zu verwalten, oder? Ist es denn wirklich erforderlich.)

    Ich habe mir gedacht ich verzichte auf eine feste Tabelle in der die Produkte erfasst werden, weil nicht jeder Anbieter immer alle Values zu den Produkten benötigt. Dazu kommt das ich gerne die Values vom Design trennen möchte weil dort teilweise Wörter drinnen stehen die ich später evtl. auslagern möchte um die Sprache von den Inhalten der Datenbank ein wenig abzugrenzen.

    Ich bin nicht sicher, obs Sinn macht. Ist ein heisses Eisen, wegen Komplexitaet und so...

    Gruss,
    Ludger

    1. Hi,

      ja. Allerdings ist mir die Verwaltungsfunktionalitaet "zulaessige Werte" ein wenig unklar.

      Die Tabelle soll nur die Values enthalten die in der Tabelle Produkte einer Produkteigenschaft zugeordnet werden dürfen. Ich nehme quasie die einzelnen Werte aus einem ENUM() oder SET() und speicher diese in der value Tabelle. Ob es Sinn macht ist wieder eine andere Sache, ich werde da wohl die Values ganz aus der DB nehmen und extern Speichern (XML oder im Script) ...

      (Ist doch moeglicherweise unguenstig aufwendig zu verwalten, oder? Ist es denn wirklich erforderlich.)

      Naja, ohne Fleiß kein Preis :-) Spaß, ich habe mir nur angewöhnt vorher alle Möglichkeiten zu prüfen um Momente zu vermeiden in denen ich mir wochenlange Arbeit anschaue und festelle das schon im DB Design einiges daneben ist.

      Aber die gesamte Verwaltung wird sicher recht schwierig, jetzt gibt es etwa 2000 Anbieter in der DB, diese haben wiederum jeweils ca. 10 Angebote. Jedes Angebot kann ca. 20 Eigenschaften haben, was bedeutet das die Tabelle mit den Produkten doch recht viele einzelne Datensätze enthält.

      Also via phpMyAdmin kann man da nicht mehr viel zuordnen, da muss dann schon eine Oberfläche gebastellt werden.

      Danke für deine Hilfe, Chrisi

      1. Hi,

        Die Tabelle soll nur die Values enthalten die in der Tabelle Produkte einer Produkteigenschaft zugeordnet werden dürfen. Ich nehme quasie die einzelnen Werte aus einem ENUM() oder SET() und speicher diese in der value Tabelle. Ob es Sinn macht ist wieder eine andere Sache,

        es macht Sinn - diese Tabelle ist die eine Seite der Kreuztabelle, von der ich sprach. Die Lösung hat den wunderbaren Vorteil, dass bei einer Änderung der Daten nicht das Schema angefasst werden muss.

        ich werde da wohl die Values ganz aus der DB nehmen und extern Speichern (XML oder im Script) ...

        Wie gesagt, das macht Dir weit mehr Arbeit, als es nutzen kann.

        Naja, ohne Fleiß kein Preis :-) Spaß, ich habe mir nur angewöhnt vorher alle Möglichkeiten zu prüfen um Momente zu vermeiden in denen ich mir wochenlange Arbeit anschaue und festelle das schon im DB Design einiges daneben ist.

        Das zeugt von Erfahrung. Profitiere von unserer: Nimm eine Kreuztabelle. Atomare Daten in _einer_ unveränderlichen Datenquelle.

        Aber die gesamte Verwaltung wird sicher recht schwierig,

        Nö. Am Anfang mag es etwas umständlich erscheinen, und vielleicht brauchst Du dafür auch erst mal mehr Codezeilen als für eine andere Lösung. Aber _es bleibt bei diesen Codezeilen_, während Du bei anderen Lösungen für jede weitere (völlig normale) Form der Nutzung etwas Neues implementieren musst. Und zur Nutzung zähle ich auch die Veränderungen, die das System im Laufe der Zeit erfahren wird. Kreuztabellen sind eine Standard-Anwendung von Datenbanken.

        jetzt gibt es etwa 2000 Anbieter in der DB, diese haben wiederum jeweils ca. 10 Angebote. Jedes Angebot kann ca. 20 Eigenschaften haben, was bedeutet das die Tabelle mit den Produkten doch recht viele einzelne Datensätze enthält.

        Das ist kein Problem - genau dafür sind Datenbanken da. Wähle sinnvolle Indizes.

        Also via phpMyAdmin kann man da nicht mehr viel zuordnen, da muss dann schon eine Oberfläche gebastellt werden.

        Fingerübung ;-) Diese Oberfläche wird die Wartbarkeit des Systems deutlich erhöhen.

        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,

    "provider_product_values" soll die values enthalten die unter "provider_product.value" gespeichert werden dürfen ;-)

    der Rest klingt okay, aber das hier habe ich nicht verstanden.

    im schlimmsten Fall kann ein Provider auch mehr als einen Value auswählen und diesen unter "provider_product.value" abspeichern.

    Nein.

    Nun meine Frage an euch: Macht es Sinn bei meinem Vorhaben dieses 3 Tabellen Design anzuwenden ?

    Nein. Ein Datum ist als atomar anzusehen. Wenn ein (1) Datensatz eine Anzahl (n) Werte gleicher Art besitzt, so ist dies eine 1:n-Beziehung.

    Normalerweise sieht so eine Datenbank in 1:n ja etwa so aus:

    Muss nicht. Gerade wenn die Menge der Produkte variabel ist, ist das sogar ein extrem ungünstiger, wenn nicht gar sträflicher Ansatz. Dein Vorhaben schreit nach einer Kreuztabelle.

    Ich sehe aber ein Problem in der Speicherbelegung für die Tabelle "provider_products" im Feld "value" da dort völlig unterschiedliche Werte erfasst werden und ich somit keine eindeutigen Spaltenwerte (smallint,int,varchar,text etc...) festlegen könnte

    Für dieses Problem gibt es leider keine Standardlösung. Du könntest zusätzlich zu den Produktbezeichnungen den Datentyp speichern, der dann i.d.R. erst außerhalb der Datenbank Beachtung finden dürfte.

    und ich mich wohl oder über für ein varchar entscheiden müsste, was bei manchen Feldern ein große Verschendung wäre

    Sooo groß ist die Verschwendung bei einem VARCHAR nun auch nicht.

    Was haltet ihr davon ? Macht meine Idee überhaupt sinn ? Wie würdet Ihr hier vorgehen ?

    Der Ansatz erscheint mir gut, nur die Values solltest Du auslagern.

    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,

      1:n ja etwa so aus:

      Muss nicht. Gerade wenn die Menge der Produkte variabel ist, ist das sogar ein extrem ungünstiger, wenn nicht gar sträflicher Ansatz. Dein Vorhaben schreit nach einer Kreuztabelle.

      Wie schaut so eine Kreuztabelle aus ? Ich habe beim googlen diesen Beitrag gefunden: http://lists.mushaake.org/pipermail/php/Week-of-Mon-20040301/006910.html

      Kannst du mir da vieleicht ein minimales Beispiel für mein Vorhaben aufzeigen, oder hast du vieleicht einen Link wo ich genaueres nachlesen kann ?

      Der Ansatz erscheint mir gut, nur die Values solltest Du auslagern.

      Japp, ich denke die Values werde ich wohl oder übel ganz aus der DB abziehen und extern in einer XML Datei oder einfach in einer Variable unterbringen. Speziell in Hinsicht auf spätere Sprachunabhängigkeit und um flexibel zu sein wenn es darum geht eine neue Option für die Produkte einzuführen oder einfach zu einer Option einen weiteren Value zuzufügen.

      Danke für deine Tipps, Chrisi ..

      1. Hi,

        Wie schaut so eine Kreuztabelle aus ?

        Du bildest eine "many to many"-bezeihung zwischen zwei Entitaeten (Datenbanktabellen; z.B. Mensch und Vornamen) nach. Dazu beneotigt man neben den Tabellen A und B eine dritte Tabelle C fuer die Beziehungen. Da wird auch allgemein als "n:m"-Beziehung bearbeitet.

        Japp, ich denke die Values werde ich wohl oder übel ganz aus der DB abziehen und extern in einer XML Datei oder einfach in einer Variable unterbringen.

        Wuerg.   :-)

        Speziell in Hinsicht auf spätere Sprachunabhängigkeit und um flexibel zu sein wenn es darum geht eine neue Option für die Produkte einzuführen oder einfach zu einer Option einen weiteren Value zuzufügen.

        "Flexibel sein" hoert sich gut an, aber "einfach sein" ist besser...
        (Vgl. Kirchhof und Merz und so)

        Danke für deine Tipps, Chrisi ..

        Vergiss nicht dem anderen Meister zu danken.

        Gruss,
        Ludger

        1. Hi,

          Values .. XML Datei oder einfach in einer Variable unterbringen.

          Wuerg.   :-)

          :-))) So schlimm ? Angenommen ich reduziere mein 3 Tabellen Design auf 2, also provider u. products, so hätte ich in der DB wirklich nurnoch reine Daten. Jede Abhängigkeit für Formulare die Später zum Abfragen und Eintragen der Daten erstellt werden sind damit fast unabhängig von der Datenbank, weil ja alle Values irgendwo extern lagern.

          Ich schätze die einfachste Variante ist die 1:n Beziehung, aber die mag Cheatah nicht :-)

          Wie würdest du hier vorgehen ?

          Viele Grüße & danke, Chrisi

          1. Hi,

            Values .. XML Datei oder einfach in einer Variable unterbringen.

            Wuerg.   :-)

            :-))) So schlimm ?

            sehr schlimm.

            Angenommen ich reduziere mein 3 Tabellen Design auf 2, also provider u. products, so hätte ich in der DB wirklich nurnoch reine Daten.

            Huestel.

            Jede Abhängigkeit für Formulare die Später zum Abfragen und Eintragen der Daten erstellt werden sind damit fast unabhängig von der Datenbank, weil ja alle Values irgendwo extern lagern.

            Das laeuft allgemein unter Validierung. In aller Regel stellt man das RDBMS (falls vorhanden) per geeigneter constraints bspw. auf Datenfeldebene ein. Additiv dazu wird auf Front-End Ebene _moeglicherweise_ Code ausgefuehrt, der dasselbe noch einmal leistet. Letzteres ist vermutlich Mist.

            Also: Daten gehoeren ins Datenverwaltungssystem, von zusaetzlicher Verteilung von Daten auf andere Datenhaltungen (Du kannst auch Code als Datenhaltung betrachten) ist aus Gruenden der anzustrebenden Einfachheit abzuraten.

            Ich schätze die einfachste Variante ist die 1:n Beziehung, aber die mag Cheatah nicht :-)

            Wie würdest du hier vorgehen ?

            Wenns "n:m" ist, dann "n:m", sonst vielleicht "1:n" oder so.

            Ueberlege doch einfach wie sich die Objekte in der Realitaet so verhalten, das baue "in IT" nach.

            Gruss,
            Ludger

          2. Hi,

            :-))) So schlimm ? Angenommen ich reduziere mein 3 Tabellen Design auf 2, also provider u. products, so hätte ich in der DB wirklich nurnoch reine Daten.

            unvollständige. Du hättest Deine Datenbasis aufgespalten in verschiedene Quellen, ohne einen Vorteil zu erzielen, aber unter Verlust der referenziellen Integrität.

            Jede Abhängigkeit für Formulare die Später zum Abfragen und Eintragen der Daten erstellt werden sind damit fast unabhängig von der Datenbank, weil ja alle Values irgendwo extern lagern.

            Du kannst ein DBMS nehmen, oder Du kannst eine XML-Speicherung nehmen. Beides zusammen ist the worst of both worlds.

            Ich schätze die einfachste Variante ist die 1:n Beziehung, aber die mag Cheatah nicht :-)

            Doch, wenn es wirklich eine solche ist. Mehrere Werte in einem Feld zu speichern - also _einen_ Wert daraus zu machen - ist Unfug. Ich hab's probiert, das klappt nicht.

            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,

              Doch, wenn es wirklich eine solche ist. Mehrere Werte in einem Feld zu speichern - also _einen_ Wert daraus zu machen - ist Unfug. Ich hab's probiert, das klappt nicht.

              :-)
              ich habs auch probiert. Manchmal klappt das auch und alle sind bis ans Ende ihrer Zeiten happy. Das Problem ist nur, dass man vorher nicht weiss, wann es klappen wird. Und wenns nicht klappt, dann ...

              Gruss,
              Ludger

              1. Hi,

                ich habs auch probiert. Manchmal klappt das auch und alle sind bis ans Ende ihrer Zeiten happy. Das Problem ist nur, dass man vorher nicht weiss, wann es klappen wird. Und wenns nicht klappt, dann ...

                dem kann ich eigentlich nur noch Murphy hinzufügen :-)

                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,

                  ich habs auch probiert. Manchmal klappt das auch und alle sind bis ans Ende ihrer Zeiten happy. Das Problem ist nur, dass man vorher nicht weiss, wann es klappen wird. Und wenns nicht klappt, dann ...

                  dem kann ich eigentlich nur noch Murphy hinzufügen :-)

                  es gibt da ganz lustige Sachen. Bspw. behauptet auf einmal eine Abteilungsleiterin "EDV", dass pro Vertrag nur vier Vertragsgegenstaende erfasst und verwaltet werden koennen. Und das dann mit einer Selbstverstaendlichkeit, die so manchen blass werden laesst. Aufgewuerzt oft noch mit einem "Herr X, Sie verstehen das nicht.".

                  Oder es kommt raus, dass bestimmte Daten(saetze) nicht geloescht werden duerfen, weil (erlaeuterndes esoterisches Geschwafel, leider mit ernsthaftem Hintergrund - "Metadaten in den Daten" bspw.) "es nicht geht".

                  Haltet die Frauen aus dem Bereich des Datendesigns raus, Front-End ja, frickeln ja, proggen ja, Fuehrungspositionen eingeschraenkt ja, aber bitte bitte kein Datendesign!

                  Gruss,
                  Ludger

  3. yo,

    ich arbeite zur zeit an einem ähnlichen problem. bei mir ist es eine inventarisierung und nicht jedes inventar hat auch die gleichen attribute oder aber ich will ein attribut mehrmals einem gegenstand zuordnen, wie zum beispiel das ein rechner mehrere speicherriegel haben kann aber nicht muss. bei dir ist es so, dass nicht jeder provider auch die gleichen leistungen anbietet.

    nun gibt es meiner meinung nach zwei ansätze, die du auch schon beide erwähnt hast. die erste variante ist es über zwei tabellen aufzubauen. die erste tabelle gibt deine provider und die zweite gibt ein komplettes abbild aller möglichen eigenschaften eines products wieder. der vorteil liegt darin, dass man sich erst einmal eine tabelle spart, das ist immer gut. zum anderen vereinfacht es das datenlayout. der nachteil besteht darin, dass man recht unflexibel ist und auch eigenschaften eines produktes mit führt, die ein provider gar nicht anbietet.

    die zweite möglichkeit ist eben es über drei tabellen zu lösen. hinzu kommt die tabelle der "individuellen" eigenschaften der produkte. im gunde genommen sind es dann vier tabellen, da man noch eine beziehungstabelle einführen muss.

    provider: id, name, email, etc.
    produkte: id, provider_id, prodkutname, etc.
    Eigenschaften: id, eigenschaft

    dies wären die drei entitäten, wobei zwischen produkte und eigenschaften es sich um eine n:m beziehung handelt, sprich noch eine beziehungstabelle dazu kommt. dort steht dann auch der wert der entsprechenden eigenschaft. falls die gleiche eigenschaft einem entsprechenden produkt nur einmal zugeordnet werden kann, kannst du die id auch weglassen und die jeweiligen fremdschlüssel in der beziehungstabelle als primary key nehmen.

    produkte_eigenschaften: id, produkte_id, eigenschaften_id, value

    welche der beiden methoden nun die bessere ist, dass hängt stark davon ab, wie "dynamisch" deine eigenschaften der provider sind. wenn möglich würde ich das design über zwei tabellen vorziehen, frei nach dem kis motto. es ist einfacher damit zu arbeiten, auch wenn nicht jedes produkt jede eigenschaft besitzt.
    wenn sie die eigenschaften der provider aber "zu sehr" unterscheiden, dann nimm den zweiten ansatz.

    Ilja

    1. Hi,

      , frei nach dem kis motto.

      KISS heisst das. Und KISS steht nicht fuer Denormalisierung.

      Gruss,
      Ludger

      1. yo,

        KISS heisst das. Und KISS steht nicht fuer Denormalisierung.

        och, ich sage immer, wer normalisieren will, der muss auch lernen, wie man denormalisiert. ist doch was schönes.....

        Ilja

        1. Hi,

          KISS heisst das. Und KISS steht nicht fuer Denormalisierung.

          och, ich sage immer, wer normalisieren will, der muss auch lernen, wie man denormalisiert. ist doch was schönes.....

          :-)
          denormalisieren konnte ich schon immer, meine Nachbarn auch.

          Weisst Du warum ich so fest davon ueberzeugt bin, dass man fast immer, also, wenn nicht wirklich ernsthafte Gruende dagegen sprechen, normalisieren sollte, also im Sinne von in der Realitaet stehende Objekte und deren Beziehungen "1:1" nachbauen?

          Weil - man lausche - dann nicht immer wieder aufs neue darueber nachgedacht werden muss (und auch nicht diskutiert werden muss) - ob mans diesmal "richtig" macht oder ob es (in Deinem Sinne) dem kis-Prinzip folgend implementiert werden darf.

          Im richtigen Moment "kis" zu fahren ist eines der schwersten Sachen ueberhaupt.

          Gruss,
          Ludger