Peter Thomassen: Abbildung von Webhosting-Angeboten

Hallo Forum!

Ich entwickle gerade eine Datenbankstruktur zur Wiederspiegelung von
Webhostingverträgen, die sich aus verschiedenen Teilen zusammensetzen.
Der Kunde soll die Teile einzeln bestellen können.

Dazu gibt's (vereinfacht) folgende Tabelle:

domains:
id tld fee
1 de 0.99
2 com 1.29

id ist die Identifikationsnummer eines Datensatzes, tld die Endung
der Domain, fee die Monatsgebühr. Man kann nun also DE-Domains
bestellen, indem man einen Vertrag vom Typ domains(1) abschließt.

Außerdem existiert noch diese Tabelle:

webspace:
id MB fee
1 100 0.99
2 200 1.49

Man kann also weiterhin 200 MB Webspace bestellen, indem man
einen Vertrag für webspace(2) abschließt.

Das ganze soll nun auch bündelbar sein, damit man fertige Pakete
anbieten kann:

bundles_hosting:
id domains webspace fee
1 1 1  1.49
2 1 2  1.99

Bedeutet, dass es ein Webhostingpaket 1 mit 1 DE-Domain und 100 MB
Webspace für EUR 1,49 im Monat sowie ein Paket 2 mit 1 DE-Domain,
aber 200 MB Webspace für EUR 1,99 im Monat gibt.

Wenn ich zwei DE-Domains und eine COM-Domain ins Paket integrieren
möchte, schreibe ich (domains muss eben TINYTEXT oder so sein):

bundles_hosting:
id domains webspace fee
3 1 1 2 1  3.49

So weit, so gut. Allerdings brauche ich die Möglichkeit, dass der
Kunde zwischen DE- und COM-Domains wählen kann. Wie kann man das in
der Datenbank abbilden? Mir ist so etwas in den Sinn gekommen:

bundles_hosting:
id domains webspace fee
4 1||2 1  1.49

Das wäre dann ein Hostingpaket mit 100 MB Speicher und 1 DE- _oder_
1 COM-Domain. Aber irgendwie hab ich so das Gefühl, dass das unter
Umständen zu unflexibel wird. Wie würdet ihr das machen?

