Designfragen, generelles
Sebastian Will
- datenbank
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>
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 typeid 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 typeid 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 typeid 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 typeid 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 typeid smallint, auto-increment, NOT NULL
url varchar(50), NOT NULL
Url sollte m.E. auch größer sein
alt varchar(50)
* Links
name typeid smallint, auto-increment, NOT NULL
url varchar(100), NOT NULL
hier ist er größer, aber ...
alt varchar(50)
Grüße
Klaus
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