Using Views for Multilingual Database - php

This is a subject that has been discussed multiple times and it always depens on the situation, but I like to share my idea.
Im building a new CMS that must support multilingual applications and can be installed behind existing applications.
The solutions I know and found are:
[Product]
id
price
name_en
name_de
name_fr
only getting the fields you need in your language.
or using mutliple tables like:
[product]
id
price
[languages]
id
tag
[product_translation]
product_id
language_id
name
Joining the correct language
Both situations work and have its pro's and cons. Based on your choice you have to rewrite your query's.
my idea:
[product]
id
price
name
[product_translations]
product_id
language_id
name
[product_es_view]
id -- references the product table
price -- references the product table
name -- references the translation table
Now the idea is that you create a view for every language, but the view is identical to the product table.
Why?
With this setup I can make non-multilingual sites, multilingual without editing the existing model/table. Now the only thing I have to do in my code is use another table and i get a translated version of my model (in php it could be done by adding a simple trait to your model). With SQL server and Mysql you can use updateable views which save the value's in the referenced tables.
I love to hear what you guys think of the idea, and most of all what the biggest cons are of using views for this problem ?

I prefer the second option where every entity is in its own table. If you use product_es_view then it may be easier but less clean code.
Adding new languages should usually not include adding new database tables. Adding new row to languages tables is better.

Related

How to use dynamic field type in mysql?

I want to design a little on-line store. The website should have every detail about products. Since I am beginner I stuck at designing good database design.
There are many different products: Cellphone, Laptop, Stove, Bag, etc. Each of these products need different details. I am not going to design many different table for each, So one table (product) going to have all products.
But How I manage details? I couldn't find good topic on Google so I started my own poor design. This is my draft design:opps can not post image
Product stores product name.
Product_category defines type of product, like: mobile or book. each product belongs to one product category
Product_category_detail stores product attributes like color, wight,
battery life etc. each product_category_details belongs to one
product_category.
Product_detail keeps values of detail like 3 hour
for battery life, or 400g for wight. each of this belogns to one
product category detail and product.
I can store all details in Var-char.
Is it good? any suggestion!
It's better to have type of detail. like varchar for color and int for wight.
I am thinking on another field in product_catefory_datail named attr_type so I can change convert in php.
Any idea? tnx
I suggest you to use product table only to keep generic information about product, than have product_attributes table:
ID (INT|Unique) | product_id (INT) | name (VARCHAR) | value (VARCHAR) | type (INT: predefined constant values)
This is where you do need the Entity Attribute Value (EAV) model. If you need different data types then you need additional columns to specify the data type and for each data type: eg type specified as 'string' so select the string_value column, 'number' select the numeric_value column. That means CASE statemenst everywhere. Makes the whole thing horrible to work with.
an online store is very complex, and not really a beginners task. It wont be scalable and since you dont know yet how many variations you need you'll end up with adding new tables and columns until it gets too complex. Stores usually have a EAV model for this; http://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80%93value_model .
I had this similar issue while doing a project, and developed tables which solved my problem . Hope this helps you too.
product_table
pt_id,name,category
product_category_table
pct_id,name,desc
detail_fields
pf_id,field_name
product_detail_fields
pdf_id,pt_id,pf_id,default_value
product_detail_fields_values
pdfv_id,pdf_id,value,user_id //here pdf_id is fk of product_detail_fields
If you have multiple users, make use of user_id, else ignore it.

Backend app in OO PHP: Structuring classes/tables efficiently

