I'm trying to create a small Web App to categorize certain type of YouTube videos, when users submits a video they will choose what categories this video falls under and they will tag it with ready-made tags, for example:
Video one - Category: Ad - Tags: cute, funny, has animal in it.
I'm trying to sketch my Database for that (I'm using MySQL), so far I have two ideas.
Idea 1:
Table Videos with ID and Category columns, another table Tags with ID and Tag columns while Videos.ID and Tags.ID are linked together. So when the user tries to filter search results by tags, the query will have more conditions (AND Tag = 'something' AND Tag = 'other thing').
Idea 2:
One table Videos with Category and Tags columns, tags are stored as a string separated by commas, when the user tries to filter search results by tags, the query will more conditions (AND Tags LIKE '%something%' AND Tags LIKE '% other thing%).
So the question is: Is there any better method? I already think that the 1st one is wasteful (Each video might have up to 40 ready-made tags) and the 2nd one is clumsy. If not, which one do you think is better?
Creating a additional table linking video id and tag id together is the correct solution. Filtering is done by creating additional INNER JOIN conditions. A comma separated list just won't do - it drastically limits your selection and query possibilities.
Idea 1 looks good. Creating a separate table for storing tags helps in selection.
Related
Currently, I just started as a developer so i am not sure am I doing it right, I am to develop a website with a blog system. Where each of the record added to the database contains multiple tags to identify it, so I treat them as a string Example: "Gym, School, Backyard". and now I have to count the number of rows inside the database of the blog system, in a condition of the data contains certain tags.
How can I make the SQL request to count it? or is there a simpler way to do this?
SELECT ID FROM blog WHERE tags Contains 'GYM'?
you can do it like :
SELECT ID FROM blog WHERE tags IN('Gym', 'School', 'Backyard')
for count:
SELECT count(*) FROM blog WHERE tags IN('Gym', 'School', 'Backyard')
SELECT ID FROM blog WHERE tags LIKE '%GYM%'
I am creating a news web application, and each news has a category field, but this category can be one, or many at times. Which means, that a person may enter politics, world, us tags for just one news article. Now, the problem I have is how to insert this into a database. If I just enter the tags directly to database, as pure text, then I when I have to echo it, I could use explode() to separate them, like
$row['tags] = 'politics, world, us';
foreach(explode($row['tags') as $tag){
echo "<a href='{$tag}'> {$tag} </a> ";
}
Which would echo the tags, and create a hyperlink for each tag, but the problem I have with this is that, if user wants to just see a news with a specific tag, it becomes problem because there is ~no way I could query all the rows, sort out, explode the tags and just show the news feed like that. It is doable, but very cumbersome. So, I would like to ask how to do this. I am certain it involves, having having maybe another table called tags but that is as far as I can go
The proper way to do this is to make a many to many relationship in database. This would require additional table containing id's of categories and articles related to each other
Look at this example of multiple users with multiple roles:
In the same way, you can create a relationship of articles to categories
You can either use a SET to store the data or, which I suggest, add another table for tags and one which stores relations between articles and tags as mentioned by Maciej.
articles table:
id | title | content
tags table:
id | label
articles_tags table:
article_id | tag_id
Consider adding foreign key constraints to the last table, this will make your life easier.
I have 4 tables ...
"content" - Master list of content like title, desc, and contentType
"albums" - Albums made up of several photos
"photos" - Individual photo entries
"photosLinks" - Links photos to album(s)
"tags" - Tags used for searching and finding content
Is it possible to retrieve the photos for the content query if the contentType == 'album' in one query/shot?
For the tags, I can do a simple GROUP_CONTACT() since all we need is the text of the word.
I am not sure of the best approach to handle if(an album) other than reading the result (from php) and then making another query to get the photos linked.
Any tips or advice will be appreciated.
Thanks!!
Thomas
It's possible, but you'd end up with duplicate rows. I.e. you could just join, but you'd end up with something like:
Artist Album Photo
Cowboy Mouth Are you with me? [[Front Cover]]
Cowboy Mouth Are you with me? [[Back Cover]]
If you want some way of associating more than one row in one table to a single row of the result, then I am not aware of a means of doing that. You could do something like store a serialized data structure for one of the photo lists, but that of course doesn't follow the RDBMS philosophy too well.
I just need some advice about using tags. I'm working on a website right now and the users can post videos, images, audio and information about themselves.
I never worked with tags before on a normal website (did work with them on wordpress, youtube etc..), so I need some advise to start designing my database.
What is the common way to work with tags when you have multiple categories? Do I have to add tags for each category?
Example:
Table:
gallery
gallery_id
image
tags
Table
audio
audio_id
title
link
audio_tags
Etc...
Or do I make only one table named "tags" and all the tags in it?
Like:
Table Tags:
tag_id
tag
Thanks in advance.
It is up to you how you need to shape the application. If you want tags to be shared between galleries and audio, use a single table and two many-to-many reference tables (or one with polymorphism).
It depends if you want tags to be shared among multiple objects. If you want that to be separate, then i would make separate tag tables for them. If not, I would have the same tag table, and use different tables for each relation the tags will have, so
for separate:
gallery
...
gallery_tags
tag_id
tag
tags_to_gallery
tag_id
gallery_id
..same for audio..
for not separate:
gallery
...
audio
...
tags
tag_id
tag
gallery_to_tag
gallery_id
tag_id
audio_to_tag
audio_id
tag_id
you could also do this with one ploymorphic table. with a table with something like this:
tag_relations
tag_id
object_id
object_table
Technically the best format is the one you described first, but if you were going to implement the second you would need an extra field - that is the category field. But it would be better and easier to simple have tag fields in each table - better for readability and also use when you come to implement it in your site.
Hope that helps.
I am working on a website that has users and user-generated articles, galleries and video's. I am trying to make a tagging system and a search for them all.
At first I was thinking in tbl_articles, tbl_galleries and tbl_videos I would have a title, description and a tags field. Then run a query like the following for each:
select * from tbl_articles where match(title, description, tags)
against ('$search' in boolean mode) ORDER BY match(title, description, tags)
against ('$search' in boolean mode) DESC, views desc LIMIT 0, 3
The same query for tbl_galleries and tbl_videos. For the users just compare the username. Then display three of each on the results page with a 'more' button (facebook style).
When viewing an article, gallery or video there will also have links to related content so I was thinking of using the same query only with the LIMIT set to '1,3' - to avoid showing itself.
Q1 - How is this system?
I was happy with the system, until I found this
In which they have
a 'tags' table which contains two
columns a primary id and a uniquely
indexed tag_name.
a 'type' table for which they have
another primary id and a uniquely
indexed 'type' (category) (I thought
I could use it for
user/video/article/gallery)
a 'search' table that contains the
url of the article with a foreign id
from 'tags' and 'type'. (I thought
instead of a full url I could just
store the related foreign id so that
I can generate the url e.g
article.php?id=....)
Q2 - This system seems far more efficient... although how would I search the title or description?
Q3 - The other bad thing is for every page view I would have to join the tags.. so it might not be that much more efficient.
Q4 - My system only searches boolean too, would I be better with a 'like' query?
Q5 - I limit my users to 4 tags, but I encourage single-words (stackoverflow style)... I realise though that in my system a search for 'train station' will not match a tag like 'train-station' how do I get around this?
So many questions... Sorry it is so long. Thank you.
Q1 - you're better off with three separate tables for articles, tags, and a link table relating articles and tags. You could also do it with two tables for articles and an articles_tags table. The articles_tags table would contain an articleID field and the tag itself as a compound key. Either two or three tables makes it easy to find which articles have a given tag and which tags are assigned to a given article.
Q2 - title and description searches could be done using "like" with percents or with regex or full text search.
Q3 - don't worry about joining the tags tables with the others. To paraphrase Knuth, build it first, then find the bottlenecks. MySQL is very good at what it does. Joining those tables together over and over and over again won't hurt.
Q4 - It depends what you want to get out of the results. usually you want the actual data and then you can just test for the number of rows returned to tell you whether it's true or false.
Q5 - again, you'd have to use "like" syntax and maybe some creative regex on the PHP side before the query is handed off to the database.
good luck!