Best way to store custom parameters per asset - php

I have a table where I have information about each asset I have (Laptop, Screen, Desktop, Scanners, etc..). I also have another table where I have custom column for each asset (so for a specific desktop I can have a custom column called "Color")... quick shematic :
Assets Table
AssetID Description
---------------------------
1 Desktop HP79801
Assets Custom Column
AssetID Column1 Column2
-----------------------------------
1 Color BluRay ?
Now I want to store the value for each column. The way I currently do it for each unit is :
AssetID UnitID Column1 Column2
-----------------------------------
1 1 Blue Yes
1 2 Blue No
1 3 Black No
1 4 Blue Yes
Now my question, is there a more efficent way to do this and how can I increase the number of column to infinity in an efficent way also ? Is it possible ?
In the end, how to store custom product attributes with effecienty ?

In short, yes.
What you have there isn't scalable in the slightest. What you want is to have a table for your assets, a table for the custom parameters and a "link" table. Then, enter multiple values into your link table rather than multiple columns.
As an example:
Assets Table
AssetID Description
---------------------------
1 Desktop HP79801
Attributes Column
AssetAttr Column1
-----------------------------------
1 Color
2 Size
Link table
AssetID UnitID AttrId AttrValue
-----------------------------------
1 1 1 Blue
1 1 2 Big
1 2 1 Orange
1 2 2 Giant
If your attributes are all model specific though, you may also want to add a AssetId column to your assets custom column, but I wouldn't personally do that unless none of your assets at all shared attributes.
You may also want to tag this further. You may want to annotate your attributes table with a data type, and maybe have another table related to the attributes table holding the possible data values, then, in your link table, insert the ID of the entry from the aforementioned table.

Another solution would be to use a schema less db altogether. My favorite is Mongo. Another option would be CouchDB or one of the many key-value databases out there.
Not to start a noSQL war here but these databases handle situations like that a lot more gracefully - a single document could store all that data and be retrieved without any joins or views.

Related

Do I expand my SKU data fields in a mysql table for easy/efficient queries?

I'm a beginner trying to set up a database structure for a few million records.
My SKU format looks like this:
DESIGN LOCALITY PRODUCT TYPE GENDER COLOR
234324 45454 100 VN M BL
Example table:
SKU | DESCRIPTION | SIZE
I don't really need separate MySQL table columns for each of the fields within the SKU, as they are all contained within the SKU and can be stored in 1 column named SKU.
Yet, will this make my job of doing queries much more difficult and inefficient? Should I setup 1 column for each of the fields within the SKU?
Example table 2:
SKU | DESIGN | LOCALITY | PRODUCT | TYPE | GENDER | COLOR | DESCRIPTION | SIZE
Any help is much appreciated.
Since you need to query against the individual components of your SKU field, I recommend storing each component in a separate column. If you want to include the entire SKU as a field as well (as your "table 2" example suggests), I recommend making it a calculated column. Otherwise you could have update anomalies.
I would also recommend indexing each column individually, but there are others who will recommend a single index that includes all the fields. This is the subject of much debate in database-design circles :).

Many to Many Table Relationship

So a quick question here, I have two tables within my database which is connected to a Yii2 web application.
My two tables are named attributes and people, I have a CRUD area for both of them so I can manipulate the the contents of each table separately.
The two tables are extremely simple at the moment and are structured as follows.
Attribute Table:
attribute_id | attribute_name
------------------------------
People Table:
person_id | person_name
------------------------------
Now the attribute names will be items like hair color, eye color, weight, etc
Now what I want is to be able to assign an attribute to a particular person with a value, for example if person1 existed, I want to assign hair color (Assuming hair color already exists as an attribute) with a value such as 'brown' to person1.
At the moment I kind of have a mental block and don't really know how to go forward from this point on, could anyone point me in the right direction or help me out here?
Cheers.
You need another table
person_attributes
-----------------
person_id
attribute_id
value

Database design: implementing several types of the same entity