I'm currently working on an app backend (business directory). Main "actor" is an "Entry", which will have:
- main category
- subcategory
- tags (instead of unlimited sub-levels of division)
I'm pretty new to OOP but I still want to use it here. The database is MySql and I'll be using PDO.
In an attempt to figure out what database table structure should I use in order to support the above classification of entries, I was thinking about a solution that Wordpress uses - establish relationship between an entry and cats/subcats/tags through several tables (terms, taxonomies, relationships). What keeps me from this solution at the moment is the fact that each relationship of any kind is represented by a row in the relationships table. Given 50,000 entries I would have, attaching to a particular entry: main cat, subcat and up to 15 tags might slow down the app (or I am wrong)?
I then learned a bit about Table Data Gateway which seemed an excellent solution because I liked the idea of having one table per a class but then I read there is virtually no way of successful combating the impedence missmatch between the OOP and relational-mapping.
Are there any other approaches that you may see fit for this situation? I think I will be going with:
tblentry
tblcategory
tblsubcategory
tbltag
structure. Relationships would be based on the parent IDs but I+'m wondering is that enough? Can I be using foreign key and cascade delete options here (that is something I am not too familiar with and it seems to me as a more intuitive way of having relationships between the elements in tables)?
having a table where you store the relationship between your table is a good idea, and through indexes and careful thinking you can achieve very fast results.
since each entry must represent a different kind of link between two entities (subcategory to main entry, tag to subcategory) you need at least (and at the very most) three fields:
id1 (or the unique id of the first entity)
linkid (linking to a fourth table where each link is described)
id2 (or the unique id of the second entity)
those three fields can and should be indexed.
now the fourth table to achieve this kind of many-to-many relationship will describe the nature of the link. since many different type of relationship will exist in the table, you can't keep what the type is (child of, tag of, parent of) in the same table.
that fourth table (reference) could look like this:
id nature table1 table2
1 parent of entry tags
2 tag of tags entry
the table 1 field tells you which table the first id refers to, likewise with table2
the id is the number between the two fields in your relationship table. only the id field should be indexed. the nature field is more for the human reader then for joining tables or organizing data

Database concept multilanguage

I want to create a site in PHP with cakephp that users can insert product manually.
The problem is for the multilanguage because I can have into my site users from all over the world and the product 'apple' in italian for example is 'mela'.
Consider that I can have many many data!
Then i have some solution for the database:
Create a table products with an id
Create a table product_aliases where I have an id the id of product language and the text(ex. apple)
In this mode users can enter into 'apple', translate ad I insert a new line into product_aliases with same id product different language and different text but same product
Define 5 language and create a table with more fields (title_en, title_it, title_es...) the translation is in the same record
Only one table but restricted language
Create a table products with an id
Create a table for every language that i want for example: prducts_en, products_it where I can store my data with same foreign key to the product but divide from language to make fast query.
Other solution are accepted!!
I never work with large multilanguage database help me and tell me what is the best solution for my database
The first one is the correct solution in general.
It's used in many enterprise applications: a table with an id field for identification of the not multilanguage information (example: unit price for a product) and a table with a row for every combination product/language.
The second one is against every db normalization rule.
The third one is a different derivation of the second one, and if you use an index on the language column in the translated labels table you should not have a great disadvantage in terms of performance.
If you need I will explain better!

database table design for some unknown data

