Correct way making a translation table? - php

We currently use a translation table which looks like this:
| id | type | name | lang | value |
|-----+-------+----------+-------+----------|
| 853 | text | question | en | question |
| 854 | text | question | nl | vraag |
So for each extra translation in another language we would have to add another row
Were thinking about changing it to a table which has a column for each country value (so you would just need to add 1 row).
So it would look like this:
| id | type | name | lang | nl | en |
|-----+-------+----------+-------+---------+------------+
| 853 | text | question | en | vraag | question |
Are there any downsides to doing it the second way compared to the
first one?
How would you suggest creating a translation table like
this?

Why not to join two tables, master one with id,type,name fields and nested with id,master_id,lang,value. For the given example that will be looking like:
ID TYPE NAME
1 text question
ID MASTER_ID LANG TRANSLATION
1 1 en question
2 1 nl vraag
The translation set for one language is given by SQL query:
SELECT * FROM `nested` WHERE `lang` = 'nl'
-- vraag
-- .....
The translation for the given term (e.g. question, having id=1):
SELECT * FROM `nested` WHERE `master_id` = 1 AND `lang` = 'nl'
-- vraag

The downside of the second idea is that for every new language you want to add you have to change your database structure (following code changes to reflect that structure change) whereas the first only needs new rows (which keeps the same structure).
another plus for the first idea is that you really only need the space/memory for translations you add to the database. in the second approach you could have lots of empty fields in case you won't translate all texts.
a way to do it could be (an addition to the answer above from #mudasobwa):
Master Table:
| id | type | master_name |
|----+------+-------------|
|853 | text | question |
|854 | text | answer |
Language Table:
| id | language_name |
|----+---------------|
| 1 | english |
| 2 | german |
Translation Table:
| id | master_id | language_id | translation |
|----+-----------+-------------+--------------------|
| 1 | 853 | 1 | question |
| 1 | 854 | 2 | Frage |
| 2 | 853 | 1 | answer |
| 2 | 854 | 2 | Antwort |
So if you have another language, add it to the language table and add the translations for your master texts for that language.
Adding indexes to the ids will help speeding up queries for the texts.

Second way is much better:
Keeps less place in Database.
Loads faster.
Easy to edit.

Related

Sorting on data from language file

I want to have translations for a number of languages coming from the default Language files (as provided by CI). I'd also like to do some sorting on these values (e.g. to insert them in a dropdown list, I want them to be alphabetically sorted).
I have a project running in CodeIgniter and am in the process of moving all hardcoded text to the language files. This also includes some database tables.
For example, I have the following table:
+-------------+---------------------+--------------------+---------------+
| language_id | language_nl | language_en | language_code |
+-------------+---------------------+--------------------+---------------+
| 1 | Afrikaans | Afrikaans | AF |
| 2 | Albanese | Albanian | SQ |
| 3 | Arabisch | Arabic | AR |
| 4 | Armeens | Armenian | HY |
| 5 | baskisch | Basque | EU |
| 6 | Bengalees | Bengali | BN |
| | | | |
+-------------+---------------------+--------------------+---------------+
Now I would like to transfer this table to my language file.
I will first start by deleting the language_nl and language_en columns.
A new column will have to be introduced as well, language_key.
So it should look like this:
+-------------+--------------+---------------+
| language_id | language_key | language_code |
+-------------+--------------+---------------+
| 1 | language_af | AF |
| 2 | language_sq | SQ |
| 3 | language_ar | AR |
| 4 | language_hy | HY |
| 5 | language_eu | EU |
| 6 | language_bn | BN |
+-------------+--------------+---------------+
Then in my language file I will add the following lines:
$lang["language_af"] = "African";
$lang["language_sq"] = "Albanian";
$lang["language_ar"] = "Arabic";
And so on...
I will then create a manager class to help me in finding the translations for each necessary language for the key.
It would look something like this:
public function getLanguageName($key) {
return lang(key);
}
Now I have two main questions:
1) Is this a good way of approaching the issue I have?
2) Let's say I need the languages to be shown in a drop-down. I want this dropdown to be alphabetically sorted (order will be different based on the language selected, of course). How do I approach this issue? Do I load in all the values from the language file, put them in an array and then sort that array?

Database model for a multilanguage translation module

