2009-08-24 15 views
8

Ich habe eine Reihe von Datenbanktabellen, die name und description Spalten enthalten, die lokalisiert werden müssen. Mein erster Versuch, ein DB-Schema entwerfen, das war so etwas wie unterstützen würde:Datenbank-Lokalisierung

product 
------- 
id 
name 
description 


local_product 
------- 
id 
product_id 
local_name 
local_description 
locale_id 


locale 
------ 
id 
locale 

Diese Lösung ist jedoch eine neue local_ Tabelle für jede Tabelle benötigt, die name und Beschreibung Spalten enthält, die localization erfordern. In einem Versuch, diesen Aufwand zu vermeiden, neu gestaltete ich das Schema, so dass nur eine einzige localization Tabelle benötigt wird

product 
------- 
id 
localization_id 


localization  
------- 
id  
local_name 
local_description 
locale_id 


locale 
------ 
id 
locale 

Hier ein Beispiel für die Daten ist, die in diesem Schema gespeichert werden würden, wenn es 2 Tabellen (Produkt und Land) erfordern Lokalisierung:

Land

id,  localization_id 
----------------------- 
1,  5 

Produkt

id,  localization_id 
----------------------- 
1,  2 

Lokalisierungs

id,  local_name, local_description,  locale_id 
------------------------------------------------------ 
2,  apple,  a delicious fruit,  2 
2,  pomme,  un fruit délicieux, 3 
2,  apfel,  ein köstliches Obst, 4 
5,  ireland,  a small country,  2 
5,  irlande,  un petite pay,   3 

locale

id,  locale 
-------------- 
2,  en 
3,  fr 
4,  de 

Hinweis, dass die Verbindung Primärschlüssel der localization Tabelle ist (id, locale_id), aber die Fremdschlüssel in der product Tabelle bezieht sich nur auf das erste Element dieser Verbindung PK. Dies scheint eine "schlechte Sache" aus dem POV der Normalisierung zu sein.

Gibt es eine Möglichkeit, dieses Problem zu beheben, oder gibt es alternativ ein vollständig anderes Schema, das Lokalisierung unterstützt, ohne eine separate Tabelle für jede lokalisierbare Tabelle zu erstellen?

Aktualisierung: Eine Anzahl von Befragten hat eine Lösung vorgeschlagen, die das Erstellen einer separaten Tabelle für jede lokalisierbare Tabelle erfordert. Genau das versuche ich jedoch zu vermeiden. Das Schema, das ich oben vorgeschlagen habe, löst das Problem fast zu meiner Zufriedenheit, aber ich bin nicht glücklich darüber, dass sich die Fremdschlüssel nur auf einen Teil des entsprechenden Primärschlüssels in der Tabelle localization beziehen.

Danke, Don

+1

"aber ich bin unglücklich darüber, dass sich die Fremdschlüssel localization_id nur auf einen Teil des entsprechenden Primärschlüssels in der Lokalisierungstabelle beziehen". Ich sehe das Problem nicht, es gibt eine Eins-zu-viele-Beziehung vom Produkt zur Lokalisierung, die Datenbankstruktur folgt den Anforderungen, Sie haben eine gute Lösung gefunden. –

+0

Dies sollte auf http://dba.stackexchange.com/ –

Antwort

1

Der richtige Weg, ich fühle, wäre die zusätzliche Tabelle zu erstellen, aber dann den zusätzlichen Schritt gehen und alle sprachspezifischen Ressourcen aus der ersten Tabelle entfernen.

So müssten Sie:

Produkt

id 
-name removed 
-description removed 

Produktlokalisierung

productid, locale_id, name, description 
------------------------------------------------------ 
1,   3,   pomme, un fruit délicieux 
1,   4,   apfel, ein köstliches Obst 
1,   1,   apple, a delicious fruit 

locale

id,  locale 
-------------- 
1,  en 
3,  fr 
4,  de 
+0

veröffentlicht werden Dieses Schema wird nicht funktionieren, wenn es mehr als eine Tabelle mit lokalisierbarem Inhalt gibt –

+0

Sie benötigen eine zusätzliche Tabelle pro lokalisierbarem Inhalt. Ich denke nicht, dass du das umgehen kannst. Einige lokalisierbare Tabellen haben möglicherweise keine Namen oder Beschreibungen, oder mehr Felder, die übersetzt werden müssen. Dies bricht natürlich die besten Praktiken für Normalisierungen. Verwenden Sie die zusätzlichen Tabellen. – DanDan

+0

In diesem Fall kann man davon ausgehen, dass * jede * lokalisierbare Tabelle nur einen Namen und eine Beschreibung benötigt, um lokalisiert zu werden –

3

Ich denke, es ist in Ordnung. Sie beschreiben eine Eins-zu-Viele-Beziehung zwischen einem Produkt und seinem Lokalisierungstext.

Ich frage mich, ob Sie auch das Englisch lokalisieren sollten, anstatt es in Ihrer Produkttabelle zu denormalisieren.

+0

Ich habe das Schema geändert, um Ihren Vorschlag zu übernehmen –

+2

