We are building a core shopping cart that our company will use as a foundation for multiple shopping carts we will build. These are highly specialized, so different product types will require their own tables of data.
For instance, for a cart that sells labels...
product - id | type_id | created
label - id | product_id | x | y | z
We're struggling with how to structure our objects. We'd like to programmatically only interact with the Label class and have the data be "split" so to speak between the two tables. One idea we tossed around was creating a view to use for querying and then just overwriting the object's save() method to actually interact with each table's setters/save functionality.
Has anyone accomplished this or at least faced a similar challenge?
Update: Of course this begs the question... is there a scenario where both tables might have the same column name? And if so, how to handle it.
You can use name/value pair for specialized columns. With "name" part consistent with column names, you can have generalized setter/getter.
Product is related table, so you can interact with it via relation, for instance $labelModel->product. So you have model for each table, as yii suggest. And you can interact only with Label model if you place your functionality at beforeSave(), afterSave() and other methods.
Related
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.
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.
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.
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.
I have a problem with using the ORM and creating a has and belongs to many self join using Kohana 2.3.4
I have this table
Tasks
ID | Title | etc......
I need to be able to link tasks to other tasks, a task can have multiple children, and multiple parents. So I was thinking of having this table.
Tasks_Tasks
ID | task_1_id | task_2_id
To link the tasks to each other, but I can't work out in Kohana how to set the foreign keys correctly for the relationships, or if it is possible at all?
Can anyone suggest an answer? Or even better, a better solution?
Instead of extending ORM you should be extending ORM_Tree. This is built for just this type of relationship. Take a look at system/libraries/ORM_Tree.php.