André Laugks: Tabellenstruktur

Hallo!

Ich stehe gerade etwas bezüglich einer "Tabellenstruktur" auf dem schlauch.

Es sollen auf der Webseite Dateien (gif, jpg, pdf) geuploadet werden können.

// Objekt
obj_id   name
1        xyz
2        abc
3        fgh

!! Ein Objekt (obj_id) kann mehrere Dateien (dat_id) haben.

Als erstes habe ich mir folgende Struktur übelegt.

//datei
dat_id        INT
obj_id        INT
datei_thumb   VARCHAR  (1243.gif)
datei_foto    VARCHAR  (12478.gif)
datei_pdf     VARCHAR  (457.pdf)
beschr        VARCHAR
rang          INT

// Beispiel
dat_id  obj_id  datei_thumb  datei_foto  datei_pdf    beschr
125        2      1458.gif     368.gif     NULL       blabla
126        2        NULL      1487.jpg     NULL        NULL
127        1        NULL        NULL      399.pdf     blabla

Mit dieser Struktur habe ich sehr kurze SQL-Statements. Es kann zu sehr vielen NULL-Feldern kommen, weil es zu einem Thumbnail kein Foto geben muß und umgekehrt. Zu einem Thumbnail und Foto gibt es auch keine PDF-Datei. Zu einer PDF-Datei muß es kein Foto geben.
Es ist nicht mit zu rechnen, daß ein weitere Dateiart hinzu kommt. Es ist davon auszugehen, daß die Tabelle nicht mehr als 5000 Datensätze bekommen wird, also nicht gerade viel.

Als alternative Struktur habe ich mir folgende ausgedacht. Besteht fast nur aus dem Typ INT und Enum, also schnelle Spaltentypen und wenig Speicherplatz. Die eine VARCHAR-Spalte wird die Geschwindigkeit wieder runter ziehen. Diese Struktur bedeutet natürlich lange LEFT JOINs und somit Geschwindigkeitseinbußen.

// Tabelle datei
dat_id    INT
obj_id    INT
beschr    VARCHAR
rang

// Tabelle datei_thumb
dat_id    INT
datei     INT
typ       ENUM('gif', 'jpg');

// Tabelle datei_foto
dat_id    INT
datei     INT
typ       ENUM('gif', 'jpg');

// Tabelle datei_pdf
dat_id    INT
datei     INT

MfG, André Laugks

--
L-Andre @ gmx.de
  1. Hallo Andre,

    so ginge es doch auch

    Typtabelle           Bsp
    Typ_ID               1      2    3
    Bezeichnung          Bild   PDF  Thumb

    Objekttabelle        Bsp
    Objekt_ID            1      2      3
    Bezeichnung          Hund   Katze  Maus
    sonstige Attribute

    Koppeltabelle:       Bsp
    Objekt_ID            1
    Typ_ID               1
    Dateiname            hund.jpg

    kommt eben darauf, was für selects Du häufig hast.
    ob das so sinnvoller ist, wage ich allerdings zu bezweifeln, kenne
    mich nicht so gut aus :)

    Gruß
    annA

  2. Hi!

    Mit dieser Struktur habe ich sehr kurze SQL-Statements. Es kann zu sehr vielen NULL-Feldern kommen,

    das ist eigentlich nicht schlimm, wenn auch nicht besonders schön. NULL nimmt nicht viel Platz weg, udn bei 5000 Datensätzen sollte sowas egal sein. Trotzdem würde ich es anders machen, kommt aber drauf an wie Du das später verwenden willst. Ich würde das z.B. so machen:

    tbl_dateien
      dat_id        MEDIUMINT PRIMARY KEY
      obj_id        MEDIUMINT
      typ           ENUM('gif', 'jpg', 'pdf')
      beschr        CHAR(128)

    Ich würde den Namen gar nicht mehr speichern, da ich zumindest in meinen Projekten befürchte dass verschiedene Dateien denselben Namen haben könnten, daher verwende ich nur die eindeutige ID als Namen und die Endung.

    Jetzt könntest Du z.B. alle Grafik-Dateien von Objekt 1 abfragen mit

    SELECT * FROM tbl_dateien WHERE obj_id = "1"

    Dann kanst Du aus

    echo $row['dat_id'].".".$row['typ'] den Dateinamen ausgeben. Ggfs. noch eine Beschreibung dazu.

    Es ist nicht mit zu rechnen, daß ein weitere Dateiart hinzu kommt. Es ist davon auszugehen, daß die Tabelle nicht mehr als 5000 Datensätze bekommen wird, also nicht gerade viel.

    genau, also würde ich mir um Performance wirklich keine Sorgen machen,  lege halt nützliche Indices drauf und es wird vollkommen ausreichen, egal welche Variante Du verwendest. Verwende die Variante die Dir am besten gefällt.

    Als alternative Struktur habe ich mir folgende ausgedacht. Besteht fast nur aus dem Typ INT und Enum, also schnelle Spaltentypen und wenig Speicherplatz. Die eine VARCHAR-Spalte wird die Geschwindigkeit wieder runter ziehen.

    Du brauchst aber keine varchar Spalte, CHAR tut es auch, udn wenn man mal den Speicherplatz ausrechnet, haben 5000 Datensätze CHAR(255) vielleicht 1 MB Speicherplatz, nicht wirklich viel.

    Grüße
    Andreas

    1. Hallo!

      tbl_dateien
        dat_id        MEDIUMINT PRIMARY KEY
        obj_id        MEDIUMINT
        typ           ENUM('gif', 'jpg', 'pdf')
        beschr        CHAR(128)

      Das hatte ich mir auch schon überlegt. So werde ich aber Fotos folgendermaßen ablegen müßen: thumb_123.gif und foto_123.gif. Nur woher weiß ich, daß es zu einem Thumbnail ein Foto gibt oder nicht. Ich muß also ständig in den Ordner schauen. Da bin ich kein Freund von. Deshalb hatte ich mir die drei Spalten für Thumbnail, Foto und PDF-Datei überlegt. Die eindeutige datei_id generiere ich aus einer Zählertabelle (eine Spalte/Datensatz -> immer + 1) heraus.

      Wenn ich den Dateityp mit abspeichere ( ENUM('gif', 'jpg', 'pdf') ) muß ich auch überprüfen, wenn Thumbnail und Foto hochgeladen wird oder eins von beiden geändert wird, ob beide den selben Dateityp haben. Das halte ich für aufwendiger, als wenn ich den Dateinamen + Dateityp (VARCHAR -> '12345.gif') mit abspeichere. Ich würde also gern dem User (geschulter Mitarbeiter) überlassen, den richtigen Dateityp zu wählen.

      Aiaiai, ich mache erstmal was anderes und denke weiter nach.

      genau, also würde ich mir um Performance wirklich keine Sorgen machen,  lege halt nützliche Indices drauf und es wird vollkommen ausreichen, egal welche Variante Du verwendest. Verwende die Variante die Dir am besten gefällt.

      So habe ich auch schon gedacht. Die eine ist besser "aufgelöst", hat aber längere SQL-Statements zur folgee, bei der anderen ist es umgekehrt.

      Du brauchst aber keine varchar Spalte, CHAR tut es auch, ...

      Stimmt, ist ja sonst keine Spalte vom Typ VARCHAR oder TEXT vorhanden.

      MfG, André Laugks

      --
      L-Andre @ gmx.de