KraKi: MySQL array-Datentyp

Moin moin,
also, immer wieder kommt es vor, dass ich in einer Datenbak eine ganze Reihe von Spalten benötige, die einander sehr ähnlich sind und die auch immer gemeinsam ausgelesen werden.

Normalerweise löse ich das so, dass ich bei einer bestimmten Anzahl von Spalten diese tatsächlich erstelle (und durchnummeriere) um anschließend mittels php darauf zuzugreifen.
Z.B. so:
id | Name | Spalte1 | Spalte2 | Spalte3 |
1  | foo  | 3       | 6       | 8       |
2  | bar  | 6       | 12      | 54      |

in php brauche ich aber

$sql_array[1]['Name'] = 'foo';  
$sql_array[1]['Spalten'][1] = 3;  
$sql_array[1]['Spalten'][2] = 6;  
$sql_array[1]['Spalten'][3] = 8;  
$sql_array[2]['Name'] = 'bar';  
$sql_array[2]['Spalten'][1] = 6;  
$sql_array[2]['Spalten'][2] = 12;  
$sql_array[2]['Spalten'][3] = 54;

mit anderen Worten, "Spalte" soll ein Array sein.

nun, wenn es eine unbestimmte Anzahl sein soll (oder auch eine bestimmte, ist ja egal), dann habe ich das gerne auch durch einen Seperator (ich hoffe das Wort gibt es im Deutschen) gelöst:

id | Name | Spalten |
1  | foo  | 3;6;8   |
2  | bar  | 6;12;54 |

$sql_array[1]['Name'] = 'foo';  
$sql_array[1]['Spalten'] = explode(';',$Spalten_string);  
$sql_array[2]['Name'] = 'bar';  
$sql_array[2]['Spalten'] = explode(';',$Spalten_string);  
//($Spalten_string bezeichnet hier natürlich den aus der Spalte "Spalten" ausgelesenen string)

Sieht schon mal besser aus, aber jetzt kommt das "Problem", ich halte es für einen unnötigen Speicherverbrauch diese integer-Werte als string (bzw. VARCHAR/TEXT/whatever) zu speichern. Das kommt insbesondere auch gerne dann vor, wenn ich auf eine Reihe anderer Zeilen in anderen Tabellen der selben Datenbank verweise.
Daher die Frage: Gibt es in mySQL einen passenden Array-Datentyp odr kennt jemand eine andere (bessere) Methode oder muss ich bei der zuletzt genannten Variante bleiben?