Danke für eure Hilfe!
Peter

  1. *argh* Tabulatoren werden nicht richtig abgebildet - schaut bitte
    ins Antwortfeld, im Zitat stehen sie dann richtig. Danke!

    Peter^

  2. Huhu Peter

    domains:
    id tld fee
    1 de 0.99
    2 com 1.29

    webspace:
    id MB fee
    1 100 0.99
    2 200 1.49

    Also die Bundle-DB könnte auch so aussehen:

    id bid foreign_key foreign_db

    1;1;1;domains
    2;1;2;webspace

    3;2;1;domains
    4;2;1;webspace

    5;3;1;domains
    6;3;2;domains
    7;3;2;webspace

    bid ist dabei die Bundle-ID

    obiges wäre dann wie folgt zu verstehn:

    zu Bundle 1 gehört
    1 de-Domain
    200 MB-Webspace

    zu Bundle 2 gehört
    1 de-Domain
    100 MB-Webspace

    zu Bundle 3 gehört
    1 de-Domain
    1 com- domain
    200 MB-Webspace

    Den Endpreis musst Du Dir dann per Join zusammendrösseln.

    Um so etwas wie de oder com abzubilden
    wäre es denkbar dafür einen neuen Eintrag in der
    domains-Tabelle zu machen
    z.B.

    domains:
    id tld fee
    1 de 0.99
    2 com 1.29
    3       de oder com .50

    Dann könnte ein Bundle so aussehen

    8;4;1;domains
    9;4;3;domains
    10;4;2;webspace

    d.h. einaml den Preis für de ODER com und eine zusätzliche
    de-Domain + 200 MB Webspace

    so ungefähr jedenfalls. Die Idee mehrere Angaben in einer DB-Spalte mit Hilfe von Delimitern zusammenzukloppen solltest Du jedenfalls fallen lassen.

    Viele Grüße

    lulu

    --
    bythewaythewebsuxgoofflineandenjoytheday
    1. Huhu Peter

      Hu-lu lu-hu! :-)

      Also die Bundle-DB könnte auch so aussehen:

      id bid foreign_key foreign_db

      1;1;1;domains
      2;1;2;webspace

      3;2;1;domains
      4;2;1;webspace

      5;3;1;domains
      6;3;2;domains
      7;3;2;webspace

      bid ist dabei die Bundle-ID

      Verstanden. Der Vorteil liegt wohl darin, dass ich die Trennzeichen
      nicht mehr brauche.

      Der Nachteil liegt darin, dass ich auf Anhieb
      nicht weiß, wie man bei Angebotsänderungen nachvollziehen kann, wann
      was aktuell war (beim anderen Ansatz würde ich dafür einfach eine
      Spalte timestamp verwenden).

      Sollte man dann noch x:y:<timestamp>:timestamp einfügen - oder wie?

      Außerdem ist der Preis für ein Paket anders als der addierte seiner
      einzelnen Komponenten - x:y:a:fee mit a als Preis? Dann müsste Spalte
      3 auf einmal FLOAT sein ... Des weiteren sollte es eine Spalte name
      geben, deren Felder die Produktbezeichnungen enthalten. x:y:name:name?
      Dann wäre Spalte 3 ein String ...

      domains:
      id tld fee
      1 de 0.99
      2 com 1.29
      3       de oder com .50

      In Wirklichkeit ist tld eine Enumeration, da COM, NET, ORG dasselbe
      kosten. Oder würdest Du das auch wieder anders machen, d.h. für jede
      Domainendung einen Datensatz anlegen und tld wirklich zum String
      machen, mit den Wert de || com für die Wahlmöglichkeit zwischen DE und
      COM verwenden?

      [...] Die Idee mehrere Angaben in einer DB-Spalte mit Hilfe von Delimitern zusammenzukloppen solltest Du jedenfalls fallen lassen.

      Stimmt, aber irgendwie geht das auch nicht, wie ich hoffentlich
      einigermaßen verständlich beschrieben habe ...

      Danke für deine Hilfe!
      Peter

      1. Moin!

        Verstanden. Der Vorteil liegt wohl darin, dass ich die Trennzeichen
        nicht mehr brauche.

        Genau. Du kannst dadurch mehr Fragen von der Datenbank beantworten lassen, bzw. die Beantwortung ist wesentlich unaufwendiger, weil Indices zum Zuge kommen können.

        Der Nachteil liegt darin, dass ich auf Anhieb
        nicht weiß, wie man bei Angebotsänderungen nachvollziehen kann, wann
        was aktuell war (beim anderen Ansatz würde ich dafür einfach eine
        Spalte timestamp verwenden).

        Sollte man dann noch x:y:<timestamp>:timestamp einfügen - oder wie?

        Willst du historische Daten speichern? Dann wird die Sache nochmal wesentlich komplizierter. Grundsätzlich gilt: Die Datenbank spiegelt den derzeit aktuellen Zustand wider.

        domains:
        id tld fee
        1 de 0.99
        2 com 1.29
        3       de oder com .50

        In Wirklichkeit ist tld eine Enumeration, da COM, NET, ORG dasselbe
        kosten. Oder würdest Du das auch wieder anders machen, d.h. für jede
        Domainendung einen Datensatz anlegen und tld wirklich zum String
        machen, mit den Wert de || com für die Wahlmöglichkeit zwischen DE und
        COM verwenden?

        Enumerationen? Oder Sets?

        Enumerationen sind grundsätzlich ja wie fest vordefinierte Strings zu behandeln. Da kann man eine gewisse große Anzahl von verwenden, aber jeweils immer nur einen einzigen.

        Sets hingegen sind zahlenmäßig begrenzt auf (bei MySQL) 64 Stück = 64 Bit. Es gibt aber mehr als 64 TLDs, also sorgst du an dieser Stelle unnötig für eine absehbare Begrenzung, die dich später ärgern wird.

        Mit Sets kannst du aber in der Tat elegant "com, net, org" in einen Datensatz packen, und auch "com oder de" läßt sich so abbilden - einfach alle TLDs in den Datensatz reinpacken, die erlaubt sind. Die Begrenzung der möglichen TLDs wirkt aber IMO zu stark negativ.

        - Sven Rautenberg

        --
        "Beim Stuff für's Web gibts kein Material, was sonst das Zeugs ist, aus dem die Sachen sind."
        (fastix®, 13. Oktober 2003, 02:26 Uhr -> </archiv/2003/10/60137/#m338340>)
        1. Hallo Sven!

          Verstanden. Der Vorteil liegt wohl darin, dass ich die Trennzeichen
          nicht mehr brauche.

          Genau. Du kannst dadurch mehr Fragen von der Datenbank beantworten lassen, bzw. die Beantwortung ist wesentlich unaufwendiger, weil Indices zum Zuge kommen können.

          Klärst Du mich mal kompakt über Indizes auf?

          Der Nachteil liegt darin, dass ich auf Anhieb
          nicht weiß, wie man bei Angebotsänderungen nachvollziehen kann, wann
          was aktuell war (beim anderen Ansatz würde ich dafür einfach eine
          Spalte timestamp verwenden).

          Sollte man dann noch x:y:<timestamp>:timestamp einfügen - oder wie?

          Willst du historische Daten speichern? Dann wird die Sache nochmal wesentlich komplizierter. Grundsätzlich gilt: Die Datenbank spiegelt den derzeit aktuellen Zustand wider.

          Weshalb? Ich würde eine Tabelle mit Timestamp zur Verknüpfung von
          Kundendatenbank und Angeboten erstellen, um Verträge zu beschreiben. Nun muss ich doch bei der Rechnungsstellung berücksichtigen, welches
          Angebot der Kunde damals wahrgenommen hat.

          In Wirklichkeit ist tld eine Enumeration, da COM, NET, ORG dasselbe
          kosten. Oder würdest Du das auch wieder anders machen, d.h. für jede
          Domainendung einen Datensatz anlegen und tld wirklich zum String
          machen, mit den Wert de || com für die Wahlmöglichkeit zwischen DE und
          COM verwenden?

          Enumerationen? Oder Sets?

          Sets, sorry.

          Sets hingegen sind zahlenmäßig begrenzt auf (bei MySQL) 64 Stück = 64 Bit. Es gibt aber mehr als 64 TLDs, also sorgst du an dieser Stelle unnötig für eine absehbare Begrenzung, die dich später ärgern wird.

          Mit Sets kannst du aber in der Tat elegant "com, net, org" in einen Datensatz packen, und auch "com oder de" läßt sich so abbilden - einfach alle TLDs in den Datensatz reinpacken, die erlaubt sind. Die Begrenzung der möglichen TLDs wirkt aber IMO zu stark negativ.

          Ich weiß, bloß ist mir nichts anderes eingefallen ... :-)

          Danke,
          Peter

          1. Huhu Peter

            Weshalb? Ich würde eine Tabelle mit Timestamp zur Verknüpfung von
            Kundendatenbank und Angeboten erstellen, um Verträge zu beschreiben. Nun muss ich doch bei der Rechnungsstellung berücksichtigen, welches
            Angebot der Kunde damals wahrgenommen hat.

            eine denkbare Variante wäre bei Preisänderungen
            einen neuen Datensatz zu erzeugen
            bsp.

            id feature preis
            12 ssl      2.50
            [...]
            27 ssl      3.00

            also Dein Kunde hat irgendwann etwas bestellt, dann speicherst Du
            zu der Bestellung die entsprechenden IDs (in diesem Fall die 12)

            jetzt ändert sich der Preis für z.B. "SSL"
            es wird ein neuer Datensatz mit dem neuen Preis erzeugt.
            Entsprechend wird in der Datenbanktabelle mit den Bundles
            die alte id 12 durch die neue 27 ersetzt.
            D.h. wenn eine neue Bestellung reinkommt wird der aktuelle Preis
            (also die id 27) genommen.

            In obigem Beispiel wäre es vermutlich auch sinnvoll die
            "features" ebenfalls in einer separaten Tabelle abzulegen.

            Viele Grüße

            lulu

            --
            bythewaythewebsuxgoofflineandenjoytheday
          2. Moin!

            Verstanden. Der Vorteil liegt wohl darin, dass ich die Trennzeichen
            nicht mehr brauche.

            Genau. Du kannst dadurch mehr Fragen von der Datenbank beantworten lassen, bzw. die Beantwortung ist wesentlich unaufwendiger, weil Indices zum Zuge kommen können.

            Klärst Du mich mal kompakt über Indizes auf?

            Ein Index ist eine schnelle Suchtabelle, in der die Datenbank sucht, welche Datensätze aufs Kriterium passen. Die Alternative zum Index wäre, jeden Datensatz tatsächlich einzulesen und auf Übereinstimmung zu prüfen. Sowas ist üblicherweise langsamer, als der Index.

            Wenn du die ODER-Verknüpfung für ".de oder .com" in die DB legst, und dann beispielsweise alle Bundles mit ".de-Domain" herausfinden willst, dann fallen in diese Abfrage sowohl "nur .de" als auch alle "oder"-Kombinationen.

            Mit einem Set kannst du sowas machen. Da sind Bits gesetzt, nach denen die DB einzeln suchen kann. Sie würde also in diesem Fall nur nach dem ".de"-Bit suchen. Und das könnte tatsächlich per Index funktionieren (wenn der Index das unterstützt).

            Wenn du die Domain-Angabe aber beispielsweise in einem Textfeld untergebracht hast, indem du "de" und "de||com" und "info||de||com||net||org" in einzelnen Datensätzen gespeichert hast, dann mußt du mit LIKE '%de%' suchen - und ein % am _Anfang_ des Suchstrings bedeutet: Full Table Scan. Kein Indexzugriff, die DB muß die gesamte DB einlesen und durchsuchen, um zu finden. Das ist schlecht.

            Natürlich hängt "schlecht" von der Größe der Tabelle ab. Kleine Tabellen sind trotzdem schnell durchsucht. Aber die Kombination mit anderen Tabellen machts. Du wirst mit Sicherheit JOINs benutzen, um die DB abzufragen. Und dabei helfen Indices enorm, Performance zu bekommen.

            Das Problem ist das "wahlweise" in der Geschichte. Das solltest du tatsächlich irgendwie anders auffangen. Es ist eklig.

            Willst du historische Daten speichern? Dann wird die Sache nochmal wesentlich komplizierter. Grundsätzlich gilt: Die Datenbank spiegelt den derzeit aktuellen Zustand wider.

            Weshalb? Ich würde eine Tabelle mit Timestamp zur Verknüpfung von
            Kundendatenbank und Angeboten erstellen, um Verträge zu beschreiben. Nun muss ich doch bei der Rechnungsstellung berücksichtigen, welches
            Angebot der Kunde damals wahrgenommen hat.

            Tja, aber was ist, wenn sich der Preis eines Artikels ändert. Sagen wir, die .de-Domain wird billiger. Für die _aktuellen_ Preise deiner _Angebote_ ist das relevant, also änderst du (mit Timestamp) den Datensatz ".de-Domain" im Preis.

            Dadurch berechnen sich möglicherweise alle definierten Bundles neu - zumindest kriegst du aber eine Liste ausgegeben, welche Bundles dieses Element enthalten und neu berechnet werden müßten.

            Was deine Kunden angeht: Die arbeiten nicht mit den aktuellen Artikelpreisen, sondern mit den vertraglich festgelegten Preisen. Dazu mußt du ohnehin den zum Vertragsabschluß festgelegten Preis irgendwo speichern.

            Du hast dabei eigentlich nur zwei Ansatzpunkte:
            1. Einfach.
            2. Umfangreich.

            1. Du hast für die aktuellen Angebote deine Tabelle mit den Artikeln, und für geschlossene Verträge (bei denen sich der Kunde ja beispielsweise auch für eine konkrete der Wahlweise-Domains entschieden hat) hast du eine zweite Tabelle, welche 1:1 den Vertragspreis mit dem Artikel in der Artikeltabelle verbindet. Somit hast du den damals gültigen Preis zusammen mit dem Artikel, welcher über ein Bundle zusammengefaßt ist.

            Besser allerdings wäre, wenn du Vertragsabschlüsse und Bundle-Angebote tabellenmäßig komplett trennst. Ein Vertrag ist vom Prinzip her zwar auch ein Bundle, aber er enthält konstante Preise, die sich nur bei bestimmten Anlässen ändern und grundsätzlich individuell gestaltet sind/sein können.

            Deshalb: Bundles, die in einen Vertrag münden, gehören zum Vertragsstichtag kopiert, damit der Preis gerettet wird, der gültig war.

            2. Umfangreich wäre, wenn du in der Artikelliste statt des Feldes für den aktuellen (und einzigen) Preis eine Tabelle 1:n verknüpfst. Diese Tabelle enthält:
            preistabelle:
            id  art_id   preis   gueltig_ab

            Auf diese Weise kannst du einem Artikel einen Preis zuordnen, der ab einem bestimmten Datum gültig ist, und durch einen neuen Eintrag mit einem späteren Gültigkeitsdatum geändert wird. Auch Preisänderungen für die Zukunft lassen sich auf diese Weise einpflegen.

            Die Datenbankabfrage wird dadurch aber keinesfalls einfacher. :)

            Damit kannst du aber auf jeden Fall den Preis feststellen, der für einen bestimmten Stichtag galt. Wenn du also das Vertragsschließungsdatum hast, kannst du die zu dem Zeitpunkt gültigen Preise feststellen. Um ein Preisupdate für den Kunden hinzukriegen, machst du einfach ein Datumsupdate.

            Wie du es hinkriegst, bei den verschiedenen Bundles und Einzelzukäufen den Überblick zu behalten, insbesondere, wenn das Bundle einen neuen Preis kriegt, der Einzelzukauf aber nicht, sei dir überlassen. Diese Aufgabe ist weit weg von "trivial". :)

            - Sven Rautenberg

            --
            "Beim Stuff für's Web gibts kein Material, was sonst das Zeugs ist, aus dem die Sachen sind."
            (fastix®, 13. Oktober 2003, 02:26 Uhr -> </archiv/2003/10/60137/#m338340>)
  3. Moin!

    Ich entwickle gerade eine Datenbankstruktur zur Wiederspiegelung von
    Webhostingverträgen, die sich aus verschiedenen Teilen zusammensetzen.
    Der Kunde soll die Teile einzeln bestellen können.

    Klingt kompliziert, ist es aber nicht.

    domains:
    id tld fee
    1 de 0.99
    2 com 1.29

    webspace:
    id MB fee
    1 100 0.99
    2 200 1.49

    bundles_hosting:
    id domains webspace fee
    1 1       1           1.49
    2 1       2           1.99

    bundles_hosting:
    id domains webspace fee
    3 1 1 2       1           3.49

    Das erscheint mir der falsche Ansatz zu sein.

    Im Prinzip kannst du deine Produktsammlung runterbrechen auf folgenden Zusammenhang:

    Du hast eine Tabelle mit Komponenten drin. Also Domains, Speicherplatz, Traffic, Subdomains, Mailadressen etc., alles das, was man so zusammensetzen kann, um einen Webhosting-Vertrag mit Leben zu füllen.

    Dann hast du noch eine weitere Tabelle, welche die Bundles enthält. Name, ID, Preis, sonstige Daten.

    Und mit einer dritten Tabelle verknüpfst du diese n:m-Beziehung zwischen Komponenten und Bundles. Denn es gilt: Eine Komponente kann Bestandteil mehrerer Bundles sein, und ein Bundle kann mehrere Komponenten enthalten.

    Also als Tabellen ausgedrückt:

    artikel:
    art_id  name            einzelpreis
    1       domain de        0,49
    2       domain com       0,99
    3       webspace 100 MB  0,99
    4       webspace 200 MB  1,49

    (An dieser Stelle ist natürlich blöd, dass du alle unterschiedlichen Artikeltypen in einer Tabelle hast. Das Problem läßt sich über eine weitere Spalte "Typ" lösen, die n:1 verknüpft ist mit einer Tabelle "Artikeltypen", in der einer Artikeltyp-ID eine Artikeltypbezeichnung zugeordnet ist - ist aber für die Betrachtung hier irrelevant, sondern eigentlich nur interessant für die GUI).

    bundles:
    bund_id  name              preis
    1        Superhosting 100  0,99
    2        Superhosting 200  1,49
    3        Hosting 3x100     ...

    Und als Zusammensetzung die Liste der Pakete:

    bundles_artikel:
    bund_id    art_id
    1          1        -> Bundle 1 mit 1 .de
    1          3        -> Bundle 1 mit 100 MB
    2          1        -> Bundle 2 mit 1 .de
    2          4        -> Bundle 2 mit 200 MB
    3          1        -> Bundle 3 mit 1 .de
    3          1        -> Bundle 3 mit 1 .de
    3          2        -> Bundle 3 mit 1 .com
    3          4        -> Bundle 3 mit 200 MB

    Wahlweise kannst du die Stückzahl natürlich auch noch in diese Tabelle packen, um gewisse Redundanzen zu vermeiden, aber das könnten dir auch Aggregatfunktionen zusammenzählen.

    So weit, so gut. Allerdings brauche ich die Möglichkeit, dass der
    Kunde zwischen DE- und COM-Domains wählen kann. Wie kann man das in
    der Datenbank abbilden?

    Wahlmöglichkeit bewerben, aber zwei verschiedene Bundles verwenden. Oder den Domaintyp ".de oder .com" wählen.

    Mir macht viel mehr Sorgen, wie du die ganzen Preise zusammenrechnen willst. Dein Beispiel legt jedenfalls für die Einzelkomponenten Preise fest, die als im Bundle nicht summiert sind - sondern teurer! Zwar nur ein Cent, aber immerhin. Der schlaue Kunde wird sich also kein Bundle nehmen, sondern Einzeleinkauf machen. :)

    - Sven Rautenberg

    --
    "Beim Stuff für's Web gibts kein Material, was sonst das Zeugs ist, aus dem die Sachen sind."
    (fastix®, 13. Oktober 2003, 02:26 Uhr -> </archiv/2003/10/60137/#m338340>)
    1. Hallo Sven,

      vielen Dank für deine Antwort!

      Du hast eine Tabelle mit Komponenten drin. Also Domains, Speicherplatz, Traffic, Subdomains, Mailadressen etc., alles das, was man so zusammensetzen kann, um einen Webhosting-Vertrag mit Leben zu füllen.

      Dann hast du noch eine weitere Tabelle, welche die Bundles enthält. Name, ID, Preis, sonstige Daten.

      Und mit einer dritten Tabelle verknüpfst du diese n:m-Beziehung zwischen Komponenten und Bundles. Denn es gilt: Eine Komponente kann Bestandteil mehrerer Bundles sein, und ein Bundle kann mehrere Komponenten enthalten.

      Also als Tabellen ausgedrückt:

      artikel:
      art_id  name            einzelpreis
      1       domain de        0,49
      2       domain com       0,99
      3       webspace 100 MB  0,99
      4       webspace 200 MB  1,49

      (An dieser Stelle ist natürlich blöd, dass du alle unterschiedlichen Artikeltypen in einer Tabelle hast. Das Problem läßt sich über eine weitere Spalte "Typ" lösen, die n:1 verknüpft ist mit einer Tabelle "Artikeltypen", in der einer Artikeltyp-ID eine Artikeltypbezeichnung zugeordnet ist - ist aber für die Betrachtung hier irrelevant, sondern eigentlich nur interessant für die GUI).

      Kannst Du das mal konkretisieren? Irgendwie peil ich das gerade nicht
      ...

      typ:
      id  name
      1   domain
      2   webspace

      artikel:
      id  typ  value  einzelpreis
      1   1    DE     0.49
      2   1    COM    0.99
      3   2    100    0.99
      4   2    200    1.49

      Welchen Typ soll dann value haben - oder hast Du das anders gemeint?

      bundles:
      bund_id  name              preis
      1        Superhosting 100  0,99
      [...]

      Und als Zusammensetzung die Liste der Pakete:

      bundles_artikel:
      bund_id    art_id
      1          1        -> Bundle 1 mit 1 .de
      [...]

      Okay.

      Wahlweise kannst du die Stückzahl natürlich auch noch in diese Tabelle packen, um gewisse Redundanzen zu vermeiden, aber das könnten dir auch Aggregatfunktionen zusammenzählen.

      Außerdem wird's menschenlesbarer ...

      So weit, so gut. Allerdings brauche ich die Möglichkeit, dass der
      Kunde zwischen DE- und COM-Domains wählen kann. Wie kann man das in
      der Datenbank abbilden?

      Wahlmöglichkeit bewerben, aber zwei verschiedene Bundles verwenden. Oder den Domaintyp ".de oder .com" wählen.

      Ersteres scheidet aus, wenn ein Angebot 100 Domains jeweils wahlweise
      DE oder COM enthält - soll ich dann 101 Bundles verwenden? :-)

      Könnte man nicht auch eine Tabelle domains anlegen?

      artikel_domains:
      id  tld      quantity  fee
      1   DE       1         0.49
      2   COM      1         0.99
      3   DE, COM  5         NULL

      tld ist eine Enumeration und gibt die möglichen TLDs an, quantity die
      Anzahl, sodass Datensatz 3 dem Kunden 5-mal die Wahl zwischen DE und
      COM lässt. fee = NULL gibt an, dass das so keinen Preis hat und nur in
      einem Bundle vorkommt.

      Hälst Du was davon? Dann müsste man eben für jeden Artikeltyp, der im
      Bundle enthalten sein kann, eine eigene Tabelle anlegen, und nicht
      einen Datensatz in einer Tabelle. Folge wäre, dass bundle_artikles
      noch eine Angabe zum Artikeltyp benötigt und uns so unseren
      zusammengesetzten Primärschlüssel kaputt macht ...

      Mir macht viel mehr Sorgen, wie du die ganzen Preise zusammenrechnen willst. Dein Beispiel legt jedenfalls für die Einzelkomponenten Preise fest, die als im Bundle nicht summiert sind - sondern teurer! Zwar nur ein Cent, aber immerhin. Der schlaue Kunde wird sich also kein Bundle nehmen, sondern Einzeleinkauf machen. :)

      Wo hab ich denn sowas geschreiben? ;o

      Danke nochmal!
      Peter

      1. Hallo nochmal,

        artikel_domains:
        id  tld      quantity  fee
        1   DE       1         0.49
        [...]

        tld ist eine Enumeration [...]

        ... ein Set.

        Bye,
        Peter

      2. Moin!

        (An dieser Stelle ist natürlich blöd, dass du alle unterschiedlichen Artikeltypen in einer Tabelle hast. Das Problem läßt sich über eine weitere Spalte "Typ" lösen, die n:1 verknüpft ist mit einer Tabelle "Artikeltypen", in der einer Artikeltyp-ID eine Artikeltypbezeichnung zugeordnet ist - ist aber für die Betrachtung hier irrelevant, sondern eigentlich nur interessant für die GUI).

        Kannst Du das mal konkretisieren? Irgendwie peil ich das gerade nicht

        typ:
        id  name
        1   domain
        2   webspace

        artikel:
        id  typ  value  einzelpreis
        1   1    DE     0.49
        2   1    COM    0.99
        3   2    100    0.99
        4   2    200    1.49

        Genau so. Grund: Wenn du eine Auswahlliste machen willst, in der du Megabytes auswählen willst, sollen da natürlich keine Domains drin vorkommen. Das ist also primär als Ordnungskriterium zu sehen, es hat vielleicht dann noch die Relevanz, dass du die DB befragen kannst, welche Bundles denn alles irgendwelche Domains enthalten (kann ja auch Bundles ohne Domains geben). Dann gehst du über den Typ 1 (domain) in die Artikel, kriegst alle IDs von Domains, gehst damit in die n:m-Verknüpfung, und von dort aus in die Bundles, und kriegst alle Bundles, die _irgendeine_ Domain im Angebot haben.

        Mag für dich irrelevant sein, wenn alle Bundles eine Domain haben. :) Aber das System ist darauf vorbereitet.

        Welchen Typ soll dann value haben - oder hast Du das anders gemeint?

        value ist ein Textstring, der für den Menschen beschreibt, was der DB-Eintrag bedeutet.

        Keine Sets, Enums oder sonstiges. :)

        Wahlmöglichkeit bewerben, aber zwei verschiedene Bundles verwenden. Oder den Domaintyp ".de oder .com" wählen.

        Ersteres scheidet aus, wenn ein Angebot 100 Domains jeweils wahlweise
        DE oder COM enthält - soll ich dann 101 Bundles verwenden? :-)

        Nein. Du hast ein Bundle "mit 100 Domains". Frage: Welche Domains? Nur .de-Domains? Dann verknüpfst du "Bundle 100 Domains" in der n:m-Tabelle mit dem Artikel ".de-Domain" - und da du einen Zähler für die Anzahl der Verknüpfungen anlegst, schreibst du da eine 100 rein. Damit weißt du: Das Bundle enthält 100 .de-Domains. Die "wahlweise .de/.com" Artikel ließen sich natürlich so auch verknüpfen. Dann zeigst du eben auf den "wahlweise"-Artikel.

        Könnte man nicht auch eine Tabelle domains anlegen?

        Man kann alle möglichen Tabellen anlegen. :) Die Kunst ist, genau die Tabellen anzulegen, die dem Problem weiterhelfen.

        artikel_domains:
        id  tld      quantity  fee
        1   DE       1         0.49
        2   COM      1         0.99
        3   DE, COM  5         NULL

        tld ist eine Enumeration und gibt die möglichen TLDs an, quantity die
        Anzahl, sodass Datensatz 3 dem Kunden 5-mal die Wahl zwischen DE und
        COM lässt. fee = NULL gibt an, dass das so keinen Preis hat und nur in
        einem Bundle vorkommt.

        Deine ENums sind ja Sets, und in Sets kannst du typischerweise nur 64 verschiedene, dafür aber beliebig kombinierbare Werte codieren. Hatte ich irgendwo im Thread schon geschrieben, dass das bei TLDs knapp werden könnte. Es ist "broken by design", ein Set oder Enum für etwas zu verwenden, von dem es prinzipbedingt unendlich viel geben kann. Und von TLDs kann es grundsätzlich beliebig viel geben. Verwende Enum für so Dinge wie "ja/nein", "männlich/weiblich", Benutzerrechte "lesen/schreiben/löschen/verschieben/kopieren/anmerken" (die werden einmal beim Design vorgegeben, ändern sich aber im Betrieb dann nicht mehr) etc. Für Sets gilt dasselbe (die sind bei Benutzerrechten wohl geeigneter).

        - Sven Rautenberg

        --
        "Beim Stuff für's Web gibts kein Material, was sonst das Zeugs ist, aus dem die Sachen sind."
        (fastix®, 13. Oktober 2003, 02:26 Uhr -> </archiv/2003/10/60137/#m338340>)