Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I am planning to build a multilingual CMS & I have the following:

CREATE TABLE `posts` ( `post_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, `post_cat` INT(11) UNSIGNED NOT NULL, `post_date` DATETIME NOT NULL, `post_title` VARCHAR(255) NOT NULL, `post_body` TEXT NOT NULL, `post_lang` TINYINT UNSIGNED NOT NULL ); CREATE TABLE `languages` ( `lang_id` TINYINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, `lang_name` VARCHAR(60) NOT NULL );

Obviously enough I'll need a 3rd table to connect same posts of different languages together ... but I am out of ideas as I don't see how easy to implement it or use it in Perl i.e: when you are in a page in English you'll have the option to press on "French" button .. and you'll have the same post in French.

Replies are listed 'Best First'.
Re: [OT] Database Design
by ikegami (Patriarch) on Aug 10, 2010 at 22:33 UTC
    CREATE TABLE `languages` ( `lang_id` TINYINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, `lang_name` VARCHAR(60) NOT NULL ); CREATE TABLE `post_translations` ( `post_translation_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT PRI +MARY KEY, `post_translation_cat` INT(11) UNSIGNED NOT NULL, `post_translation_date` DATETIME NOT NULL, `post_translation_title` VARCHAR(255) NOT NULL, `post_translation_body` TEXT NOT NULL, `post_translation_lang` TINYINT UNSIGNED NOT NULL ); CREATE TABLE `posts` ( `post_id`, INT(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, `post_translation_id` INT(11) UNSIGNED NOT NULL, );

    For each post, you'll have multiple translations. All you have to do now is to find the correct translation for the current post_id.

      I could not understand how this works? would you mind explain it to me?

      How would I use the `post` table with an auto_increment field `post_id` and only 1 field `post_translation_id` to have more than one translation per post?

      Thanks for your help

        If someone wants to read post $post_id in language $language_name,
        my $sth = $dbh->prepare(' SELECT * FROM post_translations JOIN posts ON post_translations.post_translation_id = posts.post_translati +on_id JOIN languages ON post_translations.lang_id = languages.lang_id WHERE posts.post_id = ? AND languages.lang_name = ? '); $sth->execute($post_id, $language_name);

        Pardon any syntax errors.

        How would I use the `post` table with an auto_increment field `post_id` and only 1 field `post_translation_id` to have more than one translation per post?

        You woulnd't. You'd fix my bug :)

        If you wanted to have it autoincrement,

        CREATE TABLE `languages` ( `lang_id` TINYINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, `lang_name` VARCHAR(60) NOT NULL ); CREATE TABLE `post_translations` ( `post_translation_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT PRI +MARY KEY, `post_translation_cat` INT(11) UNSIGNED NOT NULL, `post_translation_date` DATETIME NOT NULL, `post_translation_title` VARCHAR(255) NOT NULL, `post_translation_body` TEXT NOT NULL, `post_translation_lang` TINYINT UNSIGNED NOT NULL ); CREATE TABLE `posts` ( `post_id`, INT(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, ); CREATE TABLE `post_to_translation` ( `post_id`, INT(11) UNSIGNED NOT NULL, `post_translation_id` INT(11) UNSIGNED NOT NULL, );

        Update: Since it's an 1:N and not N:N relationship, post_to_translation is not necessary.

        CREATE TABLE `languages` ( `lang_id` TINYINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, `lang_name` VARCHAR(60) NOT NULL ); CREATE TABLE `post_translations` ( `post_id`, INT(11) UNSIGNED NOT NULL, `post_translation_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT PRI +MARY KEY, `post_translation_cat` INT(11) UNSIGNED NOT NULL, `post_translation_date` DATETIME NOT NULL, `post_translation_title` VARCHAR(255) NOT NULL, `post_translation_body` TEXT NOT NULL, `post_translation_lang` TINYINT UNSIGNED NOT NULL ); CREATE TABLE `posts` ( `post_id`, INT(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, );

      ikegami ++!

      this is the best way for multi-language design.




      I am trying to improve my English skills, if you see a mistake please feel free to reply or /msg me a correction

Re: [OT] Database Design
by planetscape (Chancellor) on Aug 11, 2010 at 03:31 UTC
Re: [OT] Database Design
by Your Mother (Archbishop) on Aug 10, 2010 at 23:47 UTC

    You got good advice from ikegami already. I just want to add, since we're OT, that I find this naming convention-

    CREATE TABLE `posts` ( `post_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, `post_cat` INT(11) UNSIGNED NOT NULL, ...

    -completely annoying. It's like naming a hash like so %hash_variable_name. Redundant information is almost always suboptimal if not an outright mistake in code design. I have no idea how it's become popular in schema design. I'd rather see cat spelled out category or catalog or catamaran or whatever you're assuming everyone will know it's short for than see something like posts.post_cat.

      I've seen too many people using 'cat' as a short cut for 'category'

      About the naming convention ... I think it's used that way so you don't get confused or type too much when selecting from multiple tables ... i.e: you don't have to say posts.post_id ... otherwise if you're selecting from 2 tables that have the same field name you'll have to do something like posts.id and if you want to use it somewhere you'll have to provide a temporary name using 'As `fields`'

      At least that's what I remember from my readings.

        How is posts.id more typing or more confusing than posts.post_id?
Re: [OT] Database Design
by isync (Hermit) on Aug 10, 2010 at 23:42 UTC
    I prefer to keep the number of involved databases down, so I would introduce a db scheme where you've got multiple entries for one post, only differentiated by a second field holding the language.

    id:1 - lang:en - "post content in en"
    id:1 - lang:fr - "post content in fr"
    ect.

      I thought about this too ... but it will be difficult to add new languages and if you have too many fields the table will look messy.

      I want to make it as dynamic as possible ... that's why I am trying to find a solution that works but I am not expert in db design

Re: [OT] Database Design
by aquarium (Curate) on Aug 11, 2010 at 03:23 UTC
    I'm a bit baffled by what you're trying to accomplish exactly. But if you're supposed to be able to access the same post and see it in a different language, does that imply some automated translation?..in which case the language preference would only be a session/user/display setting, instead of storing the language and translated text. If the translations are done by hand, that's a different story.
    To help clarify your database schema it's best to draw an ER diagram rather than straight into specific schema. You should be able to walk the pen along the relationship lines in the ER diagram, as you work through functional scenarios of your app. ER diagram shows the cardinality ( 1-to-many etc) about the relationships between the tables, so helps clarify the relationships and remove basic anomalies (e.g. many-to-many cardinality needs refactoring)
    the hardest line to type correctly is: stty erase ^H