multiple fields in mysql - php

Ok, I hope I can make this question as clear as possible.
I have the following table:
table: phones
phone_id | name | ... ... ... | manufacturer_code
-----------------------------------------------------
1 | samsung | | 001
2 | apple | | 002
3 | htc | | 003
and so on...
I have A LOT of columns (... ... ... means at least 40 different columns like width, height, depth, color, has_bluetooth, ... stuff like that).
Now I want to do this differently, but I have NO IDEA how to start.
How I THINK to do it? (correct me if i'm wrong!)
1) Store the field names in a different table
table: phone_fields
field_id | name
--------------------------------
1 | name
2 | width
3 | weight
4 | depth
... | ...
41 | manufacturer_code
2) Connect the fields with the data for each phone in another table
table phones
row_id | phone_id | field_id | value
------------------------------------------------------
1 | 1 | 1 | samsung
2 | 1 | 2 | 10,50 cm
3 | 1 | 3 | 1 kg
... (and so on).
I want this to be searchable/filterable, I have a filter now which filters on brand, color, pricerange, ... and this works fine.
How should you guys do it? Or does anyone have a useful link/tutorial about this? English is not my native language so I don't know exactly how to search for it.
Thanks in advance!
Edit: why am I doing this? I want to be able to add extra fields through my admin-panel if necessary (and not via phpmyadmin or something like that).

If your request always returns the entire set of fields, then leave it in one table
If not, then you can leave only the most important fields in one table, and in the other table place the remaining attributes and link it via foreign key

Related

How to identify which table to delete a record when data coming from two tables?

