subrion
subrion copied to clipboard
Why not use a good and organized structure of multilingual class?
You usege of multirow approach table, but I think: Advantages: Simplicity - easy to implement Easy querying - no JOINs required
Disadvantages: Hard to maintain - every column that is not translated must be changed in all rows for each language. e.g changing the price for single product requires repeating of this operation for all languages Hard to add a new language - requires repeating insertion operation for each language (cloning the record for default language) Duplicate content - you will have a lot of duplicate content for all the columns that are not translated
and the right optimization solution is as follows: Additional Translation Table Approach This is a variation of the above approach and it seems to be easier to maintain and work with. Let's check why: for each table that stores information that may need to be translated an additional table is created. The original table stores only language insensitive data and the new one all translated info. Below the example for such database schema in MySQL:
CREATE TABLE IF NOT EXISTS `app_product` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`date_created` datetime NOT NULL,
`price` decimal(10,2) NOT NULL DEFAULT '0.00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `app_product_translation` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`product_id` int(11) NOT NULL DEFAULT '0',
`language_code` char(2) NOT NULL,
`title` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`description` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`),
KEY `translation_id` (`product_id`),
KEY `language_code` (`language_code`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `app_language` (
`code` char(2) NOT NULL,
`name` varchar(20) NOT NULL,
PRIMARY KEY (`code`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Usage of additional translation table approach.
<?php
// Retrieve titles for all languages
$sql = "SELECT p.*, pt.title, pt.description, l.name as language_name
FROM `app_product` p
INNER JOIN `app_product_translation` pt ON p.id = pt.product_id
INNER JOIN `app_language` l ON pt.language_code = l.code
WHERE p.id = 1";
if($result = mysqli_query($link, $sql)){
while($row = mysqli_fetch_assoc($result)){
echo "Language (".$row["language_name"]."): ".$row["title"]."<br>";
}
}
// Retrieve appropriate title according to the chosen language in the system
$sql = "SELECT p.*, pt.title, pt.description
FROM `app_product` p
INNER JOIN `app_product_translation` pt ON p.id = pt.product_id
WHERE p.id = 1 AND pt.language_code = '".$_SESSION['current_language']."'";
if($result = mysqli_query($link, $sql)){
if($row = mysqli_fetch_assoc($result)){
echo "Current Language: ".$row["title"];
}
}
?>
Advantages: Proper normalization - seems like clean, relational approach Ease in adding a new language - doesn't require schema changes Columns keep there names - doesn't require "_lang" suffixes or something else Easy to query - relatively simple querying (only one JOIN is required) Disadvantages: May double the amount of tables - You have to create translation tables for all your tables that have columns that need to be translated
Conclusion. The second option I have shown I recommend when using good frames like this, but the option you use is for small projects. If you want to underline the frame, use my example in the new version. If you support the frame at all.