29

Ich muss ein großes DB-Modell für eine Webanwendung erstellen, die mehrsprachig ist.Datenbankmodellierung für internationale und mehrsprachige Zwecke

Ein Zweifel, dass ich jedes Mal, wenn ich darüber nachdenke, wie ich es mache, ist, wie ich multiple Übersetzungen für ein Feld lösen kann. Ein Fallbeispiel.

Die Tabelle für Sprachlevel, die Administratoren aus dem Backend bearbeiten können, kann mehrere Elemente haben: basic, advance, fluent, mattern ... In naher Zukunft wird es wahrscheinlich noch einen Typ geben. Der Administrator geht zum Backend und fügt eine neue Ebene hinzu, es wird an der richtigen Stelle sortiert. Aber wie handhabe ich alle Übersetzungen für die Endbenutzer?

Ein weiteres Problem mit der Internationalisierung einer Datenbank ist, dass wahrscheinlich für Benutzer Studien von USA nach UK zu DE variieren kann ... in jedem Land werden sie ihre Ebenen haben (das wird wahrscheinlich zu einem anderen, aber schließlich, anders) . Und was ist mit Abrechnung?

Wie modellieren Sie das in großem Maßstab?

+3

Nebenbei, stellen Sie sicher, dass Sie Ihre Tabellen mit UTF-8-Codierung erstellen. –

+0

Welche Technologie verwenden Sie? Die meisten der bestehenden Frameworks verwalten i18n ziemlich gut. – sp00m

+0

@ sp00m: Ich benutze PHP. Es gibt kein Problem mit der Sprache der Website, den "statischen". Ich frage nach Dingen, die Administratoren aus dem Backend der Website hinzufügen können ... wenn sie hinzufügen, können sie nicht 15 Sprachen für nur 1 Element hinzufügen. Wahrscheinlich ist es auch nicht richtig, zu diesem Thema über Sprach-/Sprachlevel zu sprechen. Oder sagst du, dass es auch in Datenbanken gut geht? Vielen Dank! – udexter

Antwort

48

Hier ist die Art, wie ich die Datenbank entwerfen würde:

Data model

Visualisierung von DB Designer Fork

Die i18n Tabelle enthält nur eine PK, so dass jede Tabelle nur hat Verweise auf diese PK, um ein Feld zu internationalisieren. Die Tabelle translation ist dann verantwortlich für die Verknüpfung dieser generischen ID mit der korrekten Liste der Übersetzungen.

locale.id_locale ist ein VARCHAR(5)ISO syntaxes beide en und en_US zu verwalten.

currency.id_currency ist ein CHAR(3) zur Verwaltung der ISO 4217 syntax.

Sie können zwei Beispiele finden: page und newsletter. Diese beiden admin-verwalteten-Entities müssen ihre Felder bzw. title/description und subject/content internationalisieren. Hier

ist ein Beispiel Abfrage:

select 
    t_subject.tx_translation as subject, 
    t_content.tx_translation as content 

from newsletter n 

-- join for subject 
inner join translation t_subject 
    on t_subject.id_i18n = n.i18n_subject 

-- join for content 
inner join translation t_content 
    on t_content.id_i18n = n.i18n_content 

inner join locale l 

    -- condition for subject 
    on l.id_locale = t_subject.id_locale 

    -- condition for content 
    and l.id_locale = t_content.id_locale 

-- locale condition 
where l.id_locale = 'en_GB' 

    -- other conditions 
    and n.id_newsletter = 1 

Beachten Sie, dass dies ein normalisiertes Datenmodell. Wenn Sie einen riesigen Datensatz haben, könnten Sie vielleicht an denormalizing it denken, um Ihre Abfragen zu optimieren. Sie können auch mit Indizes spielen, um die Leistung der Abfragen zu verbessern (in einigen Datenbanken werden Fremdschlüssel automatisch indiziert, z. B. MySQL/InnoDB).

+1

OK, es ist sehr einfach verständlich und nützliche Erklärung. Die einzige Frage, die ich habe - wäre das im Sinne von Speicher- und Server-Ressourcen nicht teuer, TEXT-Typ für jede lokalisierte Zeichenkette zu verwenden? –

+0

@f_martinez Ich denke, es hängt von den Daten ab, die Sie speichern müssen. Aber verwenden Sie den Typ, den Sie brauchen, wenn er zum Beispiel in ein Varchar passt. – sp00m

+6

Nicht mischen ** Währung ** und ** Übersetzung **. – gavenkoa

27

Einige frühere Stackoverflow Fragen zu diesem Thema:

einige nützliche externe Ressourcen:

Der beste Ansatz ist oft, für jeden vorhandenen Tabelle, erstellen Sie eine neue Tabelle, in die Textelemente bewegt werden; Die PK der neuen Tabelle ist die PK der alten Tabelle zusammen mit der Sprache.

In Ihrem Fall:

  1. Die Tabelle für Sprachebene, die Administratoren aus dem Backend bearbeiten können, kann wie mehrere Elemente hat: einfach, voraus, fließend, Mattern ... In der Nähe von Zukunft wird es wahrscheinlich ein weiterer Typ sein. Der Administrator geht zum Backend und fügt eine neue Ebene hinzu, es wird an der richtigen Stelle sortiert. Aber wie handhabe ich alle Übersetzungen für die Endbenutzer?

    Ihre vorhandene Tabelle sieht wahrscheinlich so etwas wie folgt aus:

     
    +----+-------+---------+ 
    | id | price | type | 
    +----+-------+---------+ 
    | 1 | 299 | basic | 
    | 2 | 299 | advance | 
    | 3 | 399 | fluent | 
    | 4 |  0 | mattern | 
    +----+-------+---------+ 
    

    Es wird dann zwei Tabellen:

     
    +----+-------+ +----+------+-------------+ 
    | id | price | | id | lang | type  | 
    +----+-------+ +----+------+-------------+ 
    | 1 | 299 | | 1 | en | basic  | 
    | 2 | 299 | | 2 | en | advance  | 
    | 3 | 399 | | 3 | en | fluent  | 
    | 4 |  0 | | 4 | en | mattern  | 
    +----+-------+ | 1 | fr | élémentaire | 
           | 2 | fr | avance  | 
           | 3 | fr | couramment | 
           : :  :    : 
           +----+------+-------------+ 
    
  2. Ein weiteres Problem bei internationalitzation einer Datenbank ist, dass wahrscheinlich für Benutzer Studien können von USA nach UK nach DE variieren ... in jedem Land werden sie ihre Niveaus haben (das wird wahrscheinlich einem anderen aber ähnlich sein) nally, anders). Und was ist mit Abrechnung?

    Alle Lokalisierung kann durch einen ähnlichen Ansatz erfolgen. Anstatt nur Textfelder in die neue Tabelle zu verschieben, können Sie alle lokalisierbaren Felder verschieben - nur die, die allen Gebietsschemata gemeinsam sind, bleiben in der ursprünglichen Tabelle.