Database design for posts and comments - php

If one post has many comments, and the comments are essentially the same as posts (e.g. they have a title, pictures and audio etc.) should I create two tables or just one?
For example, if I only use one table I can have a parent_id column, so If it's not a reply to anything it would be null, otherwise, it would have the id of the parent post. On the other hand I can create a post table and a comments table. Comments can also reply back to other comment so this could get confusing quick.
*Post*
id
title
content
image
audio
parent_id
or,
*Post* *Comments*
id id
title title
content content
image author_id
audio post_id
author_id image
audio
What the second option would allow is creating indexes. Infact I won't even have to add author_id or post_id If I use indexes from the start will I?
What are you thoughts on this SO? Which would be more efficient? I thinking of using redbeanphp for this.

The second option would be better. When displaying a message board, you don't care about comments and looking them up by an indexed parent post id column is fast. Posts and comments will likely have different fields, so keeping them separate is correct. The parent id index for the first option would work fine, but conceptually, it's messy and you're basically creating an index to use on half or however many comments there are relative to posts.

As a rule in database-design: Tables are called entities, so each entity in your application should be separated and demonstrated by table. Here, although you regarded posts and comments each has the same kind of data but finally each of them is a separate entity so they should be separated in two tables. This behavior is not a personal opinion. It is basic rule that leads to more smooth application development.

Related

For a post with categories, what is faster: Several database calls or additional PHP code?

I'm designing a blog database. I want posts to belong to any number of categories, including none (i.e. number of categories = 0, 1, 2, 3, ...).
I understand that the common way to design such a database (e.g. in Wordpress), is to have one table for posts, one table for categories, and one table for relationships, thus:
table relationships
column relationship id
column post id
column category id
But this means that to display a post, my script will have to make at least three database queries. This seems slow to me.
Which is why, in another blog, I had only one table for posts which included a varchar column for categories, in which I inserted a string with all the category names, which I parsed in PHP, thus
table posts
column post id
... (many other columns)
column categories
where column categories contained a string that might look like this:
apples,oranges,bananas
which I simply explode()ed in PHP.
Please explain why I should avoid the second method (one table, explode). There must be something wrong with it that I miss, because it is not commonly used in blog software.
Note:
There might still be a table listing categories, into which new categories are written when a post is created, and from which lists of categories are drawn to display them in, of example, the sidebar.
I expect there to be many more queries for posts than for posts-in-categories, which is why I don't worry much about querying the second database for posts from a certain category, which might be faster in the first database.
In second case you will get huge problems with finding post by some category.
For example, you write posts about programming languages and want to show all post about python, php, ruby, etc on separate pages ... but you can't write simple and quick request to database because you violates 1 normal form in your second database scheme.
JimL has already mentioned JOIN which allows to make 1 request and get all needed information from standard many-to-many relationship scheme with link table post2category

How to deal with multiple categories entry for an article website

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.

How to design a database to achieve navigation effect in a website with php?

