Komplexe SQL-Queries mit Übersetzungstabelle

ActionScripter3

New Member
Hallo,

es geht um eine mehrsprachige sqlite DB welche eine translations tabelle mit den Übersetzungen enthält. Jeder zu übersetzende Wert in der Datenbank findet sich dort in der 'term' Spalte wieder, die jeweilige übersetzung ist in der Spalte der Sprache.
Betrachten wir zum Beispiel das Feld 'title' der Tabelle 'image', dann steht dort 'uid_123', die entsprechende Zeile der translatations-Tabelle sehe so aus:

Code:
| id | column_name | term    | de   | fr      | en    |
| 3  | image.title | uid_123 | Haus | Accueil | House |

Nun wird jedoch nicht nur der Titel, sondern z.B. auch die Beschreibung des Bildes übersetzt, daraus ergibt sich folgender (funtkionierender) Query:

Code:
SELECT `id_image`, `title`, `desc`, `filename`,
trans_title.en as title_en, trans_title.fr as title_fr, trans_title.de as title_de, 
trans_desc.en as desc_en, trans_desc.fr as desc_fr, trans_desc.de  as desc_de
FROM images
LEFT JOIN translations  trans_title ON  (trans_title.column_name = 'images.title' AND trans_title.term = image.title) 
LEFT JOIN translations  trans_desc ON  (trans_desc.column_name = 'images.desc' AND trans_desc.term = image.desc) 
WHERE id_image = 123;

Nun kann ich beliebig viele Felder mit einer Anfrage in allen drei Übersetzungen bekommen. Allerdings muss ich nun noch die Sprachen variabel gestalten. D.h. es muss möglich sein jederzeit neue Sprachen (als Spalte in der translations-Tabelle) hinzuzufügen, ohne den SQL-Query zu verändern, wie kann ich das lösen?
 
Ich würde de fr und en in eine eigene Tabelle speichern mit einer UID und Primary Key.
Diesen ziehst du dir dann als Fremdschlüssel in die Übersetzungstabelle. Dadurch hast du zwar mehr Datensätze bist aber flexibler ...

Abfrage könntest du dann auf entsprechende column_names bauen und über die UID kommst du an die Sprache die du brauchst.
 
Hallo JaEgErmEistEr,

gleich vorneweg: Die Datebenbank mit dem beschriebenen Schema besteht bereits und wird so schon genutzt.
Deine Lösung bringt mich aber im Kern auch nicht weiter als meine bisherige, denn was mache ich wenn mehrere Sprachen hinzukommen, wie gestalte ich dann meine Anfrage ohne die Sprachkürzel 'hart' zu coden?
 
Indem du dir einfach alle verfügbaren Kürzel aus der neuen Tabelle ausliest und dann über die UIDs die Verknüpfung herstellst. :eek:
Die kannst du ja dann weiterverarbeiten ;)

Wenn das so besteht wüsste ich da keinerlei Möglichkeit die wirklich Sinn macht denn jedes mal eine neue Spalte hintendranzuhängen ist wohl richtig shice ;)
 
Indem du dir einfach alle verfügbaren Kürzel aus der neuen Tabelle ausliest und dann über die UIDs die Verknüpfung herstellst. :eek:
Die kannst du ja dann weiterverarbeiten ;)

Wenn das so besteht wüsste ich da keinerlei Möglichkeit die wirklich Sinn macht denn jedes mal eine neue Spalte hintendranzuhängen ist wohl richtig shice ;)

Kannst du mir hierfür ein Beispiel geben, bzw. den Code von oben dahingehen anpassen?
Danke
 
Du möchtest dynamisch die Projektion verändern. Die einzige Möglichkeit das zu bewerkstelligen ist * zu nutzen oder dein Query dynamisch zu erstellen. Was also gehen könnte ist so etwas:
Code:
Database changed
mysql> SELECT 
    ->   `images`.`id`, 
    ->   `images`.`title`, 
    ->   `images`.`description`, 
    ->   `images`.`filename`, 
    ->   `trans_title`.*, 
    ->   `trans_desc`.*
    -> FROM `images`
    -> LEFT JOIN `translations`  `trans_title` 
    ->   ON `trans_title`.`column_name` = 'images.title' AND `trans_title`.`term` = `images`.`title` 
    -> LEFT JOIN `translations`  `trans_desc` 
    ->   ON `trans_desc`.`column_name` = 'images.desc' AND `trans_desc`.`term` = `images`.`description`
    -> ;
+----+-------+-------------+----------+------+--------------+------+------------+------------+-------+--------+------+-------------+--------+------------------+------------------+------------+-------------+
| id | title | description | filename | id   | column_name  | term | de         | en         | fr    | sua    | id   | column_name | term   | de               | en               | fr         | sua         |
+----+-------+-------------+----------+------+--------------+------+------------+------------+-------+--------+------+-------------+--------+------------------+------------------+------------+-------------+
|  1 | A1    | descA1      | a1.jpg   |    1 | images.title | A1   | Deutsch A1 | English A1 | fr A1 | sua A1 |    3 | images.desc | descA1 | Deutsch Desc. A1 | English Desc. A1 | fr desc A1 | sua desc A1 |
|  2 | A2    | descA2      | a2.jpg   |    2 | images.title | A2   | Deutsch A2 | English A2 | fr A2 | sua A2 |    4 | images.desc | descA2 | Deutsch Desc. A2 | English Desc. A2 | fr desc A2 | sua desc A2 |
+----+-------+-------------+----------+------+--------------+------+------------+------------+-------+--------+------+-------------+--------+------------------+------------------+------------+-------------+
2 rows in set (0.00 sec)

mysql>
Was halt zur Folge hat, dass - wie man sieht - alle Spalten erscheinen und sie auch nicht so schön benannt sind.
Dynamisch zusammenbauen: In der Applikation erst schauen was es für Sprachfelder gibt, dann entsprechend darüber iterieren und Abfrage basteln...

Ansonsten baue deine Struktur um:
Translations: id, column_name, term, language, value
Dann bekommst du eben beim Abfragen mehrere Ergebnisse für ein Bild, für jede Sprache eines und kannst dir dann das passende suchen - bzw. mit where die Sprache einschränken/wählen.
 
Back
Top