Der ganze Punkt der Lokalisierung ist, dass es eine Eins gibt -viele Beziehung zwischen dem "Ding" und dem Namen. Daraus folgt natürlich, dass eine Referenz in der "Ding" -Tabelle kein vollständiger Primärschlüssel für die Lokalisierungstabelle sein kann, da dies die Beziehung zu Eins-zu-Eins einschränken würde. Der gebräuchlichere Weg, eine Viele-zu-Eins-Beziehung herzustellen, besteht darin, den Bezeichner des "Eins" -Endes in das "Viele" -Ende zu schreiben, aber Sie hätten hier ein Problem, wie es die Lokalisierungstabelle dann tun müsste referenzieren Sie viele verschiedene Tabellen, was zu einer unordentlichen, lose definierten Fremdschlüsselreferenz führt. – Jay

1

Wenn ich richtig verstehe, ist Ihr Problem nur, weil Sie die gleiche Sprachlokalisierung für Name und Beschreibung in mehr als einer Tabelle verwenden möchten. In einem solchen Szenario können Sie die Produkt-ID nicht in der Lokalisierungstabelle hinzufügen. Ein weiteres Problem in Ihrem Design ist, dass es nicht mehr als eine Sprachlokalisierung für das gleiche Produkt elegant verarbeiten kann. Sie können es zwicken, um zu arbeiten:

Wenn Name und Beschreibung die einzigen Felder sind, die Lokalisierung erfordern, können Sie das folgende tun.

Produkt (ID, Name, Beschreibung, tanslation_row_id)

Product_translations (ID, Name, Beschreibung, lang_id, translation_id)

Der translation_row_id Fremdschlüssel zeigt auf Product_translations.ID Die translation_id wird sein, Zeigen Sie jedoch einen übergeordneten Datensatz in derselben Tabelle, die als gemeinsamer Datensatz für alle sprachspezifischen Datensätze dienen würde.

Beispiel Aufzeichnungen

Artikel

(ID, name, description, translation_row_id) 
(p1, apples,a red fruit, tr1) 
(p2, mango, a yellow fruit, tr2) 

Product_translations

(ID, name, description, lang_id, translation_id) 
(tr1, apples, a red fruit, ENU, null) 
(tr2, mango, a yellow fruit, null) 
(tr3, pomme,un fruit rouge, FRA,tr1) 
(tr4, mangue,a yellow fruit, SPA,tr2) 

ein Sprachcode gegeben, können Sie die Namen und die Beschreibung Werte mit der folg SQL-Abfrage

select T.name, T.description 
from product_translations T 
where T.translation_id = 
    (select T2.ID 
     from Product P,Product_translations T2 
     where P.translation_row_id = t2.ID 
    ) 
    and T.lang_id = '&langID'; 
extrahieren

Wichtiger Hinweis: Ich gehe davon aus, dass die Produkttabelle viele weitere Attribute enthält, die diese Übersetzung nicht benötigen. ‚& SprachID‘ ist ein Parameter für die SQL-Abfrage, die dem Benutzer des Sprachcode seiner Wahl

+0

Toller Vorschlag, ich könnte es versuchen. Ich werde jedoch wahrscheinlich den Namen und die Beschreibung aus den Produkttabellen (und anderen lokalisierbaren Tabellen) entfernen, da sie überflüssig zu sein scheinen. Außerdem sollte die Tabelle product_translations etwas allgemeineres wie "Übersetzungen" genannt werden, da sie in Wirklichkeit lokalisierte Länder, Produkte usw. enthält. –

2

ich die Idee mag fragen würde, würde aber einen Schritt in der anderen Richtung gehen, und einen Lokalisierungs Eintrag für jede Spalte das heißt übersetzt:

Land

id,  localization_id 
----------------------- 
1,  5 

Produkt

id,  name_locale_id, description_locale_id 
---------------------------------------------- 
1,  2,    8 

Lokalisierung

id,  locale_id, value 
------------------------------------------------------ 
2,  2    apple 
2,  3    pomme 
2,  4    apfel 
5,  2    ireland 
5,  3    irlande 
8,  2    a delicious fruit 
8,  3    un fruit délicieux 
8,  4    ein köstliches Obst 
9,  2    a small country 
9,  3    un petite pay 

locale

id,  locale 
-------------- 
2,  en 
3,  fr 
4,  de 

Der PK von Lokalisierungs ist (id, locale_ID). Es ist kein Problem, dass id auch in mehreren anderen Tabellen eine FK-Referenz ist. Sie können einen Ersatz-PK hinzufügen, wenn Sie möchten, solange Sie noch einen eindeutigen Index für (id, locale_id) haben.

Das schöne daran ist, es ist eine einzige Lokalisierungstabelle, und es funktioniert für jede Tabelle in Ihrem Schema, unabhängig davon, welche Felder es hat (Sie sind nicht beschränkt auf Name und Beschreibung von allem, das lokalisiert wird) . Der Nachteil ist ein potenzieller Performance-Hit bei der Verwendung der Lokalisierungstabelle - obwohl Sie möglicherweise das Ganze für eine gegebene locale_id einfach zwischenspeichern könnten. Wenn Sie also Einträge suchen, müssen Sie nur nach der gegebenen ID suchen (da Ihr Cache ist basierend auf der Sprache bereits eingegeben).

Sie können auch in der Produkttabelle Standardnamen- und -beschreibungsfelder belassen, die für den Fall verwendet werden, dass für die aktuelle Sprache ein Eintrag fehlt oder der Benutzer bei der Eingabe keine Sprache angegeben hat. Dies ist auch der Fall, wenn Sie eine vorhandene App portieren. Sie haben dort bereits Werte (ohne Gebietsschema-Informationen).