I'm coding a Classified Ads web application. The application has several types of Ads:
General ads(electronics, toys, pets, books...)
Real estate (houses, apartments, terrains...)
Vehicles (motocycles, cars, vans, trucks...)
Each type has several common fields (id, title, description) and also some that are exclusive to its kind:
General Ads (no exclusive fields)
Real estate (area, type-of-property...)
Vehicles (type-of-vehicle, cubic-capacity, kilometers...)
What is the most recommended approach to this situation?
A table that contains all fields and leave empty the fields that
don't apply to the current recordset.
A main table with the fields common to all Ads, and an additional table for each type of Ad that has exclusive fields.
One table for each type of Ad.
Other
I would build a solution depending on various criteria :
If you believe the table will be large in the future (a lot of ads to be published), you may want to minimize the number of JOINs for better performance => option 1. "one table with empty fields when not relevant to ad type"
Previous comment applies especially if your data storage cost is low.
If you have to query the data against certain field values (e.g. house size, car kilometers), you might avoid the solution described by phpalix (ad_type | property | value) or Andy Gee since your SQL syntax will be a nightmare, and prefer to have all your data in the same table (again).
If there are A LOT of custom fields per ad type, you might prefer to separate each ad type in their own table, for easier maintenance and data storage optimization. Then you can either JOIN or UNION to query your ads lists.
I'll add to my answer if i think of something else.
You can normalise (a table for the abstract concept and a table the the specialised one) or denormalise (a table with all the fields)
As always, the choice must be done according to the cost of each solution, reprensented by the speed of the queries (normalised model means more joins (buffer/cpu) whereas denormalised more disk reads usually because the columns are sometimes retrieved when it is not necessary) or the storage required in both cases.
All solutions are acceptable and a matter of preference, performance, complexity and design needs. The terms for what you are discussing are Table-Per-Type, Table-Per-Class and Table-Per-Hierarchy. If you google on these you are guaranteed to get a ton of Entity Framework results, but the underlying design considerations are much the same.
For flexibility I would have all the field in a separate table then allow the assigning of each field to each ad type. This would also allow you to add and remove fields easily at a later date.
Each field may have different types of data so this information should also be in a separate table.
Something like this (not very clear sorry)
Table: fields
field_id, field_type, field_name
1 1 title
2 1 price
3 2 size
4 3 description
5 1 square meters
Table: field_types
field_type_id, type
1, textbox
2, select_box
3, text_area
Table: field_data
field_data_id, ad_id, field_id, field_type_id, field_data
1 1 1 1 Cool t-shirt
2 1 2 1 5.99
3 1 3 2 L,XL,XXL,XXXL
4 1 4 3 Some description
5 2 1 1 Nice house
6 2 2 1 250000
7 2 4 3 Some description
8 2 5 1 1024sq/m
Table: ad_types
ad_type_id, ad_type_name, fields
1 general 1,2,3,4
2 real_estate 1,2,4,5
Well, store the values in columns and not in rows, so create a table and have 3 columns:
ad_type, property, value
define your properties for each type of ad and query the ad type for its fields.
Hope that helps

MySQL search in field (or other solutions)

I have a table with products that fall under specific categories, but the products within each category can contain multiple meta data tracking field
Table: products
id name category metadata
1 something 1 blue,red,purple
2 something else 2 left,right,middle
I have been trying to contemplate the best method to have a single product table but can't seem to squeeze the metadata in conveniently. for now I have created a table with all the metadata and fields for tracking the related category (the sequence is so i can order them withing a dropdown etc..)
Updated table: products
id name category metadata
1 something 1 1,2,3
2 something else 2 4,5,6
Table: metadata
id category sequence option
1 1 1 blue
2 1 2 red
3 1 3 purple
4 2 1 left
5 2 2 right
6 2 3 middle
If this format makes sense .. I am trying to generate a query that will search for values in my product table and grab each and all of the related meta values. The issue I am having is trying to find a unique value in the products field. if I do a MySQL search for LIKE(%1%) I will get matches for 1, 11, 21, 31 etc ... I thought of adding a leading and trailing comma to the field by default and then search for ",1," which would be unique .. but there has to be a better way ...
Any recommendations (regarding format or query)?
It's not an ideal design to have comma-separated values within a single database field. Aside from the problem you mentioned (difficult to search), your queries will be less efficient, as the DB won't be able to use indices for the lookup.
I'd recommend making a separate table products_metadata with a many-to-one relationship to the products table. Have the *metadata_id*, and the *product_id*, which is a foreign key linking back to the products table. That will make your job much easier.
You want to add another table, which links products to their metadata. It will have two columns: productid and metadataid which refer to the relevant entries in the products and metadata tables respectively. Then you no longer keep metadata in the products table, but JOIN them together as required.

How to Store Multiple Options selected by User in a Table

So I want my users to be able to restrict who may contact them.
There are several factors they should be able to filter, including Age (e.g. Must be between 18 - 29), income (must earn between $25,000 - $60,000), what they're looking for (e.g. Friendship, Hang out, etc.), what drugs they do (Marijuana, Meth, Cocaine, etc), etc.
The problem is, I want them to be able to select and store multiple choices for some of the criteria (e.g. drugs), but I do not know how I should store that in the DB or how I should structure the table to best accomplish that.
For example, how would I store a user's row that for "drugs" chose "Marijuana", "Cocaine", and "Heroin" within this context? Would I simply store those as comma-separated values in the "Drugs" column? Or should I do it in a completely different way?
What would be the best way to do this (considering I will obviously have to retrieve and check this information every time a user wants to contact another user) and why?
No, don't store the values in CSV format in the database. Instead create a join table called user_drug and store one row for each user/drug combination:
user
id name income
1 Foo 10000
2 Bar 20000
3 Baz 30000
drug
id name
1 Marijuana
2 Cocaine
3 Heroin
user_drug
user_id drug_id
1 1
1 2
2 1
2 3
3 3
A DB column (at least theorethically) should NOT hold multiple values. Unfortunately, there are some programmers that store multiple values in a single column (values separated by comma for examples) - those programmers (in most cases) destroy the concept of DB and SQL.
I suggest you to read about Database Normalization to get a start in organizing your tables. And, do your best to achieve the Codd's Third Normal Form
You can try with this:
criterium
------------
user_id type value
1 AGE_MIN 18
1 AGE_MAX 29
1 INCOME_MIN 25000
1 INCOME_MAX 60000
1 DRUGS Marijuana
1 DRUGS Meth

Categories