I want to add categories to my website - but with more complex sorting.
Lets say I have article a. now, I want a to be under main category a, but also on category c thats its parent is b.
I thought of doing it like this:
An article would have a main category field, and also parent_ids
parent_ids would be every category this item is belong to.
my problem is: lets say i have: parent_ids: |1|5|2|7|.
now i am in category id - 7.
how would my select query look like?
select * from categories where parent_ids LIKE '%|7|%'
is it efficient? is there a better idea?
Never store multiple values in one column. All column values in a normalized database should be atomic (single-valued).
The relationship between articles and categories is many-to-many. That means you should have a separate table, such as article_category (article_id, category_id) containing one row for each category each article is in.
Related
Hello.
So I'm doing the article submission atm and I need articles to have multiple categories... Article categories would be stored in articles table under categories field like this {"cat1","cat2","cat3"}. But a mind popped to my head... "What if I want to lookup articles by a category?". If I would do something like SELECT * FROM articles WHERE categories = ? then I can't define what categories which post has... So I can't lookup by a category this way. Any suggestions, solutions? Much appreaciated!
Edit: If I would retrieve all post from database and do some for each solution it would cause server loads or even crashes for several minutes. Right now I have 7,307 articles.
To resolve your actual problem, you can use this sql query
SELECT * FROM articles WHERE categories LIKE '%cat1%'
But, about database scheme, Best way should like to have articles categories and a pivot table article_categories table. A many to many relation would help
articles
id,
title
...
categories
id,
name, ...
article_categories
id,
article_id,
category_id
I have to create a web site witch contain goods. these goods have their own categories.for a
example a good can be categorized in many categories or sub categories.
I already have a item table witch contain their properties. and can anyone say how to keep it`s categories in database without duplicating data
Ok. In this case an Item may have many categories and a category may have many Items. So its a many to many relationship. Try as follows,
Your Item table may look like this,
Item(id, description, amount, ... )
In your Category table,
Category(id, name, description, ... )
And there will be another table to assign categories to items,
ItemCategoryAssignments(itemId, categoryId)
And there will be two foreign keys at ItemCategoryAssignments table. That,
itemId references id in the Item tabel
and
categoryId references id in the Category tabel
Like that. There will be no duplicated rows. Hope this will help.
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
How could I create a list in php of categories and types of topics that are mixed together?
Meaning, the list should look like this:
Sports (this is a category)
Soccer (this is a type)
Golf (this is a type)
Basketball (this is a type)
Science (this is a category)
Biology (this is a type)
Chemistry (this is a type)
Anatomy (this is a type)
The difficult part is that sports and science come from the same table (called categories), and soccer, golf, basketball, biology, chemistry and anatomy all come from a different table (called types). In the MySQL table "types" there is a foreign key that points to the id of the entry in the categories table. The current setup in MySQL cannot easily be changed as the navigation of the site is dependent on it.
How could i use php to put the types in between the categories?
Currently the code i have is this:
<?php session_start ();
include 'connect.php';
$result = mysql_query("SELECT * FROM categories JOIN types ON categories.catid = types.typecat");
while($row = mysql_fetch_array($result))
{
echo $row["catname"];
}
?>
However, that outputs "SportsSportsSportsSportsSportsScienceScienceScience," which it obviously shouldnt. There are 5 types in sports, and 3 in science. So i am not sure what is happening there and i cant proceed on to the next step of adding in php to include the types.
I think you need two lists with main category and sub-category, if so you can do as follows
fetch categories from db and display in list 1 with sub category list empty
on change of category submit the form using jquery or javascript
based on category posted fetch sub-categories from database and display in list 2 and select attribute of list 1 make it as selected based on posted category value.
You can use ajax too instead of submitting form.
I believe you have an id_cat in your types table.
Then you should use SQL JOINs.
I don't have the code for you, but the query would be either:
select category, type from categories c, types t on c.id = t.id group by category;
or:
select distinct category from categories;
Then query each category individually.
I suspect the single query would be more efficient.
I'm trying to create a web index. Every advertiser in my database will be able to appear on a few categories, so I've added a categorys column, and in that column I'll store the categories separated by "," so it will look like:
1,3,5
The problem is that I have no idea how I'm supposed to select all of the advertisers in a certain category, like: mysql_query("SELECT * FROM advertisers WHERE category = ??");
If categories is another database table, you shouldn't use a plain-text field like that. Create a "pivot table" for the purpose, something like advertisers_categories that links the two tables together. With setup, you could do a query like:
SELECT A.* FROM advertisers AS A
JOIN advertisers_categories AS AC ON AC.advertiser_id = A.id
WHERE AC.category_id = 12;
The schema of advertisers_categories would look something like this:
# advertisers_categories
# --> id INT
# --> advertiser_id INT
# --> category_id INT
You should design your database in another way. Take a look at Atomicity.
Short: You should not store your value in the form of 1,3,5.
I won't give you an answer because if you starting you use it this way now, you going to run into much more severe problems later. No offense :)
It's not possible having comma-separated values to do this strictly in an SQL query. You could return every row and have a PHP script which goes through each row, using explode($row,',') and then if(in_array($exploded_row,'CATEGORY')) to check for the existence of the category.
The more common solution is to restructure your database. You're thinking too two-dimensionally. You're looking for the Many to Many Data Model
advertisers
-----------
id
name
etc.
categories
----------
id
name
etc.
ad_cat
------
advertiser_id
category_id
So ad_cat will have at least one (usually more) entry per advertiser and at least one (usually more) entry per category, and every entry in ad_cat will link one advertiser to one category.
The SQL query then involves grabbing every line from ad_cat with the desired category_id(s) and searching for an advertiser whose id is in the resulting query's output.
Your implementation as-is will make it difficult and taxing on your server's resources to do what you want.
I'd recommend creating a table that relates advertisers to categories and then querying on that table given a category id value to obtain the advertisers that are in that category.
That is a very wrong way to define categories, because your array of values cannot be normalized.
Instead, define another table called CATEGORIES, and use a JOIN-table to match CATEGORIES with ADVERTIZERS.
Only then you will be able to properly select it.
Hope this helps!