I need to design a db model for a backend module where user can translate page content into multiple languages. The things that will be translated are basic words, phrases, link names, titles, field names, field values. They should also be grouped so i can find them by group name. For example if there is a select field on page with different colors as options then i should be able to select all of them by group name.
So here is what i have at the moment:
lang
+----+---------+
| id | name |
+----+---------+
| 1 | english |
| 2 | german |
+----+---------+
lang_entity
+----+------------+-------------+-------+-------+
| id | module | group | name | order |
+----+------------+-------------+-------+-------+
| 1 | general | | hello | 0 |
| 2 | accounting | colorSelect | one | 1 |
| 3 | accounting | colorSelect | two | 2 |
| 4 | accounting | colorSelect | three | 3 |
+----+------------+-------------+-------+-------+
lang_entity_translation
+----+---------+----------------+-------------+
| id | lang_id | lang_entity_id | translation |
+----+---------+----------------+-------------+
| 1 | 1 | 1 | Hello |
| 2 | 2 | 1 | Guten tag |
| 3 | 1 | 2 | One |
| 4 | 2 | 2 | Ein |
| 5 | 1 | 3 | Two |
| 6 | 2 | 3 | Zwei |
| 7 | 1 | 4 | Three |
| 8 | 2 | 4 | Drei |
+----+---------+----------------+-------------+
So lang table holds different languages.
Table lang_entity has entities that can be translated for different languages.
Module row is just to group them by page modules in the backend translating module. Also this gives me possiblity to have entities with same name for different modules.
Group as mentioned is needed for selects and maybe some other places where multiple values are going to be used. This also gives me an option to allow user to add and order entities in one group.
And table lang_entity_translation holds the translations for each entity in each language.
So my question is are visible flaws in this kind of a design? Would you reccomend something different?
Also a bonus question: I really dont like the lang_entity table name, do you have a better idea of a table name that would hold all the words/phrases that are translated? :)
Edit: similar, but not a duplicate. The linked question is about translating dynamic products and having a seperate table for each translated type. Im talking about translating whole page content, including groups in a single table.
I don't understand the order column of lang_entity, but then I probably don't need to.
The setup looks sane, but make sure you add foreign key constraints from lang_entity_translation to language and lang_entity.
As for naming, I would call the table phrase or translatable.
We had similar situation. This was 7 years before.
We had different column for different language. Like for name we had
Name_Eng,Name_Ger,Name_Spa .We had 7-10 language.
We had common id for name for all language.
Based on the Language selection from UI we passed the language code to Back end In the Stored proc it was appended to the column Name
Example, we will be passing "Eng" if English is selected and we form the column name as Name_Eng and fetch the data. we were using dynamic query.

mysql performance and security related issue

I get some issues when i implement product_description table with language .
my process is that i have default table product_description_en to store description and when a client installs new language (Chinese) the php script will create new table product_des_ch and then put the all default data(from the English table) in to the newly created table.then the client can update .
My problems are
Is it a security issue that we create the table dynamically while installing new language
2.If we use same table for all languages(the records will be around 500,000) then are there any per performance issues
3.what is the best way for large amount of records to store , i mean same table or separate tables.
Thanx
Az
Updated:
This is sample product_description table structure for English table and Japan .What you think about this table(we store the all records in a same table and when the client inserts new record for different language only inserting new records ) ,Any feedback please ?
+---------------------------------------------------------------------------+
| product_id | name | desc | meta_name | meta_desc | key_words | lan_code |
+---------------------------------------------------------------------------+
| 1 | A | D| m1 | m_d1 | k1 | en |
+---------------------------------------------------------------------------+
| 1 | A | D| m2 | m_d2 | k2 | jp |
+---------------------------------------------------------------------------+
Basic RDBMS design wisdom would put a huge red flag on anything that dynamically alters the table structure. Relational databases are more than flexible enough to handle pretty much any situation without requiring such measures.
My suggestion as for the structure would be to create a single Languages table to store the available languages, and then a Phrases table to store all the available phrases. Then use a Translations table to provide the actual translations of those phrases into the available languages. Something that might look like this:
Language
+----+---------+
| id | name |
+----+---------+
| 1 | English |
| 2 | Chinese |
+----+---------+
Phrase
+----+-------------+
| id | label |
+----+-------------+
| 1 | header |
| 2 | description |
+----+-------------+
Translations
+-------------+-----------+-----------------+
| language_id | phrase_id | translation |
+-------------+-----------+-----------------+
| 1 | 1 | Header |
| 1 | 2 | Description |
| 2 | 1 | 头 |
| 2 | 2 | 描述 |
+-------------+-----------+-----------------+
For small to medium sized databases, there should be no performance issues at all even using the default database configurations. If you get to huge sizes (where you are counting the database size in terabytes) you can optimize the database in many ways to keep the performance level acceptable.

