subrion icon indicating copy to clipboard operation
subrion copied to clipboard

Why not use a good and organized structure of multilingual class?

Open testt23 opened this issue 3 years ago • 0 comments

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

multirow_approach_tbl

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

additional_translation_approach_tbl

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.

testt23 avatar Apr 14 '21 15:04 testt23