So I'm trying to build a website in which I will have different Youtube videos organized in playlists.I want a page to display the playlists I have grouped by categories, and a watch page to watch the videos with "previous" and "next" buttons. I am using PHP and MySql. I always sucked at databases and table relationships; so I'm clueless about this. So my questions are:
first of all, What would be the best way to organized my videos? I want my links to be something like watch.php?playlist=n&video=n, where video=1 will always be the first video on the corresponding playlist. Right now I have a playlist table with the columns playlist_id(PK) playlist_name and category. Then I have a table for each specific playlist, the columns for these are: video_id(PK) playlist id(FK ref playlist.playlist_id) video_name and url. Am I on the right direction there?
my second question is: is it a good idea to store the Youtube video urls in the database? if not, what's the best way to do it?
and last but not least, what is the best way to accomplish the navigation effect I want(linking to the previous and next videos from the currently displayed one)? I know I have to use the _GET and _POST methods for this and I'm sure I'll be able to figure it out but if you know a very good way to explain this I will appreciate it
On your first question:
There are many useful database structure patterns you may want to look into.
Adjacency list
One of the simplest and most intuitive is the adjacency list (1:M):
CREATE TABLE `playlist` (
`playlist_id` INTEGER NOT NULL AUTO_INCREMENT,
`youtube_id` VARCHAR(255) NOT NULL; DEFAULT '',
-- other necessary fields pertaining to a playlist
PRIMARY KEY(`playlist_id`),
KEY(`youtube_id`)
);
CREATE TABLE `video` (
`video_id` INTEGER NOT NULL AUTO_INCREMENT,
`youtube_id` VARCHAR(255) NOT NULL; DEFAULT '',
-- other necessary fields pertaining to a video
PRIMARY KEY(`video_id`),
KEY(`youtube_id`)
);
The above only has the drawback of making it impossible to assign a video to multiple playlists -- unless you accept the fact that a video record can have different video_ids but the same youtube_id (you insert the same video twice into the table in order to associate it with 2 playlists).
Junction table
Another classical database design pattern is the junction table (M:N) which implies creating a separate table which associates a playlist_id with a video_id. This allows you to insert a video only once in the video table and associate it to multiple playlists.
Ancestor table
If you need to create hierarchies such as categories of playlists which have subcategories which finally have playlists you can use the ancestor table (similar to a junction table) by storing each level of relation "parent/grandparent/ancestor-level-n".
Taxonomies:
Another approach is the taxonomy pattern in which you can construct various types of taxonomies. For example if you want to organize your playlists as categories which contain subcategories which contain playlists (to which videos are attached).
You may want to create a single taxonomy table to store in it either category records or playlist records.
On your second question:
Storing YouTube videos URLs in the DB is perfectly fine. Many CMS platforms keep links and/or entire embed snippets as varchar or text in the database.
Since you know you only want YouTube videos you can take advantage of that and store less data in your database by extracting only the relevant content from the YouTube URL.
URL: www.youtube.com/watch?v=VIDEOID&list=LISTID
You can parse_url to get the query string and then parse_query to get the v and list parameters respectively.
If the above advice is good for your usecase (you're sure youtube is and will always be your most important/only provider) you can drop the playlist_id and the video_id and use the youtube_id from each table as the primary key (they're short enough, you can index them well, you can set a unique constraint on them etc.).

Is it better to have separate tables for articles & comments, or one table for both?

I am working on a little project where a user submits an article to MySQL, and then PHP send the post to the screen. So far so good.
Now i want to extend it to a "two level" post system, where people can comment on the articles.
The case is, i dont know how to do that.
The table i use for storing articles:
TABLE: posts
id user date avatar signature post
Should i make a new row named comments in the posts table, or should i place the comments in a seperate table? one for articles, one for comments?
All help is much appreciated.
Depends on how you use it on your website. You have to ask: "are my articles and comments essentially the same concept?" If yes, then use one table, if no, use two. On most websites articles work differently, can be categorized, editted etc., and usually need a different fields which would clutter the comments table... so in that case two tables are more reasonable. But if you conclude that on your website articles and comments are generally the same (but try to think future proof: wouldn't you need to add some article functionality in 2 months?) then you can think of articles also as of comments and have one table for them.
If you decide to merge things to one table, and you realize that you need another column to distinguish type of the post, and that some columns remain unused for some types, it is a clear warning signal you should have two tables!
This is a little subjective, but I would just set up a parent/child relationship on your posts table, make a parent_id column that is a foreign key for the id column in the same table. for extra credit, you can make it a nested set relationship which will allow you to pull the parent and all the children in one query

Thinking logically about a database structure: Adding 'tags' to things users post - A seperate table or...?

I'm still beginning to get my head around this whole relational-database-thingymawhatsit. Anyway, I'm a PHP programmer so I can do all that shabang. I just need to think what would be the best method for this scenario...
I'm developing a site (with CodeIgniter if that's any help) - a site where users can post content (think a blog-style thing). Each post has to have tags, any number of tags, I can't just be constrained to, say, 3 or 5. This has got to be unlimited.
So which of these do I do?
Put the tags alongside the posts in the same database table, i.e. 'entries' contains 'post', 'title', and 'tags' (and obviously 'id')
Put the tags in a table of their own and link each tag row to an entry('s) 'id'...?
...Something else entirely?
Just need to know the best, most logically structured way of doing this. Thinking about tables communicating with each other is confusing enough...!
Oh, and bonus points to anyone with any CodeIgniter snippets that may get me along on my way ;)
Thanks!
Jack
Basically, you want an n-m relation between tags and posts :
each post can have several tags
each tag can correspond to several posts.
Using a relationnal database, this is done with three tables :
a "post" table, that contains one line per post
a "tag" table, which contains one line per tag
and a "post_tag" table, which contains one line per correspondance between a tag and a post -- which means several lines per tag ; and several lines per post
You'd have, in your DB, those three tables :
post
id
title
content
...
post_tag
id_post => foreign key to the post
id_tag => foreign key to the tag
tag
id
name
You want a many-to-many relationship. This is modelled in a database by three tables:
Post
Tag
PostTag
PostTag contains a foreign key to the Post table and to the Tag table. It has one row for each tag on each post.

Categories