Save quiz alternatives as JSON string or individual rows?

I'm making a quiz. Each question consists of a question, three alternatives, and one of them are correct. The server should output HTML (not JSON that JS is going to parse), and the user chooses an answer.
The reason why I'm in doubt is that the person who makes the quiz is sending the alternatives over JSON. And if you want to edit any of the alternatives later on, you just parse the JSON, do your changes and send it to the server. Then the server will just update the alternatives "cell".
However when the user takes the quiz, the server has to run through the array to find the right answer. If the answers are stored in their own separated row (many-to-many), the server could just query for the right answer.
In addition to this, JSON would result in saving the alternatives in a TEXT column compared to many small VARCHARS if one uses a many-to-many relationship.
What is the most efficient way to do it? (Speed)
What is the most convenient way, and most accepted way to do it?
Well, I would have say that your table should look like this:
+------+------------+--------+--------+--------+--------------+
| ID | Question | Ans1 | Ans2 | Ans3 | CorrectAns |
+------+------------+--------+--------+--------+--------------+
| PKey | text | text | text | text | text |
+------+------------+--------+--------+--------+--------------+
| 1 | π = ? | 3.1415 | 2.2465 | 5.6598 | 3.1415 |
+------+------------+--------+--------+--------+--------------+
And your query would be:
SELECT (CorrectAns = %enteredanswer%) FROM QuizTable WHERE ID=%questionid%
Its pretty easy to convert json to this table, and vice-versa.
EDIT: For an undefined number of alternatives:
You could have a Question table, and an Options table like so:
Question:
+-------+------------+---------------+
| QID | Question | CorrectAnsID |
+-------+------------+---------------+
| PKey | text | FKey,integer |
+-------+------------+---------------+
| 1 | π = ? | 2 |
+-------+------------+---------------+
Options:
+-------+--------------+--------------+
| OID | OptionText | QuestionID |
+-------+--------------+--------------+
| PKey | text | FKey,Integer |
+-------+--------------+--------------+
| 1 | 3.5600 | 1 |
+-------+--------------+--------------+
| 2 | 3.1415 | 1 |
+-------+--------------+--------------+
| 3 | 3.4567 | 1 |
+-------+--------------+--------------+
| 4 | 3.7894 | 1 |
+-------+--------------+--------------+
| 5 | 3.9874 | 1 |
+-------+--------------+--------------+
This might be faster to work than the json method, but more difficult to implement (joins and stuff to write), so if its a quick, smaller scale project, I'd go with the json method.

Displaying Data From Multiple MySQL Tables

I have 14 tables (one for every year) with product code, firm name and invoice numbers. Main structure of table is identical (product code, ID), but there can be some variables in names of firms.
Table2011
| ID | productcode | firm1 | firm2 | firm3 | etc |
| 1 | G-00001 | 2;5;40| 32;67 | | 150 |
| 2 | G-00005 | | 50 | | |
|etc | | | | | |
Table2010
| ID | productcode | firm1 | firm2 | firm3 |etc |
| 1 | G-00001 | 1;10 | | 55 | |
| 2 | G-00003 | | 2 | | |
| 3 | G-00005 | | 50 | 40 | |
| etc| | | | | |
Table2009
...
Column Firm1 do not usually equals to same firm as firm 1 in other table
I am using table editor to work with tables (adding columns to table, editing values…).
I would like to know if it is possible to achieve result like below. It is above my PHP skills.
Product G-00001 page
…
<UL>
<LI>Year 2011: 150etc; 67firm2; 40firm1; 32firm2; 5firm1; 2firm1</LI>
<LI>Year 2010: 55firm3; 10firm1; 1firm1</LI>
<LI>Year 2009: ...</LI>
...
</UL>
…
Lemme begin with book recommendation : SQL Antipatterns. You will need it, doesn't matter if you caused this mess or ar just assigned to fix it.
If i was in your place, first thing would do would be to fix the database structure. This is madness. You do not need a new table for each year and new column for each company. Database is not a form of Excel spreadsheet.
Invoices Years Companies
----------------- ------------- ---------------
| product_code PK | | year_id PK | | company_id PK |
| company_id FK | | number | | title |
| amount | ------------- ---------------
| year_id FK |
-----------------
Where PK - primary key and FK - foreign key.
This structure would make the gathering of information much much much MUCH easier.
If you just want to display the data and not worry about the restructuring just yet you can use a JOIN to display the information from all the tables.
Although I would agree with teresko you really need to redesign that database. It is not maintainable the way it is.

Categories