I’m working on an recipe module (ASP.NET MVC, entity framework, sql server), and one of the entities I have to setup in the database are ingredients, their characteristics and translations to a number of languages.
I was thinking of creating two tables as follows:
Table Ingredient
Id, nvarchar(20), primary key
EnergyInKCal, float
... other characteristics
Source, nvarchar(50)
Table IngredientTranslation
Id, nvarchar(20), primary key
LanguageCode, nvarchar(2)
Name, nvarchar(200)
So each ingredient will be defined once in the Ingredient table, with a unique code as their primary key, for example:
'N32-004669', 64, 368, 'NUBEL'
and translated in the IngredientTranslation table, for example
'N32-004669', 'NL', 'Aardappel, zoete'
'N32-004669', 'FR', 'Pomme de terre, douce'
'N32-004669', 'EN', 'Potatoe, sweet'
I think querying ingredients becomes easy like this… do you think it’s a good idea to use code (which is nvarchar(20)) as a primary key? Or is a simple bigint better, but then I have to use JOINS in my queries. Maybe other approaches that are better – performance wise?
EDIT: after reading the answers, I redesigned the tables as follows:
Table Ingredient
Id, bigint, primary key
ExternalId, nvarchar(20)
EnergyInKCal, float
... other characteristics
Source, nvarchar(50)
Table IngredientTranslation
Id, bigint, primary key
IngredientId, bigint (relation with Id of Ingredient table)
LanguageCode, nvarchar(2)
Name, nvarchar(200)
Thanks,
L
Since a primary key is included in every other index, it’s best to keep the primary key small. So an
int identityis an excellent choice.One side note: storing translations in a database has a rather hefty performance impact. Both on the database and the rendering engine that has to build the web page. Since translations are fairly constant, most websites store them outside the database. In ASP.NET, the typical choice would be resource files.