I am trying to create a database for storing cars information.
Cars can be categorized as new, used, or for rent.
Each type of car category has different attributes, because new cars have different features that are not needed for used, and same case for used and rent category. Attributes can be added, deleted in future using Application Admin side form manager for these 3 categories.
currently i am storing these in 1 product table with all the attributes required by these 3 categories.
PRODUCT(id,title,description,model,kilometer,enginsize,conditions,.....,.,...)
As form for each category is proposed to be managed from admin control, i am looking for a new scalable database.
current development:
all common attributes in Products
PRODUCT(pid,title,description,...)
CATEGORY(cid,cname) new,used,rent
form_field(formfield_id,name,type) to store all attributes that are not common
form_field_category(formfield_id,cid) to store category associated attributes
form_post_data(post_id,pid,formfield_id,value) to store submitted data
Any suggestions.
for what I understand you have 2 type of attributes: common and category-specific.
So doing something like:
PRODUCT(pid,title,description,...)
CATEGORY(cid,cname) new,used,rent
additional_info_category(aid, cid, name)
adition_info_data (adataid, aid, pid, data)
Should be enough, you just need to loead all the product info plus the fields in additional info that are related to the category.
You should have no issues adding new fields if they are category-specific but my question is: are you sure you won't need to add common fields?
What you need is called an Entity-Attribute-Value model.
If most of the values in table form_post_data are text, simply make it a varchar field. However if you're storing numeric values, choices and other types (things you might want to filter on), have a look at this article An alternative way of EAV modelling.
For you have properties that can have multiple values, have a look at this follow up article EAV multi-value fields.
Related
I have a categories and users table. A user can have many categories and a category can have many users (many to many). However, I also need a feature were users can insert/create their own categories and which is only accessible to the user (category creator) + the defaults categories.
I created a pivot table to handle the many to many relationship, however, I was having difficulty deciding if I need to create another table to handle the custom user categories or just add a user_id on the categories table.
What would be the correct structure I should take/create to handle this.
Thanks.
Given the information you have described, there are two solutions which would be valid: one would be to have a separate table for custom categories, and my preferred solution, would be to have a boolean value on the categories table which indicates whether a category is custom or not. This gives you the following advantages:
Logic applied to the two similar kinds of category remains the same
Other fields which are shared can be kept, in kind
If you wish to convert a custom category to a real category, this then becomes trivial (change the boolean)
You could include a creator id field to identify the person to whom the category applies, alternatively, you might simply designate in-code that custom categories may only have one member.
We have a php/mysql system with about 5 core entities. We now need to add the ability for customers to create custom fields for some of these entities on a per project basis.
They would contain a label, key, type, default value, and possible allowed values.
This is so they could add a custom date field, or a custom dropdown to the UI and save this value against the specific entity.
What is the best approach for storing this kind of data in a mySQL database? I need to store both the config for the field, and then the current value for a specific entity.
I've had a look at various options here.. https://ayende.com/blog/3498/multi-tenancy-extensible-data-model
But this is not really at a tenancy level, more a project level.
I was thinking...
A CustomFields table to hold the configuration of a field against an entity type and project id.
A CustomFieldValues table to hold the value saved against the field - a row per field ( entity_id | field_id | field_value)
Then we create relationships between the entities and these custom values when retrieving the entities.
The issue with this is that there will be as many rows in the Values table as there are custom fields - so saving a entity will result in X extra rows. On top of that, these are versioned, so once a new version is created, there will be another X rows created for that new version.
Also, you can't index the fields on name, joins would become pretty complex i think as you have to join to the configuration and the values to build the key value pair to return against the entity, and how would you select based on a custom field name, when the filed name was actually a value?
I don't want to add dynamic columns to the table, as this will affect ALL the entites in the whole system - not just the ones in the current client / project.
The other option is to store the values in a JSON column.
This could be on the entity row itself customFields or similar. This would prevent the extra rows per field, but also has issues with lack of indexing etc, and still need to join to the config table. However, you could perform queries by the property name if the key=value was stored in the JSON... WHERE entity.customFields->"$.myCustomFieldName" > 1.
Storing the filed name in the json does mean you cannot change it once created, without a lot of pain.
If anyone has any advice on approaches for this, or articles to point me at that would be much appreciated - Im sure this has been solved many times before....
JSON records: No! A thousand times no! If you do that, just wait until somebody actually uses your system for a few tens of millions of records, then asks you to search on one of your extra fields. Your support people will curse your name.
Key-value store. Probably yes. There's a very widely deployed existence proof of this design: WordPress. It has a table called wp_postmeta, containing metadata fields applying to wp_posts (blog pages and posts). It's proven successful.
You will need to do some multiple joining to use this stuff. For example, to search on height and eye-color, you'd need
SELECT p.person_id, p.first, p.last, h.value height, e.value eye_color
FROM person p
LEFT JOIN attrib h ON p.person_id = h.person_id AND h.key='eye_color'
LEFT JOIN attrib e ON p.person_id = e.person_id AND e.key='height'
WHERE e.value='green' and CAST(h.value AS INT) < 160
As the CAST in that WHERE clause shows, you'll have some struggles with data type as well.
You'll need LEFT JOIN operations in this sort of attribute lookup; ordinary inner JOIN operations will suppress rows with missing attributes, and that might not work for you.
But, if you do a good job with indexes, you'll be able to get decent performance from this approach.
The table structure envisioned in my example doesn't have your table describing each additional field, but you know how to add that. It also doesn't have explicit support for multi-project / multitenant data separation. But you can add that as well.
I'm creating a website using Symfony2 and I want my users to see a list of items according to their profile. I am looking for the best way to do that.
The users have basic fields attached to their profile (first name, email, etc.) but I want to add some specific information: gender, income, interests (so different types : bool, integer, string etc). Some fields and values may be added, modified or deleted later.
The items will have criteria so that they will be shown to the corresponding users according to the users' profile.
Actually it is a bit like a shopping website with information attached to products and then the client can reduce the number of items shown thanks to a list of criteria.
I thought of putting an array with the different criteria and values in the User entity but I find this solution really bad.
Do you have an idea of what might be the best Entity/DB schema to do that?
This is filtering, your query which you use to get your product is the one you should play with not the user.
As i understood you want to show different product to each user depending on their gender etc..
You will need some kind of link to know which product to show to which user? Which information you want to check in the product side? you can have an entity linked to product with different information like gender male for a product that you will use in your query to get all select * from product where product.criteria.gender = user.gender this is just a simplified query but it is a bit more tricky with a join if you want to do it in SQL or DQL
I am doing a database for a project and im stuck in a point.
Since every product can have multiple field of use, but even every materials can have multiple field of use, i come up with that solution.
THis is my database architecture.
http://i57.tinypic.com/2mhc03o.jpg
product are specifical for every material e.g. there can't be the same product for 2 material
material are leather, simil-leather, cloth, PVC
field of use are the field which that material can be used: sport, leisure, work
The problem is that material can be used in many field and many field can be used for a material, so it's N:M
Every product can be used in many field and many field can be used for a product so it's too N:M
For example, leather can be used in work, sport, cloth in work sport and office
product can be used in some or all field of application and vice versa.
1)WIth my architecture, to retrieve a material that can be used in a specific field of use i need to do 4 JOIN between all the table. Is it ok? or it's too long?
2)Also, when the user want to add a new category, to insert which field of use that category can have, i need to have a product already for that category.
3)when i want to fill a many to many relationship, i need to do it manually in the conjuction table (field_of_use_product) with some php codes right?
You need three joins for four tables that involved.
No, product may insert after all of the data at foreign tables have inserted.
Yes, it's a simple insert if you know the foreign keys.
I'm new to zend framework but have made my first steps with it successfully.
Until now I have created some Zend_Forms which are mapping single records of my model
to the form fields. I have handled the forms with form classes for each case.
This works all very well until now.
Now I have the situation that I have to asign features to a product. Features and products are parts of my application. Features are stored in my database in three tables. For each feature there is one record in the third table.
First is the feature group where the name of the feature group is saved. Every feature should be asigned to a feature group.
Second table is the features table. This table has an foreign key to the feature group and the name of the feature.
Third table is some kind of many-to-many relation which connects features to products. This table has an aditional field which contains an optional value (beside the two foreign keys) for this unique feature of the product.
For example: if the product has a weight of 4,78 kg the value "4,78" is stored in the third table and the label "weight of %s kg" is stored in the second table. The feature group could be something like "physical attributes" had is saved in the first table.
To cut a long story short:
My problem is how to handle the case that I have to create and edit multiple database records in one form. The plan is to have a form with many checkboxes for each for a feature whereby features are thematicaly grouped. Every checkbox should have an aditional text field to input optional values.
you could make a custom form class that extends Zend_Form and use that for you classes.
It could take in the construct instances of your models and construct the form inputs based on that models.
After form validation in your controller you can do
$values = $form->getValues();
and use that array to populate your models again
You can try creating subforms (Zend_Form_SubForm) inside your form class. This can separate fields for different tables. For edition, in your controller, when you pull all the data from the tree tables, you can populate subforms that correspond to the tables.
You can try to extend Zend_Form to create your own elements.
You will be able to write a class that connects to DB to get attributes (features & products).
Assuming you wrote My_Form_Element_Features & My_Form_Element_Products classes, you can do $features = new My_Form_Features(); and then use the base class methods like getValues(), populate(), etc.
You can take a look there to start :
http://framework.zend.com/manual/en/zend.form.elements.html
http://smartycode.com/extending/database-aware-select-elements/
--
To answer to your comment, you can use :
Zend_Form::setElementsBelongTo($array):
More information can be found at Zend_Form Advanced manual page.