La primera es basura como diseño, perdona que lo diga directamente.
Generaría recarga en la base toda vez que puedan existir registros donde no se hayan iincliuido todos los idiomas.
Además requiere modificar la estructura física de la tabla cada vez que se incorpore o se elimne un idioma...
Los ejemplos 2 y 3 son exactamente lo mismo conceptualmente, pero la 2 no es un modelo verdaderamente relacional. La segunda tabla no tiene razones para existir en un diseño normalizado y su uso carece de utilidad práctica.
Y recuerda que los campos de tipo dato IDENTITY no existen en todos los DBMS...
Sólo la tercera forma que pones se acerca a la correcta solución a nivel diseño y normalización.
Por otro lado faltan definiciones de PK, ademas de apuntar una FK a un campo no clave, lo que es un error.
Esto estaría mas cerca:
Código SQL:
Ver originalCREATE TABLE ref_language (
Code CHAR(2) NOT NULL,
Name VARCHAR(20) NOT NULL,
PRIMARY KEY (Code)
);
CREATE TABLE app_translation_entry (
ProductId INT NOT NULL,
Code CHAR(2) NOT NULL,
Text Text NOT NULL,
FOREIGN KEY (TranslationId) REFERENCES app_translation(ProductId),
FOREIGN KEY (Code) REFERENCES ref_language(Code)
);
CREATE TABLE app_product (
ProductId INT NOT NULL,
Description INT NOT NULL,
PRIMARY KEY (ProductId)
);