Should the father know about the children or vica versa?
That is, in a situation where I have two kinds of objects (items and categories), each has its own characteristics and fields and we have a relation between them that every item has a category he is in.
I want to ask in two ways about what should happen, in theory and in php + mysql.
Should the categories know about all the items that are in it, or should every item know about its category?
In php + mysql the exact question is should I for every item in its row save its category's id, or should I create a special table for this relation (each row contains a category id and an item id)?
Best practice is the children know about the parents (ex: parent_id). The alternative is not scalable, and very taxing to your system. You could easily run a query to FIND the children though - SELECT * FROM items WHERE item_category = x. The reason for this is when you add or delete items, the category is not affected. It doesn't become a different category because you assign an item to it or remove an item from it, so it shouldn't care either way which items are assigned to it.
This is different from a tagging setup. In the one-to-many category assignment method, items would fall into a single "category" but might have many "features". Tagging features is a many-to-many relationship and would require the mapping table you mentioned. Assigning parent categories requires only a single "parent" field in the items table.
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.
I have the current models:
Categories
SubCategories
Items
Each can have many of the others. For example, an item might belong to subcategory id 1, but the same item might also belong to subcategory id 2. Then subcategory id 1 might belong to category id 1, as well as subcategory id 2 belonging to category id 1.
Currently I have a HABTM relationship between each models, using a table called Categories_Sub_Categories or Items_Sub_Categories to link them. However I'd like to know is there a more efficient 'cake' way of doing this?
Categories and SubCategories could be combined into a single "Category" model and use the Tree Behavior to keep track of which is is the parent/child of each. That also allows you to keep more than 2 levels of Categories without need for changing your code.
Then, you can just do a HABTM between Category and Item.
I Have the following SQL schema:
tbl_products:
- id
- id_category
tbl_categories:
- id
- id_parent
tbl_products_categories: - id_product - id_category
My question is: In my categories model, what kind of relation I have to declare to get all products from this category and from it's childs ? Can I get all products from a relation or will I have to make a method to loop for each child-category and later merge all products and return it?
Anyone have any idea ?
Nested relationships, such as among categories or menu items, are notoriously tricky. The case is a bit simpler when you have constraints, such as a maximum number of children. In that case, your Product's criteria would contain as many joins as you have possible relationships (I wouldn't use Yii's relational active record in this case; would it make it too complicated in my opinion).
Otherwise, yes, your best bet is to loop recursively through each relationship and return a merged array. NOTE: this can be incredibly performance intensive, so you'll probably want to do some sort of caching on pages where this action is performed.
Since it is many to many, each product can be associated with the current desired children and all its parents, so when you query a parent, all children products will also be parent products.
I want to store reviews in a flexible system of categories and subcategories, and am currently in the process of designing the database structure for that. I have an idea how to do that, but I'm not entirely sure if it couldn't be done more elegant and/or efficient. These are my thoughts - if anybody can comment on if/how this can be improved I'd be really grateful.
(To keep this post concise, I only list the important field for the tables)
1.) The reviews are stored in the table "reviews". It has the following fields:
id: uniquite ID, auto-incrementing.
title: the title that will show up in <head><title>, etc.
stub: a version of the title without spaces, special chars, etc. so it can be part of the URL/URI
text: the actual content
2.) All categories are in the same table "categories"
id: unique ID, auto-incrementing.
title: the full title/name of the categorie how it will be output on the website
stub: version of the title that will be shown in the URL/URI.
parent_id: if this is a subcategory, here is the categories.id of the parent category. Else this is 0.
order_number: simple number to order the categories by (for display in the navigation menu)
3.) Now I need an indicator which reviews are in what categories. The can be in multiple. My first idea was to add a "review_list" field to the categories and have it contain all reviews.id's that should be in this category. However I think that adding and removing reviews from categories would be a hassle and "unelegant". So my current idea is to have a table "review_in_category" and have an entry for every review-category relation. The structure is:
id: Unique ID, auto-increment.
review_id: the reviews.id
category_id: the categories.id
So if a review is in 3 different categories it would result in 3 entries in the "review_in_category" table.
The idea is, that when a user opens www.mydomain.de/animation/sci-fi/ the wrapper script will break up the URL into its parts. If it finds more than one category with category.stub = "sci-fi", it will check which of those has a parent category with the stub "animation". Once the correct category is identified (most the time the stubs are unique anyway so this check can be skipped) I want to SELECT all review_id's from "review_in_category" where the category_id matches the the one determined by the wrapper script. All the review_id's are put into an array. A loop will iterate through this array and compose the SELECT statement for listing all review titles (and create links to them using the stub values) by "SELECT title, stub FROM reviews WHERE id=review_list[$counter]" and then add "OR id=review_list[$counter]" until the array is completely travelled.
SO my questions are:
- Is the method my creating a single SELECT statement with potentially a large number of "OR id=" parts an "elegent" and/or efficient way to handle this situation or are there better variants?
- Does using a "taxonomy"-style table (review_in_category) make sense or would it be better to store the "membership"/"relation" directly in the reviews or category tables?
- Any other thoughts... I just started to learn this stuff and appreciate any feedback.
Thank you
Your design looks sound.
To retrieve all reviews in a category, you should use a join:
SELECT reviews.title, reviews.stub FROM reviews, review_in_category WHERE reviews.id = review_in_category.review_id AND category_id = $category
First question on stackoverflow. I used this A more dynamic way of nesting multi-level categories for creating multilevel category table for my assignment.
I have childof field in category table for managing parent-child relationship. I am clear about fetching these categories based on childof. The root categories will have "childof = 0".
While adding a new category , I will represent a choose parent drop down of all categories in the form and user will choose one parent for this new category child (which is to be added).
I am confused about updating the categories : -
While updating a category , I am having two problems.
a) I can not use current choosen category in the choose parent drop down as this will assign parent to itself. I mean same id can not have same childof id ?? what do you think ?
b) What about editing root categories ?? Editing their parent and moving them to other sub levels can cause problems ??
Any other way of doing this is most welcome.
please help
Welcome to StackOverflow; I hope you've read the faqs
In answer to your questions:
(a) Yes, you can just restrict the "select parent" drop-down to list all categories except the current one. One way to do this is by retrieving the correct categories, i.e.
SELECT category_id,category_name
FROM categories
WHERE category_id != $thisCategoryId
Or you can do it in the php code by checking each value when you loop through them.
(b) Yes it would cause you problems if you move a category to be a sub-category of one of its own sub-categories so you will need to check that as well
There are lot of ways to solve this, there is a discussion already answered on this please refer this