29

Necesito crear un modelo de base de datos a gran escala para una aplicación web que sea multilingüe.Modelado de bases de datos para fines internacionales y multilingües

Una duda que tengo cada vez que pienso en cómo hacerlo es cómo puedo resolver tener múltiples traducciones para un campo. Un ejemplo de caso.

La tabla de niveles de idioma, que los administradores pueden editar desde el backend, puede tener varios elementos como: básico, avanzado, fluido, de texto ... En un futuro próximo, probablemente sea un tipo más. El administrador va al backend y agrega un nuevo nivel, lo ordenará en la posición correcta ... ¿pero cómo manejo todas las traducciones para los usuarios finales?

Otro problema con la internacionalización de una base de datos es que probablemente los estudios de usuarios pueden diferir de EE. UU. A UK a DE ... en cada país tendrán sus niveles (que probablemente será equivalente a otro pero finalmente, diferente) . ¿Y qué hay de la facturación?

¿Cómo modelas esto a gran escala?

+3

En una nota lateral, asegúrese de crear sus tablas con codificación UTF-8. –

+0

¿Qué tecnología estás usando? La mayoría de los marcos existentes administran i18n bastante bien. – sp00m

+0

@ sp00m: Estoy usando PHP. No hay problema con el idioma del sitio web, los "estáticos". Estoy pidiendo cosas que los administradores pueden agregar desde el back-end del sitio web ... cuando agregan, no pueden agregar 15 idiomas para solo 1 artículo. Probablemente hablar sobre language/language_levels en este tema no es correcto también. ¿O está diciendo que también maneja i18n en las bases de datos? ¡Gracias! – udexter

Respuesta

48

Aquí es la manera de que el diseño de la base de datos:

Data model

Visualización por DB Designer Fork

La tabla i18n sólo contiene una PK, por lo que cualquier mesa sólo tiene que referencia este PK para internacionalizar un campo. La tabla translation está a cargo de vincular este ID genérico con la lista correcta de traducciones.

locale.id_locale es una VARCHAR(5) para gestionar tanto de en y en_USISO syntaxes.

currency.id_currency es un CHAR(3) para administrar el ISO 4217 syntax.

Puede encontrar dos ejemplos: page y newsletter. Ambas de estas admin-managed entidades necesitan internacionalizar sus campos, respectivamente title/description y subject/content.

Aquí es una consulta de ejemplo:

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 

Tenga en cuenta que este es un modelo de datos normalizado. Si tiene un gran conjunto de datos, tal vez podría pensar en denormalizing it para optimizar sus consultas. También puede jugar con índices para mejorar el rendimiento de las consultas (en algunos DB, las claves externas se indexan automáticamente, por ejemplo, MySQL/InnoDB).

+1

OK, es una explicación muy fácil de entender y útil. La única pregunta que tengo - ¿no sería costoso en cuanto a la memoria y los recursos del servidor utilizar el tipo de texto para cada cadena localizada? –

+0

@f_martinez Supongo que depende de los datos que necesita almacenar. Pero no dude en utilizar el tipo que necesita, si pudiera caber en un varchar por ejemplo. – sp00m

+6

No mezcle ** moneda ** y ** traducción **. – gavenkoa

27

Algunas preguntas StackOverflow anteriores sobre este tema:

Algunos recursos externos útiles:

El mejor enfoque es a menudo, para cada tabla existente, crear una nueva tabla en la que se mueven los elementos de texto; el PK de la nueva tabla es el PK de la tabla anterior junto con el idioma.

En su caso:

  1. El cuadro de los niveles de lenguaje, que los administradores pueden editar desde el servidor, puede tener varios elementos como: básico, por adelantado, fluidez, Mattern ... En el corto futuro probablemente será un tipo más. El administrador va al backend y agrega un nuevo nivel, lo ordenará en la posición correcta ... ¿pero cómo manejo todas las traducciones para los usuarios finales?

    Su tabla existente, probablemente se ve algo como esto:

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

    Entonces se convierte en dos tablas:

     
    +----+-------+ +----+------+-------------+ 
    | 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. Otro problema con internationalitzation de una base de datos es que, probablemente, para el usuario los estudios pueden diferir de EE. UU. a RU y DE ... en cada país tendrán sus niveles (que probablemente será equivalente a otro, pero finalmente, diferente). ¿Y qué hay de la facturación?

    Todas las localizaciones pueden ocurrir mediante un enfoque similar. En lugar de simplemente mover los campos de texto a la nueva tabla, puede mover cualquier campo localizable: solo aquellos que son comunes a todas las configuraciones regionales permanecerán en la tabla original.

Cuestiones relacionadas