Hallo,
wie würdet ihr denn mehrere Sprachen (sinvoll) in einer Datenbank
abbilden? Dabei soll aber auch beachtet werden, dass es sprachunabhänige
Inhalte gibt (z.B. Artikelnummer).
Mir würden spontan 2 Ansätze einfallen:
Beispiel Tabelle Artikel Variante 1:
SpracheId|Artikelnummer|Artikeltext
---------+-------------+-----------
1 |0815 |Tastatur
2 |0815 |Keyboard
1 |4711 |Kabel
2 |4711 |Cable
Beispiel Tabelle Artikel Variante 2:
Artikelnummer|ArtikeltextSprache1|ArtikeltextSprache2
-------------+-------------------+-------------------
0815 |Tastatur |Keyboard
4711 |Kabel |Cable
An Variante 1 gefällt mir nicht, dass sprachunabhänige Dinge dupliziert
vorkommen.
An Variante 2 gefällt mir nicht, dass wenn neue Sprachen dazukommen, man
die Tabelle anpassen muss. Gut: Es werden nur halb so viele Felder im
Gegensatz zur Variante 1 benötigt.
Wie würdet ihr das lösen und dabei bei einem praxistauglichen DB-Modell
bleiben? Oder welche Variante würdet ihr bevorzugen?
Viele Grüße,
Peter
SpracheId|Artikelnummer|Artikeltext
---------+-------------+-----------
1 |0815 |Tastatur
2 |0815 |Keyboard
1 |4711 |Kabel
2 |4711 |Cable
Nur würde ich den Artikeltext dann eher durch eine Verknüpfung auf eine
Tabelle ersetzen.
ARTIKEL-DB
Artikelnummer|ArtikeltextID
-------------+-----------
0815 |1
4711 |2
ARTTEXT-DB
Id | Language | Text
1 | GER | Tastatur
1 | ENG | Keyboard
2 | ENG | Cable
Wenns ne Relationale Datenbank ist kann man dann im SQL-befehl schon die
Strategie einbauen Englisch zu nehmen, wenns keine nationale Übersetzung
gibt.
Du kannst auch 3 Tabellen erstellen:
Artikel (alle Artikel mit Artikelnummer der ID von Artikel_Sprach_Daten)
Artikelnummer|Beschreibung
-------------+-----------
0815 |1
4711 |2
Sprachen (ID und welche Sprache)
ID |Sprache
---+-----------
1 | Deutsch
2 | Englisch
Artikel_Sprach_Daten (denk dir was aus :) )
(ID, die ID aus Sprachen und die eigentliche Beschreibung)
ID |Sprache | Beschreibung
---+--------+--------------
1 | 1 | tastatur
2 | 1 | maus
3 | 2 | keyboard
4 | 2 | mouse
Mit ein paar JOIN kannst du das gut abfragen.
Dennis Heynlein schrieb:> ARTIKEL-DB>> Artikelnummer|ArtikeltextID> -------------+-----------> 0815 |1> 4711 |2>> ARTTEXT-DB>> Id | Language | Text> 1 | GER | Tastatur> 1 | ENG | Keyboard> 2 | ENG | Cable
Das ist die Lösung die im Globalize3 Gem bei Ruby on Rails verwendet
wird. Ich bin ziemlich zufrieden mit dieser Lösung. Dort hatte ich
dasselbe Problem die Texte zu Items usw bei BreePets multi-lingual zu
halten. Und als Fallback ist mindestens der englische Text verfügbar.
...ok, schöne nachvollziehbare Beispiele. Sind diese auch Praxisnah?
Das würde doch in etwa dem entsprechen, dass ich z.B. in einer
Personentabelle die Wohnorte einer Person auch in eine eigene Tabelle
auslagere. Dass das mit Joins gut auslesbar ist, ist klar. Aber ist es
praxisnah?
Also nicht falsch verstehen, ich möchte nur für mich wissen, ob hier die
Normalisierung zu weit geht, oder ob das ganz normal ist...
Immerhin ist das verknüpfen von Tabellen Naturgemäß für die DB
aufwendiger als wenn ich in einer Tabelle bleibe. Und gerade Artikel
können ja durchaus auch mal mehr werden (500.000+).
Wobei das Suchen innerhalb der Texte sollte sich eigentlich mit diesen
Beispielen auch rel. gut machen lassen. Muss da noch ein wenig über die
Lösungen nachdenken.
Auf jeden Fall vielen Dank für die schönen Beispiele.
Gruß,
Peter
Peter schrieb:> ...ok, schöne nachvollziehbare Beispiele. Sind diese auch Praxisnah?>> Das würde doch in etwa dem entsprechen, dass ich z.B. in einer> Personentabelle die Wohnorte einer Person auch in eine eigene Tabelle> auslagere. Dass das mit Joins gut auslesbar ist, ist klar. Aber ist es> praxisnah?
Ja, erprobe ich tagtäglich auf unserer Seite.
> ...ok, schöne nachvollziehbare Beispiele. Sind diese auch Praxisnah?
die frage ist ob die vorher genau sagen kannst wie viele Sprachen es
sind. Dann könnte man es als Spalten ablegen, wenn aber später sprachen
hinzukommen ist die Extra Tabelle eine besser lösung.
man könnte auch nur eine übersetzungstabelle machen:
ArtId Name
1 Tastatur
Name LANG TEXT
Tastatur ENG Keyboard
das hätte den Vorteil das man Wenn es mehrfach die Tastatur gibt, nicht
jedes mal neu die übersetzung eintragen muss. Und ein schneller zugriff
auf den default Sprache vorhanden ist.
> Und gerade Artikel> können ja durchaus auch mal mehr werden (500.000+).
mal 100 dann wird es viel. 500.000 kann man ja noch mit access
verwalten.
Peter schrieb:> Das würde doch in etwa dem entsprechen, dass ich z.B. in einer> Personentabelle die Wohnorte einer Person auch in eine eigene Tabelle> auslagere.
Den Wohnort übersetzt du aber auch nicht. Allerdings kann es durchaus
auch sinnvoll sein, den Wohnort in eine Tabelle auszulagern. Nämlich
dann, wenn das nicht einfach nur ein dämliches Feld ist, sondern da mehr
dahintersteckt, wie zb Verknüpfung mit der Postleitzahl, Position des
nächsten Auslieferungslagers, Link zur Gemeinde-Hompage, etc.
Dein Artikel hat als Artikeltext ganz einfach ein 'Feld', für welches es
abhängig von einer anderen Einstellung mehrere Möglichkeiten gibt.
Wenn du ein Auto beschreiben müsstest, würdest du ja auch ein Feld
'Farbe' mit einer Farb-Id vorsehen und in einer getrennten Tabelle davon
diese Farb-Id zu einem Namen, einer Bitmap, einer RAL-Nummer, dem
Hersteller des Lacks etc. aufschlüsseln. Gibt es wiederrum mehrere
Lackherstelller, dann steht dort wieder eine Hersteller-Id und in einer
weiteren Tabelle die möglichen Hersteller.
Willst du also wissen, wer den Lack für das Auto liefert, musst du dir
die Info über mehrere Stufen zusammensuchen - abhängig von der Lack-Id
und der Hersteller-Id
Bei dir ist das dann eben Text-Id (vom Artikel) und Sprach-Id (globale
Einstellung)
> man könnte auch nur eine übersetzungstabelle machen:>> ArtId Name> 1 Tastatur>> Name LANG TEXT> Tastatur ENG Keyboard
Vorsicht mit solchen Sachen. Das sieht auf den ersten Blick wie die
Lösung des Problems aus, schafft aber oft wieder neue Probleme. Eine
davon ist: Tippfehler und unterschiedliche Schreibweisen, die keinem
auffallen. Ein anderes Problem ist, dass es selten Artikeltexte ala
"Tastatur" gibt. Sondern da steht dann "Tastatur Cherry XYZ850/32". Was
jetzt? Dafür eine eigene Übersetzung anfertigen? DIe Übersetzung
wortweise zusammenstoppeln? Was ist, wenn der Hersteller ein paar Dinge
überhaupt nicht übersetzt. Ikeas 'Billy' heißt meines Wissens weltweit
überall "Billy". Aber das Regal "Billy May" könnte in Thailand
"Judo-San" heißen.
Meine Erfahrung: Übersetzungshilfen - ja.
Aber lieber bei der Eingabe der Übersetzungen entsprechenden Aufwand
treiben. Im Notfall muss es immer möglich sein, das System zu overrulen
und eine Übersetzung gezielt händisch vorzunehmen. Dazu muss aber der
Daten-Aufbau stimmen. Fliesst die Übersetzung im Nachhinein irgendwie
automatisch in das System ein, dann gibt das meistens Ärger. Zb. auch
dann wenn ein Muttersprachler die thailandische Übersetzung "Judo-San"
wegen eines Schreibfehlers korrigieren möchte. Da "Judo-San" in der
Datenbank aber gar nicht existiert, sondern aus Einzelwörtern
zusammengesetzt (und übersetzt) wurde, gibt es nichts, was er
korrigieren könnte. Und führt man die Übersetzung auf die Einzelworte
zurück aus denen sie entstanden ist, dann läuft man wieder Gefahr, Dinge
zu ändern, die eigentlich nicht geändert werden sollte. Die Übersetzung
von "Smoerebroed", welche ursprünglich "San" war, soll dann eben nicht
plötzlich "Son" lauten, nur weil aus "Judo San" ein "Judo Son" werden
musste.
Hallo,
ganz und gar ketzerischer Vorschlag: die Datenbank ist einsprachig,
übersetzt wird im Frontend, also ist die Bezeichnung Keyboard und auf
einem Bildschirm in Deutschland erscheint Tastatur. Damit kann man auf
Standard-Wörterbücher zurückgreifen, aber natürlich muss das erweiterbar
sein z.B. für Fachbegriffe, die dort nicht zu finden sind.
Klar geht das nicht in allen Fällen, aber ich habe schon vor Jahren
selbst eine Sprach-Datei aufgebaut für meine CNC-Steuerungen, die nach
Bedarf erweitert wurde - da ich ja nur Deutsch und Englisch wirklich
beherrsche, habe ich die ganze (textbasierte) Datei einem Übersetzer
übergeben, der dann für z.B. "Positionierung läuft" den entsprechenden
russischen Text eingegeben hat.
Internationale Modellbezeichnungen sind ein Thema für sich, aber
bestimmte Fordautos heissen ja nicht nur in Europa anders als in USA,
sondern sind auch anders ausgestattet, da ist der Name noch das
geringste Problem. Sowas wie Quashquai ist auch kein wirkliches Wort in
irgendeiner Sprache.
Gruss Reinhard
> Das ist die Lösung die im Globalize3 Gem bei Ruby on Rails verwendet> wird.
Übermässig normalisiert und damit übermässig langsam.
> Sind diese auch Praxisnah?
Nein.
Du solltest die Datenbankstruktur nicht ändern müssen,
wenn eine Sprache hinzukommt. Also klar deine Lösung 1
SpracheId|Artikelnummer|Artikeltext
---------+-------------+-----------
1 |0815 |Tastatur
2 |0815 |Keyboard
1 |4711 |Kabel
2 |4711 |Cable
Du solltest dafür sorgen, daß eigentlich alle Abfragen
so aussehen als ob sie nichts von der aktuellen Sprache
wüssten.
Das WHERE SpracheId=1 sollte also transparent für deine
Anwendung sein, das kann man mit einer VIEW erreichen.
Du solltest dafür sorgen, daß nicht alle Einträge
lokalisiert sein müssen, sondern auch Tabelle ohne
spachspezifika existieren können.
Auch das geht gut mit einer VIEW, denn du weisst ja durch
die VIEW gar nicht, ob die Tabelle eine SpracheId Spalte
hat oder nicht.
Reinhard Kern schrieb:> ganz und gar ketzerischer Vorschlag: die Datenbank ist einsprachig,> übersetzt wird im Frontend, also ist die Bezeichnung Keyboard und auf> einem Bildschirm in Deutschland erscheint Tastatur. Damit kann man auf> Standard-Wörterbücher zurückgreifen, aber natürlich muss das erweiterbar> sein z.B. für Fachbegriffe, die dort nicht zu finden sind.
Frontend-Übersetzungen sollte man nur von Dingen machen die auch im
Frontend angesiedelt sind, z.B. HTML-Dateien sonst wird das nach einiger
Zeit einfach nur chaotisch.
In RoR zum Beispiel kann man für seine views (die dann zu HTML gerendert
werden) .yml-Dateien für I18n-Internationalisierung anlegen und diese
dann verwenden. Das hat den Vorteil dass man alle Frontend-Texte
gebündelt hat und wenn man sich entschließt eine neue Sprache
einzuführen kann man einem Übersetzer einfach diese Text-Dateien geben
ohne auch nur einen Furz View-Logic rausgeben zu müssen.
MaWin schrieb:>> Das ist die Lösung die im Globalize3 Gem bei Ruby on Rails verwendet>> wird.>> Übermässig normalisiert und damit übermässig langsam.>>> Sind diese auch Praxisnah?>> Nein.>> Du solltest die Datenbankstruktur nicht ändern müssen,> wenn eine Sprache hinzukommt. Also klar deine Lösung 1
Nun es gibt genug Anwendungsfälle wo man die Texte und Übersetzungen für
die meisten Berechnungen garnicht braucht, dann müssen die entweder erst
mühsam rausprojeziert werden via SELECT (CPU-Last), oder du hast eine
RAM-Verschwendung via SELECT *, kommt besonders dann zum tragen wenn zu
kleinen Bezeichnungen umfangreiche Artikelbeschreibungen kommen, also
nicht nur VARCHAR sondern TEXT-Spalten. DAS ist dann langsam wie sau.
Da tut ein kleiner JOIN, der vorher meist durch ein WHERE
zurechtgestutzt wird deutlich weniger weh, wenn man die Texte
tatsächlich braucht, denn üblicherweise sind solche Verknüpfungen auch
noch indiziert...
Die Datenbänkler haben die letzten 25 Jahre nicht geschlafen...
MaWin schrieb:> Du solltest die Datenbankstruktur nicht ändern müssen,> wenn eine Sprache hinzukommt. Also klar deine Lösung 1
Aber wenn neue Sprachen vorkommen müsste ich die Views anpassen, oder?
Wie sieht es eigentlich mit der Performance bzgl. Views aus. Auch hier
denke ich dass es ähnliche neg. Effekte wie bei Joins gibt, oder?
Wie Du auch schon geschrieben hast: übermäßig normalisiert. Das ist
denke ich der Punkt. Wahrscheinlich läuft es wieder um das Abwägen der
Pros und Contras ab.
Was Karl Heinz Buchegger geschrieben hat, kann ich gut nachvollziehen.
Das mit der Einzelwortübersetzung würde ich nur für Bestimmte "Terme"
verwenden (z.B. "Artikelnummer", "Seite", "vor", "zurück" etc...). Aber
bei Texten ist das denke ich alleine durch die andere Anordnung der
Wörter innerhalb der verschiedenen Sprachen nicht sinnvoll. Sonst kommt
sowas in der Art wie bei Google-Translator (in den Anfängen) raus:
rechtlich: physikalisch:
"Haftung ausgeschlossen" >> "Adhesion impossible"
Viele Grüße,
Peter
Peter schrieb:> Aber wenn neue Sprachen vorkommen müsste ich die Views anpassen, oder?> Wie sieht es eigentlich mit der Performance bzgl. Views aus. Auch hier> denke ich dass es ähnliche neg. Effekte wie bei Joins gibt, oder?>> Wie Du auch schon geschrieben hast: übermäßig normalisiert. Das ist> denke ich der Punkt. Wahrscheinlich läuft es wieder um das Abwägen der> Pros und Contras ab.
Ich weiß ja nicht mit was für Datenbankkrücken ihr im letzten
Jahrtausend gearbeitet habt, aber Joins sind mittlerweile Gang und Gäbe.
Natürlich muss man beim Normalisieren aufpassen nicht übers Ziel
hinauszuscheißen und es zu übertreiben.
Aber so verhunzte Schemata wie Lösung 1 oder noch schlimmer lassen einem
regelmäßig die Haare zu Berge stehen. Man sollte sich ein bisschen
Wartbarkeit und Flexibilität für die Zukunft gönnen.
die "Lösung" von MaWin ist ja wohl suboptimal
da hat man ja schon "Probleme" die Artikelnummer zu ändern..
und es gibt vermutlich ja noch weitere Felder, in der Tabelle Artikel,
die man dann ständig synchron halten müsste
>. Wahrscheinlich läuft es wieder um das Abwägen der>Pros und Contras ab.
deshalb: sag ich ja, dass man die "Hauptsprache" in Artikel lässt, und
eine übersetzungs-tabelle..
das ist IMHO die Praktikabelste lösung, weil es in der Praxis eben oft
an den Resourcen fehlt, alles bis ins letzte zu übersetzten. So hat man
IMMER einen Fallback der funktioniert..
Robert L. schrieb:> da hat man ja schon "Probleme" die Artikelnummer zu ändern..
Der Primärschlüssel darf sich in einem ordentlichen Datenbankdesign
nicht ändern. Ggf. muss eine neue Spalte für die dem Endnutzer
angezeigte Artikelnummer angelegt werden, wenn es möglich sein soll
diese frei zu gestalten bzw. zu ändern.
@ Andreas Schwarz
ja, sag ich ja..
>wenn es möglich sein soll>diese frei zu gestalten bzw. zu ändern.
und nachdem diese ja nicht normalisiert wäre, müsste man bei alle
Artikel mit der selben Artikel_ID die Artikelnummer immer "manuell"
synchron halten..
ein 2. aspekt ist ja, dass Mehrsprachigkeit meistens erst später
hinzukommt, es also 100mal einfacher ist eine zusätzliche "übersetzungs"
tabelle zu machen, als die vorhandene Artikel tabelle aufzubohren...
IMHO ist der Vorschlag von MaWin bisher der schlechteste von allen...
> Wie sieht es eigentlich mit der Performance bzgl. Views aus. Auch hier> denke ich dass es ähnliche neg. Effekte wie bei Joins gibt, oder?
Nöö. Denn das hängt einfach davon ab, wie komplex die Joins sind, und
natürlich auch, wie komplex das Abfrage-SQL selber ist. Letztendlich ist
es das sich aus der View und dem SQL ergebende effektive SQL, welches
darüber entscheidet, wie die Performanceeffekte sich gestalten.
Wenn Du ein View v1 as select * from t1 hast, dann ändert das effektiv
gar nichts, wenn ich die View statt Tabelle benutze ;-)
Ich denke auch, daß MaWins Lösung nicht gerade sehr zeitgemäß ist. Der
Join von mehreren Tabellen ist doch eher ein klacks, solange die
Tabellen (wenn es größere sind) einigermaßen sinnvoll indiziert sind,
und nicht zu viele Rows in die WHERE-Bedingung passen.