I have two tables where some same kind of information kept. One table has approved information and other one contains pending(waiting for approval) data. I fetch data from both table and display in a same view. So user will see data from both the tables. User can delete those records. But when deleting I've a trouble with finding out which table I should delete.
Assume, table1(Approved info), table2(Pending info)
table1
id | name | description | creator |
-----------------------------------
10 | test1 | N/A | 100 |
11 | test2 | N/A | 100 |
12 | test3 | N/A | 101 |
13 | test4 | N/A | 200 |
table2
id | name | description | creator |
-----------------------------------
10 | test1 | N/A | 105 |
11 | test2 | N/A | 103 |
12 | test3 | N/A | 106 |
13 | test4 | N/A | 202 |
table1 has a record with id of 10; and table2 has a record with id of 10 in that table. Id is the primary key of both tables. Both record will show to user. Let's say user wants to delete the record related to id 12 came from table2. So I want to delete that record from table2. But how can I figure out which table to delete that record. Because I can't use id to figure out the table. I have tried using some kind of data attribute attached with
data coming from table2 to differentiate them. But anyone can change them by inspecting it. So what is the proper way for solve this issue?
On any case, on any system, makes sense to have two to tables with same columns. That should be one of the firsts rules of database design. What's more, you discovered yourself how hard is to maintain a design like that. I see this on legacy systems developed with zero love to the code. In the future this will turn into a snowball. You should change it as soon as possible.
status column
The status of and entity or resource, is classic requirement, usually implemented with one little column which called : status, flag, mode, etc. In your case, it could have these values (#BhaumikPandhi comment):
pending/approved/rejected
id | name | description | creator | status |
--------------------------------------------
10 | test1 | N/A | 100 | pending|
If you are worried to the database optimization, you could use a tinyint with these equivalence in your documentation:
1 = pending
2 = approved
3 = rejected
status table
You could keep your first table called record
id | name | description | creator |
And create another one called record_status with 2 columns, in which record_id is a FK of record table
record_id | status |
Anyway, the status column is the most easy a classic approach to your requirement.

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.

Laravel: how to make a key of a column name?

I'm bending my mind for some time now over this problem. Could someone please help me?
I have two tables: products and product_attributes. The product has all basic product information and product_attributes has all specific information for products on different categories. It's much like the magenta attribute system. this table has 4 columns: id, product_id, attribute_name, attribute_value.
Now let's say a product has 2 attributes:
------------------------------------------------------
| id | product_id | attribute_name | attribute_value |
------------------------------------------------------
| 1 | 123 | length | 123cm |
------------------------------------------------------
| 2 | 123 | material | Denim |
------------------------------------------------------
| 3 | 123 | season | Summer |
------------------------------------------------------
Now if I set up the eloquent relationships and query a product, I get a product object with all three attributes. So far this is what I wanted. But now in a blade template I would like to be able to do something like this:
$product->attribute->length
Is this even possible or do I need to achieve these kind of things with a total different approach (like creating different tables for different product types/categories)?
Thanks in advance!
length is a tuple value not an attribute you need
$product->attribute->where('attribute_name', 'length')
or
$product->attribute->whereAttributeName('length')

how to maintain a continuous id number row count in mysql

i have an id coloumn which is integer and auto incremented type.
The problem is when ever i delete a row the continuity of the number breaks.
+----------------------+----+
| name | id |
+----------------------+----+
| mashable | 1 |
| Behance | 2 |
| Techcrunch | 3 |
| flipkart | 4 |
+----------------------+----+
FOR EXAMPLE if i delete the row with id=2, then i output in id will be
+----------------------+----+
| name | id |
+----------------------+----+
| mashable | 1 |
| Techcrunch | 3 |
| flipkart | 4 |
+----------------------+----+
but i want it to be like :
+----------------------+----+
| name | id |
+----------------------+----+
| mashable | 1 |
| Techcrunch | 2 |
| flipkart | 3 |
+----------------------+----+
How to do it ??
To directly answer your question, here's how you fix those gaps in sequential numeric fields: Fixing gaps in mysql table row id after we delete some of them
But let's be careful here for a moment.
Let's assume id is your primary key. ID's are usually the point of reference to an object, because auto-generated ID's are unique. Call it a convention.
That means that If ANY part of your code depends on the id column, your application will break.
If you NEED to do this, then use some other field as main reference. Perhaps an unique name field or something similar.
If ID is NOT your primary key, then you probably should've chosen another name for it to begin with. Anyway, in this case, the chances of you breaking anything are much smaller.
Notice that I said smaller, but not zero. We don't know your application, so it's possible that your code uses id for something important, and that'll mean trouble for you.

MySQL query how to get list of all distinct values from columns that contain multiple string values?

I am trying to get a list of distinct values from the columns out of a table.
Each column can contain multiple comma delimited values. I just want to eliminate duplicate values and come up with a list of unique values.
I know how to do this with PHP by grabbing the entire table and then looping the rows and placing the unique values into a unique array.
But can the same thing be done with a MySQL query?
My table looks something like this:
| ID | VALUES |
---------------------------------------------------
| 1 | Acadian,Dart,Monarch |
| 2 | Cadillac,Dart,Lincoln,Uplander |
| 3 | Acadian,Freestar,Saturn |
| 4 | Cadillac,Uplander |
| 5 | Dart |
| 6 | Dart,Cadillac,Freestar,Lincoln,Uplander |
So my list of unique VALUES would then contain:
Acadian
Cadillac
Dart
Freestar
Lincoln
Monarch
Saturn
Uplander
Can this be done with a MySQL call alone, or is there a need for some PHP sorting as well?
Thanks
Why would you store your data like this in a database? You deliberately nullify all the extensive querying features you would want to use a database for in the first place. Instead, have a table like this:
| valueID | groupID | name |
----------------------------------
| 1 | 1 | Acadian |
| 2 | 1 | Dart |
| 3 | 1 | Monarch |
| 4 | 2 | Cadillac |
| 2 | 2 | Dart |
Notice the different valueID for Dart compared to Matthew's suggestion. That's to have same values have the same valueID (you may want to refer to these later on, and you don't want to make the same mistake of not thinking ahead again, do you?). Then make the primary key contain both the valueID and the groupID.
Then, to answer your actual question, you can retrieve all distinct values through this query:
SELECT name FROM mytable GROUP BY valueID
(GROUP BY should perform better here than a DISTINCT since it shouldn't have to do a table scan)
I would suggest selecting (and splitting) into a temp table and then making a call against that.
First, there is apparently no split function in MySQL http://blog.fedecarg.com/2009/02/22/mysql-split-string-function/ (this is three years old so someone can comment if this has changed?)
Push all of it into a temp table and select from there.
Better would be if it is possible to break these out into a table with this structure:
| ID | VALUES |AttachedRecordID |
---------------------------------------------------------------------
| 1 | Acadian | 1 |
| 2 | Dart | 1 |
| 3 | Monarch | 1 |
| 4 | Cadillac | 2 |
| 5 | Dart | 2 |
etc.

Categories