So, not having come from a database design background, I've been tasked with designing a web app where the end user will be entering products, and specs for their products. Normally I think I would just create rows for each of the types of spec that they would be entering. Instead, they have a variety of products that don't share the same spec types, so my question is, what's the most efficient and future-proof way to organize this data? I was leaning towards pushing a serialized object into a generic "data" row, but then are you able to do full-text searches on this data? Any other avenues to explore?
split products and specifications into two tables like this:
products
id name
specifications
id name value product_id
get all the specifations of a product when you know the product id:
SELECT name,
value
FROM specifications
WHERE product_id = ?;
add a specification to a product when you know the product id, the specification's name and the value of said specification:
INSERT INTO specifications(
name,
value,
product_id
) VALUES(
?,
?,
?
);
so before you can add specifications to a product, this product must exist. also, you can't reuse specifications for several products. that would require a somewhat more complex solution :) namely...
three tables this time:
products
id name
specifications
id name value
products_specifications
product_id specification_id
get all the specifations of a product when you know the product id:
SELECT specifications.name,
specifications.value
FROM specifications
JOIN products_specifications
ON products_specifications.specification_id = specifications.id
WHERE products_specifications.product_id = ?;
now, adding a specification becomes a little bit more tricky, cause you have to check if that specification already exists. so this will be a little heavier than the first way of doing this, since there are more queries on the db, and there's more logic in the application.
first, find the id of the specification:
SELECT id
FROM specifications
WHERE name = ?
AND value = ?;
if no id is returned, this means that said specification doesn't exist, so it must be created:
INSERT INTO specifications(
name,
value
) VALUES(
?,
?
);
next, either use the id from the select query, or get the last insert id to find the id of the newly created specification. use that id together with the id of the product that's getting the new specification, and link the two together:
INSERT INTO products_specifications(
product_id,
specification_id
) VALUES(
?,
?
);
however, this means that you have to create one row for every specific specification. e.g. if you have size for shoes, there would be one row for every known shoe size
specifications
id name value
1 size 7
2 size 7½
3 size 8
and so on. i think this should be enough though.
You could take a look at using an EAV model.
I've never built a products database, but I can point you to a data model for that. It's one of over 200 models available for the taking, at Database Answers. Here is the model
If you don't like this one, you can find 15 different data models for Product oriented databases. Click on "Data Models" to get a list and scroll down to "Products".
You should pick up some good design ideas there.
This is a pretty common problem - and there are different solutions for different scenarios.
If the different types of product and their attributes are fixed and known at development time, you could look at the description in Craig Larman's book (http://www.amazon.com/Applying-UML-Patterns-Introduction-Object-Oriented/dp/0131489062/ref=sr_1_1/002-2801511-2159202?ie=UTF8&s=books&qid=1194351090&sr=1-1) - there's a section on object-relational mapping and how to handle inheritance.
This boils down to "put all the possible columns into one table", "create one table for each sub class" or "put all base class items into a common table, and put sub class data into their own tables".
This is by far the most natural way of working with a relational database - it allows you to create reports, use off-the-shelf tools for object relational mapping if that takes your fancy, and you can use standard concepts such as "not null", indexing etc.
Of course, if you don't know the data attributes at development time, you have to create a flexible database schema.
I've seen 3 general approaches.
The first is the one described by davogotland. I built a solution on similar lines for an ecommerce store; it worked great, and allowed us to be very flexible about the product database. It performed very well, even with half a million products.
Major drawbacks were creating retrieval queries - e.g. "find all products with a price under x, in category y, whose manufacturer is z". It was also tricky bringing in new developers - they had a fairly steep learning curve.
It also forced us to push a lot of relational concepts into the application layer. For instance, it was hard to create foreign keys to other tables (e.g. "manufacturer") and enforce them using standard SQL functionality.
The second approach I've seen is the one you mention - storing the variable data in some kind of serialized format. This is a pain when querying, and suffers from the same drawbacks with the relational model. Overall, I'd only want to use serialization for data you don't have to be able to query or reason about.
The final solution I've seen is to accept that the addition of new product types will always require some level of development effort - you have to build the UI, if nothing else. I've seen applications which use a scaffolding style approach to automatically generate the underlying database structures when a new product type is created.
This is a fairly major undertaking - only really suitable for major projects, though the use of ORM tools often helps.

Multilingual Site in Zend Framework

i am working on a site to include Multilingual Support.
I can translate strings using Zend_Translate but what about the content??
For example do i have to add multiple records for same product's for each language? Or is there any other way?
I am new to multilingual please help.
Thanks in advance.
--- Addition -----------------------------
Ok, i decided to use a mixed solution to use google translation api and storing it in database for further editing. So what sould be the structure of database to store translations???
Should i save translations of different language in same table as parent record. i.e. for product in product table with an extra column to identity language.
A generalized single table to store all translations of all tables. e.g. translations (id bigint,table_name vc(50),table_id bigint, langugae, column_name vc(50), translation )
should i save records in related tables
Few possible approaches:
Using gettext (or software like Poedit) to extract the data from the content. Possible with variable interpolation.
Creating view filter like described in: Zend Framework and Translation
Have separate content of the data in the database.
If you store the content in markup (e.g. Markdown) format, anyone can translate it easily. It's easy to create search engine in different languages.
Seems the third approach requires the most efforts, but it is worth.
Update after comment
I assume you store your product data in the database, in fields like:
- product_data
-- id
-- price
-- name
-- description
-- etc…
So you should modify it, to add fields for translated strings in each language:
- product_data
-- id
-- price
- product_data_translations
-- product_id
-- language (e.g. en)
-- name
-- description
-- etc
Then you can easily build SQL queries to extract translated data where product_id=x and language="fr".
You may use also Doctrine I18N to do it for you automatically.
You need to translate the content manually (or automate the translation using Google API), but then, you can easily index it using for example Zend_Search_Lucene.

Categories