aafreak Geschrieben 23. März 2009 Teilen Geschrieben 23. März 2009 Also ich habe folgendes Problem. Nehmen wir an ich möchte eine Artikelverwaltung schreiben, meine Datenbank ist so aufgebaut: Tabelle: Artikel - Artikelnummer - Artikelbezeichnung - EK_Preis - VK_Preis_Netto - MwSt - Artikelgruppe - Einheit ... Tabelle: Artikelgruppen - ID - ParentID - Bezeichnung Tabelle: Einheiten - ID - Bezeichnung Wenn ich jetzt Artikel, Artikelgruppen und Einheiten anlege gebe ich deutsche Bezeichnungen ein. Nun meine Frage: Wie sollte die Datenbank aussehen wenn die Bezeichnungen in n verschiedenen Sprachen eingegeben werden könnten. Hab mir dazu etwas überlegt: Bsp1.: Tabelle: Artikel - Artikelnummer - Artikelbezeichnung_Deutsch - Artikelbezeichnung_Englisch - Artikelbezeichnung_Französisch - Artikelbezeichnung... ... - EK_Preis - VK_Preis_Netto - MwSt - Artikelgruppe - Einheit ... Tabelle: Artikelgruppen - ID - ParentID - Bezeichnung_Deutsch - Bezeichnung_Englisch - Bezeichnung_Französisch - Bezeichnung_... ... Tabelle: Einheiten - ID - Bezeichnung_Deutsch - Bezeichnung_Englisch - Bezeichnung_Französisch - Bezeichnung_... ... Ist leider eine schlechte Lösung wie jeder sieht... Bsp2.: Für jede Tabelle in der Text drin vorkommt gibt es eine Language Tabelle ("Lang_"). ID ist die verknüpfung mit der Originaltabelle und LanguageId ist einfach z.B. 1 für Englisch, 2 für Franz usw... Tabelle: Artikel - Artikelnummer - Artikelbezeichnung - EK_Preis - VK_Preis_Netto - MwSt - Artikelgruppe - Einheit ... Tabelle: Lang_Artikel - Artikelnummer - LanguageId - Artikelbezeichnung Tabelle: Artikelgruppen - ID - ParentID - Bezeichnung Tabelle: Lang_Artikelgruppen - ID - LanguageID - Bezeichnung Tabelle: Einheiten - ID - Bezeichnung Tabelle: Lang_Einheiten - ID - LanguageID - Bezeichnung Problem: Um eine Liste aller Artikel anzuzeigen bräuchte ich einen SQL-String mit 5 JOIN's um die Daten aus allen 6 Tabellen herzuholen und muss dann jedesmal auf die LanguageId abfragen. Und naja je mehr Tabellen ich nacher habe um so mehrere JOIN's brauch ich. Auch nicht die optimale Lösung Naja ich bin immer noch nach der suche wie man soetwas am besten aufbaut. Wäre super wenn mir bei diesem Problem jemand helfen könnte. Es geht nicht um die GUI, sondern um die abgespeicherten Daten in der Datenbank. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
flashpixx Geschrieben 23. März 2009 Teilen Geschrieben 23. März 2009 Ich sehe bei 5 Joins nicht wirklich das Problem. Ich würde ggf das dann noch über Views lösen, sprich ein View pro Sachverhalt, wo man anhand der ID verweist. Sprich der View liefert für alle Sprachen und einen Datensatz die entsprechende Bezeichnung zurück Phil Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
VaNaTiC Geschrieben 24. März 2009 Teilen Geschrieben 24. März 2009 die Sprach-Bezeichnungen in die eigentlichen Datentabellen einzufügen hat wenig mit RDBMS zu tun. Fakt ist das dies trotzdem gemacht wird, meistens aber genau dann, wenn zuviele inner join oder zu lange dauern, weil einfach zig-Millionen Records in den betroffenen Tabellen sind. Der bessere Weg ist allemal die Sprach-Bezeichnungen in (eine) eigene Tabelle auszulagern. Eventuell ist es von Vorteil nur eine Tabelle (mit TextID, LangID, Text) zu machen. Das hat u.U. Vorteile beim Cachen. Aber für verschiedene IDs in einem select brauchst Du trotzdem dann verschiedene inner join. Aber ein Vorteil ist, dass Du dann wenn es wirklich Engpäße gibt, die nicht mit Keys oder Cache behandelt werden können, einfach die Text-Tabelle beim Start der GUI lädst und das Verknüpfen mit Texten dort erledigst. Und eine Frage hab ich noch: Wie realisierst Du, wenn bsp zu einer Artikelnummer und der LangId keine Bezeichnung existiert? Stored Procedure mit Id als Param und Rückgabe des Strings und da drin einen select auf LangID='1' or LangID='0' // default ? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
dr.dimitri Geschrieben 24. März 2009 Teilen Geschrieben 24. März 2009 Bsp2.: Für jede Tabelle in der Text drin vorkommt gibt es eine Language Tabelle ("Lang_"). ID ist die verknüpfung mit der Originaltabelle und LanguageId ist einfach z.B. 1 für Englisch, 2 für Franz usw... So würde ich das machen. Damit bist Du auch flexibel, wenn es mal eine weitere Sprache geben soll. Ganz zu schweigen von Volltextindizierungen etc. die evtl noch benötigt werden. Allerdings solltest Du dann die Felder Artikelbezeichnung und Bezeichnung aus den entsprechenden Tabellen entfernen - dafür sind ja die _lang tabellen vorgesehen. Aber ein Vorteil ist, dass Du dann wenn es wirklich Engpäße gibt, die nicht mit Keys oder Cache behandelt werden können, einfach die Text-Tabelle beim Start der GUI lädst und das Verknüpfen mit Texten dort erledigst. Jaja die alte Legende, dass die Anwendung besser und schneller joint als die Datenbank :old Wie realisierst Du, wenn bsp zu einer Artikelnummer und der LangId keine Bezeichnung existiert? Stored Procedure mit Id als Param und Rückgabe des Strings und da drin einen select auf LangID='1' or LangID='0' // default ? In einem Inner Join würde dieser Artikel nicht geliefert werden, bei einem Outer Join kann man auf NULL abfragen und dann darauf reagieren. Warum sollte man hier mit einer SP arbeiten? Dim Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
VaNaTiC Geschrieben 24. März 2009 Teilen Geschrieben 24. März 2009 Jaja die alte Legende, dass die Anwendung besser und schneller joint als die Datenbank :old Von "besser", "schneller" und "Anwendung" hab ich nix gesagt. Es war nur ein Tipp, dass es auch Alternativen gibt. Aber Fakt ist, es gibt sehr wohl Anwendungsfälle und Datenbestände wo mehrere joins weder sinnvoll noch performant sind und in der UI per Hash in einer Map besser aufgehoben sind. In einem Inner Join würde dieser Artikel nicht geliefert werden, bei einem Outer Join kann man auf NULL abfragen und dann darauf reagieren. Warum sollte man hier mit einer SP arbeiten? Muss ich dann nicht zweimal aus der aufrufenden Umgebung abfragen? Ob extra eine NULL-Logik Sinn macht, beispielsweise in einem MVC-Pattern, halte ich auch nicht für optimal. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
dr.dimitri Geschrieben 24. März 2009 Teilen Geschrieben 24. März 2009 Aber Fakt ist, es gibt sehr wohl Anwendungsfälle und Datenbestände wo mehrere joins weder sinnvoll noch performant sind und in der UI per Hash in einer Map besser aufgehoben sind. Da wär mir noch keiner Untergekommen. Einzig, dass man oft benutzte Daten cached um nicht mehr auf die DB zugreifen zu müssen (bedingt natürlich auch, dass es sich um statische Daten handelt). Wenn du das gemeint hast, hab ich das falsch verstanden, andernfalls liegt das Problem meistens in der Art und Weise wie der Join geschrieben ist, ob die Statistiken korrekt sind etc. Muss ich dann nicht zweimal aus der aufrufenden Umgebung abfragen? Ob extra eine NULL-Logik Sinn macht, beispielsweise in einem MVC-Pattern, halte ich auch nicht für optimal. Nein Du frägst im SQL selbst ab: SELECT ...NVL(evtl_null_spalte,'Wert der bei NULL zurückgegeben werden soll'),... Dim Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
aafreak Geschrieben 24. März 2009 Autor Teilen Geschrieben 24. März 2009 Ich denke ich werd das so machen wie dr.dimitri beschreiben hat. Scheint mir die besten Lösung zu sein. Dankeschön für die Hilfe. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
VaNaTiC Geschrieben 24. März 2009 Teilen Geschrieben 24. März 2009 ... Einzig, dass man oft benutzte Daten cached um nicht mehr auf die DB zugreifen zu müssen ... genau ... Nein Du frägst im SQL selbst ab: SELECT ...NVL(evtl_null_spalte,'Wert der bei NULL zurückgegeben werden soll'),... Würde denn sowas auch gehen? SELECT ...NVL(evtl_null_spalte,select text from ... where langcode = 'default'),... Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
dr.dimitri Geschrieben 24. März 2009 Teilen Geschrieben 24. März 2009 Würde denn sowas auch gehen? Unter Oracle ja, das SQL muss nur eingeklammert werden: select nvl(spalte,(select ....))as bezeichnung ... Die Abfrage darf nur eine Zeile zurückgeben, ansonsten geht's natürlich nicht. Du kannst z.B. auch sowas machen: SELECT CASE spalte WHEN 'ABC' THEN (select ...) WHEN 'XYZ' THEN (select ...) ELSE 'Nix geht mehr' END AS spaltenname FROM tabelle Dim Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.