(Für arrays, die ohnehin aus strings bestehen ist das ja kein Problem).

  1. Hi,

    also, immer wieder kommt es vor, dass ich in einer Datenbak eine ganze Reihe von Spalten benötige, die einander sehr ähnlich sind

    bist Du sicher, dass diese Spalten nicht in eine eigene Tabelle ausgelagert gehören? Für mich klingt das nach einer 1:n-Verknüpfung.

    in php brauche ich aber

    Was Du in PHP brauchst, stellst Du in PHP her. Das Datenbank-Layout ist davon unabhängig.

    nun, wenn es eine unbestimmte Anzahl sein soll (oder auch eine bestimmte, ist ja egal), dann habe ich das gerne auch durch einen Seperator (ich hoffe das Wort gibt es im Deutschen) gelöst:

    Im Deutschen gibt es das Wort "Separator".

    id | Name | Spalten |
    1  | foo  | 3;6;8   |

    Ein Zelleninhalt einer DB ist atomar. Das heißt, Du hast hier *einen* Wert "3;6;8" und *nicht* mehrere Werte.

    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. bist Du sicher, dass diese Spalten nicht in eine eigene Tabelle ausgelagert gehören? Für mich klingt das nach einer 1:n-Verknüpfung.

      Das ist eine gute Idee, wenn ich dich richtig verstehe meinst ich solle eine neue Tabelle anlegen mit nur zwei Spalten (id + Wert) und in der Ursprungstabelle den "Bereich" in zwei Spalten speichern (id_min + id_max)

      id | Name | Spalten |
      1  | foo  | 3;6;8   |

      Ein Zelleninhalt einer DB ist atomar. Das heißt, Du hast hier *einen* Wert "3;6;8" und *nicht* mehrere Werte.

      Das ist mir klar ^^ dass das nur ein Wert ist, ich zerlege ihn ja auch erst später in mehrere (siehe Code). Die Frage war im Grunde, ob es ein Wert sein *muss* oder ob ich auch eine Wert-Reihe in eine Spalte schreiben kann (eine mögliche Lösung hast du mir ja gerade gezeigt).
      Ähnliche Konstrukte hatte ich auch schon mit Speratoren und Subseperatoren.
      Name1%Wert1;Name2%Wert2;Name3%Wert3
      wird zu

        
      $array[0][0] = 'Name1';  
      $array[0][1] = 'Wert1';  
      $array[1][0] = 'Name2';  
      $array[1][1] = 'Wert2';  
      $array[2][0] = 'Name3';  
      $array[2][1] = 'Wert3';  
      
      

      mittels

        
      $array = explode(';',$Zeile);  
      foreach ($array as $key => $value) {  
       $array[$key] = explode('%',$value);  
      }  
      
      

      Ich denke aber dein Vorschlag hat 'was für sich, ich werde das ausprobieren.
      Schönen Dank!

      1. Moin!

        Das ist eine gute Idee, wenn ich dich richtig verstehe meinst ich solle eine neue Tabelle anlegen mit nur zwei Spalten (id + Wert) und in der Ursprungstabelle den "Bereich" in zwei Spalten speichern (id_min + id_max)

        Nein. Drei Spalten.

        Eine aus Prinzip für einen Primärschlüssel.

        Und als relevante Werte dann einmal die ID aus der Haupttabelle, und den Wert.

        Wenn das hier deine Haupttabelle ist:

        id | Name | Spalten |
        1  | foo  | 3;6;8   |

        ändert sich diese zu:
        h_id | Name |
        1  | foo  |

        und die Nebentabelle wird zu:
        s_id | h_id | wert
        1    |  1   |  3
        2    |  1   |  6
        3    |  1   |  8

        Beachte: Gleiche IDs heißen bei mir auch gleich. h_id ist, egal in welcher Tabelle, immer die id der Tabelle "h". Hat den Vorteil, dass man im JOIN die Verknüpfung dieser zwei gleichnamigen ID-Spalten mit "USING (h_id)" hinkriegt.

        - Sven Rautenberg

        --
        "Love your nation - respect the others."
        1. Hi

          Nein. Drei Spalten.

          Eine aus Prinzip für einen Primärschlüssel.

          Und als relevante Werte dann einmal die ID aus der Haupttabelle, und den Wert.

          Wenn das hier deine Haupttabelle ist:

          id | Name | Spalten |
          1  | foo  | 3;6;8   |

          ändert sich diese zu:
          h_id | Name |
          1  | foo  |

          und die Nebentabelle wird zu:
          s_id | h_id | wert
          1    |  1   |  3
          2    |  1   |  6
          3    |  1   |  8

          Auch gut, ich hatte es jetzt so vorgehabt:

          Haupttabelle
          id | Name | Spalte_min | Spalte_max |
          1  | foo  | 3          | 5          |

          Nebentabelle:
          id | Wert |
          1  | 0    |
          2  | 0    |
          3  | 3    |
          4  | 6    |
          5  | 8    |
          6  | 0    |

          Also sind die Werte in den Zeilen "drei bis fünf" betroffen.
          Mit deiner Mehtode ist es aber bedeutend einfacher später Werte nachzupflegen.

          Danke!

      2. Hi,

        Ein Zelleninhalt einer DB ist atomar. Das heißt, Du hast hier *einen* Wert "3;6;8" und *nicht* mehrere Werte.
        Das ist mir klar ^^ dass das nur ein Wert ist, ich zerlege ihn ja auch erst später in mehrere (siehe Code).

        genau hier steckt der Teufel, der Dir wie es scheint noch nicht klar ist: Wenn Du das Bedürfnis hast, den Wert einer Tabellenzelle nicht atomar zu betrachten, dann solltest Du Dir Gedanken darüber machen, ob das DB-Layout stimmt. In einer idealen Welt ist _und bleibt_ der Wert atomar, d.h. für alle denkbaren Zwecke ist "3;6;8" für Dich _der_ Wert.

        Klar, dass die ideale Welt nicht existiert. Aber wie so oft: Solange Du nicht weißt, wann Du eine Regel brechen kannst, darfst, sollst oder sogar musst, solltest Du sie als Gesetz ansehen. Das vermeidet Fehle und erhöht nebenbei auch den Lerneffekt ;-)

        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. Klar, dass die ideale Welt nicht existiert. Aber wie so oft: Solange Du nicht weißt, wann Du eine Regel brechen kannst, darfst, sollst oder sogar musst, solltest Du sie als Gesetz ansehen. Das vermeidet Fehler und erhöht nebenbei auch den Lerneffekt ;-)

          Du meinst es war auch keine gute Idee, eine Reihe (20-30) von boolischen Werten in integer umzuwandeln und als solchen zu speichern?
          Naja, ich glaube aber _das_ änder' ich jetzt nicht mehr.

          1. Hi,

            Du meinst es war auch keine gute Idee, eine Reihe (20-30) von boolischen Werten in integer umzuwandeln und als solchen zu speichern?

            keine Ahnung, aber gemäß der Reinen Lehre[tm] klingt es danach.

            Naja, ich glaube aber _das_ änder' ich jetzt nicht mehr.

            <DarthVader> As you wish. </DarthVader>

            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