Sebastian Will: Designfragen, generelles

Hi Forum,

ich bin gerade dabei, etwas in Richtung PHP/MySQL zu planen und irgendwann später auch zu realisieren. Ganz grob gesagt ist es ein kleines Autorensystem für's Web, bei dem beliebig viele Nutzer lesen und einige ausgewählte auch eigene Artikel verfassen dürfen. Da ich nicht allzuviel Erfahrung in Sachen Datenbankdesign habe, wollte ich euch gerne meinen Entwurf vorstellen, um so ein paar Meinungen einzufangen.

Zuerst noch eine Frage vorweg: Macht es Sinn, für Artikel ein einziges Feld variabler Länge (varchar) zu belegen oder ist dadurch der Speicherbedarf zu groß? In diesem Feld soll der Artikel in gekennzeichneter Form ( XML) vorliegen, daß dann per PHP in die Seiten eingefügt wird, große Artikel sollen auf mehrere Seiten aufgeteilt werden. Ist es in diesem Fall besser, die einzelnen Seiten in der Datenbank zu speichern, als den gesamten Artikel in einem Feld? Welche anderen Lösungsvorschläge für dieses konkrete Problem gibt es?

* Usertabelle
name  type
------------------------------------
id  smallint, auto-increment, NOT NULL
name  varchar(20), NOT NULL
vorname  varchar(20), NOT NULL
email  varchar(40), NOT NULL
passwort varchar(10), NOT NULL
last-login date
logins  smallint
newsletter boolean, NOT NULL
interessen varchar(100), NOT NULL [Bsp.: 'XML=32:Design=123:Jobs=3']

* Roles
name    type
------------------------------------
id  smallint, auto-increment, NOT NULL
user  smallint, NOT NULL
area  varchar(20), NOT NULL
role  char(1) ['e' = Editor, 'a' = Administrator], NOT NULL

* Artikel
name  type
------------------------------------
id  smallint, auto-increment, NOT NULL
autor  smallint, NOT NULL
text  varchar(10000), NOT NULL
hits  smallint
bewertung float [Bsp.: 123.3 = 123 Bewertungen, Durchschnittsnote: 3, ob's float in MySQL gibt, muß ich nochmal nachlesen, also keine Kommentare darüber, equivalentes gibt es sicher und deshalb an dieser Stelle auch nicht weiter wichtig]
rubrik   smallint, NOT NULL

* Rubriken
name    type
------------------------------------
id  smallint, auto-increment, NOT NULL
name  varchar(20), NOT NULL [Bsp.: 'XML']
super  smallint [ID der Vater-Rubrik, Root ist [0, 'HOME', NULL]

* Bilder
name    type
------------------------------------
id  smallint, auto-increment, NOT NULL
url  varchar(50), NOT NULL
alt  varchar(50)

* Links
name    type
------------------------------------
id  smallint, auto-increment, NOT NULL
url  varchar(100), NOT NULL
alt  varchar(50)

Ich weiß, daß das hier kein Crashkurs in Sachen Datenbankdesign sein kann. Vielleicht kann mir der ein oder andere aber doch einen Tip aus der Praxis liefern. Vielen Dank schonmal und

<mfg>Sebastian Will</mfg>

  1. Hallo,

    Zuerst noch eine Frage vorweg: Macht es Sinn, für Artikel ein einziges Feld variabler Länge (varchar) zu belegen oder ist dadurch der Speicherbedarf zu groß? [...]

    varchar wäre schon ok, da sowieso nur die wirkliche Anzahl der Zeichen + 1 abegelegt wird. Nur... bei varchar bringst Du max. 255 Zeichen unter :-( s.u.

    Grunsätzliches: id sollte nicht smallint sein, da dabei bei ca. 32.000 einträgen Schluß ist. Entweder ists sowieso eine kleine Datenbank, dann machen int-Werte nicht soviel aus, oder es wird groß, dann brauchst Du sie sowieso. Ich würde grundsätzlich unsigned int verwenden.

    Außedem ist es gut, ein Mengen-Gerüst aufzustellen, d.h. ungefähr abzuschätzen wieviele Datensätze jede Tabelle beinhalten wird.
    Bei Stammtabellen, wie User oder so kannst Du ruhig großzügiger sein, weil hier nur wenige Datensätze sein werden.

    * Usertabelle
    name  type

    id  smallint, auto-increment, NOT NULL
    name  varchar(20), NOT NULL
    vorname  varchar(20), NOT NULL
    email  varchar(40), NOT NULL
    passwort varchar(10), NOT NULL
    last-login date
    logins  smallint
    newsletter boolean, NOT NULL
    interessen varchar(100), NOT NULL [Bsp.: 'XML=32:Design=123:Jobs=3']

    Name bzw. Vorname sollten größer sein.
    Interessen ist Mehrzahl und klingt irgendwie nach zweiter Tabelle.

    Table Interessen
    id unsigned int, auto-increment, NOT NULL
    user_id unsigned int, NOT NULL
    bezeichnung varchar(50)
    bewertung int

    * Roles
    name    type

    id  smallint, auto-increment, NOT NULL
    user  smallint, NOT NULL
    area  varchar(20), NOT NULL
    role  char(1) ['e' = Editor, 'a' = Administrator], NOT NULL

    * Artikel
    name  type

    id  smallint, auto-increment, NOT NULL
    autor  smallint, NOT NULL
    text  varchar(10000), NOT NULL

    10 KByte ist wenig für Text
    sollte TEXT oder größer sein (diese Seite hier hat z.b. schon 12KByte)

    hits  smallint
    bewertung float [Bsp.: 123.3 = 123 Bewertungen, Durchschnittsnote: 3, ob's float in MySQL gibt, muß ich nochmal nachlesen, also keine Kommentare darüber, equivalentes gibt es sicher und deshalb an dieser Stelle auch nicht weiter wichtig]

    float gibts.

    rubrik   smallint, NOT NULL

    Eventuell gehört ein Artikel auch zu mehreren Rubriken, dann wäre es besser mit einer m:n beziehung zu arbeiten

    * Rubriken
    name    type

    id  smallint, auto-increment, NOT NULL
    name  varchar(20), NOT NULL [Bsp.: 'XML']
    super  smallint [ID der Vater-Rubrik, Root ist [0, 'HOME', NULL]

    * Bilder
    name    type

    id  smallint, auto-increment, NOT NULL
    url  varchar(50), NOT NULL

    Url sollte m.E. auch größer sein

    alt  varchar(50)

    * Links
    name    type

    id  smallint, auto-increment, NOT NULL
    url  varchar(100), NOT NULL

    hier ist er größer, aber ...

    alt  varchar(50)

    Grüße
      Klaus

  2. Hi Sebastian

    Kleine Kritik:

    Speichere jeden Wert in einem eigenen Feld. Die Bewertung. Zwei Felder sind besser als die beiden Werte zusammen in ein Feld zu schrieben. Dazu sind ja Tabellen da.

    Zeichne doch deine Tabellen auf und entwerfe ein ER Diagramm. Du (und andere) kannst so viel besser erkennen wo die Schwachstellen deiner DB liegen.
    Beispiel eines ER Diagramms, dass ich auf die schnelle im Web gefunden habe: http://atlasinfo.cern.ch/ATLAS/GROUPS/PRODUCTION_DATABASE/E_R.pdf

    Für die Artikel würde ich externe Files generieren [,die Du dann includen kannst] und in der DB nur die URL speichern.

    MfG
      Thomas