2009-08-24 10 views
8

que tienen una serie de tablas de bases que contienen name y description columnas que necesitan ser localizado. Mi primer intento de diseñar un esquema de base de datos que apoyaría esto era algo así como:base de datos de localización

product 
------- 
id 
name 
description 


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


locale 
------ 
id 
locale 

Sin embargo, esta solución requiere una nueva tabla local_ para cada tabla que contiene name y columnas de descripción que requieren localization. En un intento de evitar esta sobrecarga Rediseñé el esquema de modo que sólo se necesita una única localization mesa

product 
------- 
id 
localization_id 


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


locale 
------ 
id 
locale 

He aquí un ejemplo de los datos que se almacenan en este esquema cuando hay 2 tablas (producto y país) localización requiere:

país

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

producto

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

localización

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 

en cuenta que la clave principal compuesto de la tabla localization es (id, locale_id), pero la clave externa en la tabla product sólo se refiere a el primer elemento de este compuesto PK. Esto parece 'algo malo' desde el punto de vista de la normalización.

¿Hay alguna manera de solucionar este problema, o alternativamente, ¿existe un esquema completamente diferente que admite la localización sin necesidad de crear una tabla separada para cada tabla localizable?

Actualización: Un número de los encuestados han propuesto una solución que requiere la creación de una tabla separada para cada tabla localizable. Sin embargo, esto es precisamente lo que intento evitar. El esquema que he propuesto anteriormente casi resuelve el problema a mi satisfacción, pero estoy contento con el hecho de que los localization_id claves externas se refieren sólo a una parte de la clave primaria correspondiente en la tabla localization.

Gracias, Don

+1

"pero no estoy contento con el hecho de que las claves externas localization_id solo se refieren a parte de la clave principal correspondiente en la tabla de localización". No veo el problema, hay una relación de uno a muchos desde el producto hasta la localización, la estructura de la base de datos sigue los requisitos, ha encontrado una buena solución. –

+0

Esto debe publicarse en http://dba.stackexchange.com/ –

Respuesta

1

La forma correcta, me siento, sería la creación de la tabla extra, pero luego ir un paso más allá y eliminar todos los recursos específicos del idioma de la primera tabla.

por lo que tendría:

producto

id 
-name removed 
-description removed 

localización de productos

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 

local

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

Este esquema no funcionará cuando haya más de una tabla que contenga contenido localizable –

+0

Necesitará una tabla adicional por contenido localizable. No creo que puedas soslayar eso. Algunas tablas localizables pueden no tener nombres ni descripciones, como puede ver, o pueden tener más campos que requieren traducciones. Esto, por supuesto, rompe las mejores prácticas para normalizaciones. Usa las tablas extra – DanDan

+0

En este caso, es seguro suponer que * cada * tabla localizable solo requerirá que se localice un nombre y una descripción –

3

Creo que está bien. Está describiendo una relación uno a muchos entre un producto y su texto de localización.

Me pregunto si también debe localizar el inglés en lugar de desnormalizarlo en su tabla de productos.

+0

Modifiqué el esquema para incorporar su sugerencia –

+2

El objetivo de la localización es que hay un one-to -mucha relación entre la "cosa" y el nombre. Por lo tanto, naturalmente se deduce que una referencia en la tabla "cosa" no puede ser una clave primaria completa para la tabla de localización, porque eso restringiría la relación con uno a uno. La forma más común de hacer una relación de muchos a uno es publicar el identificador del extremo "uno" en el extremo "muchos", pero tendría un problema al hacerlo aquí, ya que la tabla de localización tendría que hace referencia a muchas tablas diferentes, lo que lo convierte en una referencia de clave foránea desordenada y poco definida. – Jay

1

Si entiendo bien, su problema es solo porque desea utilizar la misma localización de idioma para el nombre y la descripción en más de una tabla. En tal escenario, no puede agregar el prod_id en la tabla de localización. Un problema más en su diseño es que no puede manejar más de una localización de idioma para el mismo producto elegantemente. Podría modificarlo para que funcione:

Si el nombre y la descripción son los únicos campos que requieren localización, puede hacer lo siguiente.

Producto (ID, nombre, descripción, tanslation_row_id)

Product_translations (DNI, nombre, descripción, lang_id, translation_id)

El translation_row_id estará apuntando clave externa a Product_translations.ID El translation_id voluntad, sin embargo, señale un registro principal en la misma tabla que serviría como un registro común para todos los registros específicos del idioma.

ejemplo registros

producto

(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) 

Dado un código de idioma, se puede extraer el nombre y descripción valores utilizando la consulta ss SQL

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'; 

Nota importante: supongo que la tabla de productos tiene muchos más atributos que no necesitan esta traducción. '& langID' es un parámetro para la consulta SQL que pedir al usuario el código de idioma de su elección

+0

Una gran sugerencia, podría darle una oportunidad. Sin embargo, probablemente elimine el nombre y la descripción de las tablas de Producto (y otras tablas localizables), ya que parece ser redundante. Además, la tabla product_translations debería llamarse algo más genérico como 'translations', porque en realidad contendrá países, productos, etc. localizados. –

2

me gusta la idea, pero sería ir un paso más en la otra dirección, y tienen una entrada de localización para cada columna que se traduce:

país

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

producto

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

localización

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 

El PK de localización es (id, locale_id). No es problema que id también sea una referencia de FK en muchas otras tablas. Puede agregar un PK sustituto si lo desea, siempre y cuando aún tenga un índice único en (id, locale_id).

Lo bueno de esto es que es una tabla de localización única, y funciona para cualquier tabla en su esquema, independientemente de los campos que tenga (no está limitado a tener tanto el nombre como la descripción de cualquier cosa que se localice) . La desventaja es un posible impacto en el rendimiento cuando se utiliza la tabla de localización, aunque es posible que simplemente guardes en caché todo para un locale_id dado, de modo que cuando buscas entradas solo tienes que buscar el ID dado (ya que tu caché es en clave basado en el idioma ya).

También podría considerar dejar los campos de descripción y nombre predeterminados en la tabla de productos, que se utilizarían en caso de que falte una entrada para el idioma actual o cuando el usuario no especifique el idioma. Este también sería el caso si está portando una aplicación existente, ya tendría valores ahí (sin información de localización).