I am working on a blog. Now I want to display the most used tags of an author. The tags are stored in the articles table, in a column called tags, komma seperated:
Article table (id | authorid | tags):
1 | 1 | soccer, sport
2 | 1 | sport, tennis, injury
3 | 1 | sport, golf, injury
So I want to display author with id 1 and display his 3 most used tags (from the article table as displayed above). In this case that would be: sport, injury, soccer.
Is this possible in MySql?
Yes its possible, but the better answer would be to direct you into a more "Normal" database structure.
You really need a db set up like:
Table of articles, table of tags, table of article_tags containing the IDs of the tag and the article it's assigned to.
You can then query the tags by each article ('X') by looking in article_tags and returning all tag_id's where article_id = ('X').
You should take a look at database normalization -- the wikipedia article is very advanced however it will give you terminology which you can search for to find more articles on the topic.
The basic idea is you'll have another table:
table name: tags
columns: id | name
And then a table to join them:
table name: article_tags
columns: article_id | tag_id
Then you'll join all of the data together in a query in order to display the tag names for each article. It will then be possible to do more advanced queries on the tables to figure out things such as most used tag by article, and most used tag by author.
Related
I have a small blog project
I have 3 tables
Posts
PostID | TITLE | WRITERS(USERS) | CATEGORIES
1 | SOME TITLE | 1,2 | 1,2
USERS
USERID | USERNAME
1 | Alaa
2 | John
Categories
1 | Business
2 | Marketing
I am trying to get this output
POST TITLE: SOME TITLE
Writers: Alaa And John
Categories: Business, And marketing
Please note that i am talking about a very big loop, 100 post in a page for many viewers
So, currently i have two ideas
First idea
1- take value from writers ( 1,2 )
2- Explode it by php
3- use mysql query to bring the writers
4- Do the same thing for categories
Second idea is to remove the columns writers, categories from the posts table and create a fourth table and call it connections, which will refer ids to each others ( connect everything together )
But i don't even know if i can do the mysql query
You can get all these values in one MySQL query.
SELECT p.TITLE AS `Post Title`,
GROUP_CONCAT(DISTINCT u.USERNAME) AS Writers,
GROUP_CONCAT(DISTINCT c.CategoryName) AS Categories
FROM Posts p
JOIN Users u ON FIND_IN_SET(u.USERID, p.WRITERS)
JOIN Categories c ON FIND_IN_SET(c.Id, p.CATEGORIES)
GROUP BY p.TITLE
Output:
Post Title Writers Categories
SOME TITLE Alaa,John Business,Marketing
Demo on dbfiddle
Note: storing values in comma separated lists (e.g. your WRITERS and CATEGORIES columns) is a bad idea and makes writing this sort of query problematic (it's only MySQL's FIND_IN_SET function which makes it workable at all) and you should look into properly normalising your data (one value per row). Here is an example of how your database could look normalised.
I am going to make a website and before that I am going to make a database table. The problem is how to do it correctly. Sorry, but I am new to PHP and Mysql. I only have a definite number of categories, so this is my DB view:
--------------------
Video_name Varchar
Video_loc Varchar
cat1 Boolean
cat2 Boolean
cat3 Boolean
cat4 Boolean
cat5 Boolean
cat6 Boolean
cat7 Boolean
--------------------
I kept it like this because 1 video might belong to 2 or more categories. But it will take a lot of space in long term. If a video belongs to cat2 & cat5 then the boolean will have the value "1". But others will also have the value "0" and this is a waste of space.
How can I do it the right way? BTW I have seen Wordpress, it gives the categories a unique ID then on the main table it specifies multiple ids for multiple categories like e.g.: it keeps it like:
-----------------------
id | title | category |
1 | Lorem | 2,4,8,16 |
2 | Epsum | 2,9,8,20 |
3 | Losum | 2,4,9,5 |
4 | Eprum | 2,10,8,1 |
-----------------------
I don't get how it did it like that. Can anyone tell me how to do it like this or any better idea than mine?
Generally it is a "no no" to store structured data within a single column in a table. The Wordpress example does exactly that; it stores a comma separated list of categories in the category column. For that reason I would not recommend using that schema.
The "right" way to do this is to have a table for videos and another table for categories. The relationship between videos and categories is managed by a third table which maps the video to a category and vice versa. There will be multiple entries in this video-to-category table - one for each category that a video can be assigned. Something like this:
table: video
----------------
id int
name varchar
location varchar
----------------
table: category
----------------
id int
name varchar
----------------
table: video_category
---------------------
video_id int
category_id int
---------------------
Another way would be to use a bit field for the categories. Your video table would then have just a single column for all categories with bits set to 1 for those categories to which the video belongs, and 0 for those that it does not. This is an option if storage space is very important to you, however, it is less flexible than using 3 tables, and I recommend the latter approach.
Generally you use a 3rd table with the relationship between the video and category. So you'd have a categories_videos table which has id, category_id, and video id
You can do joins to get all categories related to material, but this is more advanced MySQL. Either start reading the MySQL documentation or pickup a framework that helps you with all this and makes it easier, I always recommend Cakephp.
I am finalizing a comments system and was with a doubt.
I have a table for blogs and one for news, and they accept comments.
My comments table receives the text and the id.
I wonder if I need to (or should I) go through some sort of reference to know where the comment comes from.
table comment
id | id_content | text | ref
1 | 1 | test | blog
2 | 1 | test | news
thanks
depending on the number of comments you expect to receive there are two ways of doing this ...
1 - parent_tbl, parent_id - in one big comment table
2 - two tables for comments with a parent_id - one for each primary table
either way you need to index properly, the second will always work faster, but it doesn't expand well if you say add "press_releases" now you have to duplicate code, tables, what not.
I have several entries (that will grow into thousands) in a database that I want to be able to index via keywords.
So say I have a table such as:
id | username | email | description
And I want to attach multiple keywords to that user such as:
Tall | Blonde | Male | Skinny
How would I structure the table for that? Much like the keywords used in stackoverflow at the bottom of the new question?
Thanks
you need three tables
users:
id | username | email | description
tags: (will contain Tall, Blonde, Male, Skinny etc... in the name field)
id | name
users_tags:
user_id | tag_id
to make a user have a tag, you add a row to the users_tags table with the ids of the associated items.
both user_id and tag_id should be foreign keys, referring to the appropriate table, and combined, they should form a unique key (possibly primary key).
If I understood correctly, have 3 tables:
- users (user_id, username)
- keywords (keyword_id, keyword)
- user_keywords (user_id, keyword_id)
and have relations between them (on same column names as of in an example).
This is a many-to-many relationship.
You have a table of keywords and a table of objects (which can be associated with keywords).
You then have a third table which has two columns which form a composite key, each of which is a foreign key on on of the other two tables.
e.g.
object_keyword_relationship
===========================
object_id | keyword_id
1 | 1
1 | 2
I have two tables
Table 1 is:
id | item_id
---------------
1 | a:2:{i:0;s:1:"1";i:1;s:1:"2";}
and the second table is:
tag_id | tag
------------
1 | c
2 | java
I have stored the id of table two in table 1 after serialize. Now I want to search the tag in table 1 by mysql %like% but the problem is that if I want to search the tag have id 1 or 2 in the item_id it will always find the result even if there is not 1 stored by me but this is stored by the serialize function. Now I want to know what should I do? And any better approach/method will also be appreciated!
Serialized data is not suitable for searching.
It's better to improve your table structure:
Table tags is the same as yours.
Table items_tags with stucture:
id - autoincrement field
item_id - ID of item with tag
tag_id - tag ID
With following structure it's much more easier to search items with tags.
Added
Mayankswami, example queries: For all items with specified tag: SELECT item_id FROM items_tags WHERE tag_id=(TAG_ID) For item's tags: SELECT * FROM item_tags AS IT LEFT JOIN tags AS T ON T.id=IT.tag_id WHERE item_id=(ITEM_ID)