I'm trying to make a forum - php

So I have these tables:
Topics
id, title, date
Posts
id, title, text, date, user, topic_id
How should I structure it so that the first post, the topics text, is on top of all other posts in the topic? Sort them by date? Or is there a smarter way?

Yes, sort by date (or by post ID). How else would you do it with that database structure?

Query
mysql_query("SELECT * FROM posts SORT BY date ASC");
Actually now that I look at this you may want to add time and sort by time and date, so that way two posts in the same day are shown in the correct order. It is not very clean to sort by id.
When adding pagination, you will be using MySQL's LIMIT to choose the records for that page. So if you are showing 20 records per page the query would look as so.
1st page:
mysql_query("SELECT * FROM posts SORT BY date ASC LIMIT 0,20");
2nd page:
mysql_query("SELECT * FROM posts SORT BY date ASC LIMIT 20,40");
The first page is calling records 0 through 20.
The second page is calling records 20 through 40.
It will sort them by date and time (maybe) accordingly. I am interested in how your forum will turn out! Let us know!
Best of Luck!! Let me know if you have any questions or concerns.

Related

Complex SQL Query - Popular Content

So, I'm writing a query to select data from the database, and display it in an order of popularity. I understand that this is simple enough to do if it were just ordering it through something such as ORDER BY numLikes DESC or something, but in this case, I am wanting to order the content by numLikes and through datePosted.
How would I sort the content in a way that it displays the top content from today's date? If it sorted purely through numLikes, The top content would float to the top and stay there. I want this content to be sorted through a daily basis. This is to allow for a system where the user can choose popular posts from the past day, past week, past month, and all time top posts.
Could this be done through a single SQL query? Would an SQL multi-query have to be done? Is SQL powerful enough to do this, or is PHP required to play a role?
Thanks!
You just need to sort on datePosted first and then by numLikes. Something on the following lines:
SELECT * FROM tableName ORDER BY datePosted, numLikes DESC
If you want top post between a particular range, you can do:
SELECT TOP 1 * FROM tableName
WHERE datePosted BETWEEN [MinDate] AND [MaxDate]
ORDER BY datePosted, numLikes DESC
Replace [MinDate] and [MaxDate] with the dates you need, e.g. for the past week, they would be something like April-14 and April-20.

Limiting row count to a specific number when inserting

I'm thinking of implement a view history for my wordpress blog, where users can view their previously viewed articles as a list in their account page.
I would like to limit this to 24 unique page history per user at any point of time, meaning, if the number of articles exceeds 24, the oldest article row would be deleted, and the new article added to the table.
I'm using PHP and MySQL.
Here's my current thoughts on implementation:
Create a table with user_id and post_id columns
When user views an article, insert new row into the table
Select the rows with the current user_id, and if number of rows is more than 24,
Delete the oldest row
I'm not sure if this is the best method, since it's 3 additional database queries per user page view which is pretty heavy.
Is there a better way to do this?
The ideea is good. Improve it by updating the oldest row instead of deleting it and then adding a new one. ;)
Also make a single read query and a single write query.
make a query that is like this one
SELECT (SELECT COUNT(*) FROM recentArticles WHERE userID = 23)
AS NoOfArticles, articleID, timestamp
FROM recentArticles
WHERE userID = 23
ORDER BY timestamp ASC
LIMIT 1;
If NoOfArticles < 24 then execute an insert query, else execute an update query to articleID
You could always implement this using cookies to key on which pages have been visited and keeping a running list on the users PC. This will reduce the traffic to the site, put the processing scripts on the user-side, and could be easier to implement.
That being said, I agree with the other answer about updating the oldest entry if the table is full. This eliminates the need to delete and add a row. Key off a time-date stamp to sort the entries when you're displaying them and to figure out which page was the oldest (and needs to be updated if >= 24 pages.
You can merge two queries in one. In this way, You will save execution time of your script. So, basically, DELETE row if the post count is more than 24. You can modify this query according to your exact need. But yes, you can think on this way.
DELETE FROM `table_name`
WHERE id=(SELECT (CASE WHEN COUNT(id)>24 then id END)
AS last_id
FROM `table_name`
WHERE user_id='XX'
ORDER BY id DESC LIMIT 1);

Reversing the display of mysql_fetch_array on html page

I have a discussion type page, where users can enter their replies on different subjects. For this, I have a table name replies with fields replyID, topicID, userID, replybody, time
On the page, where I display the result, I use this php command:
$run = mysql_query("SELECT * FROM replies WHERE topicID = $topicnumber ORDER BY time DESC Limit 5");
while($data= mysql_fetch_array($run)){
// do formatting and display data
}
as you can see, the page initially displays only 5 replies on a topic (after which, if interested, user clicks to visit the page where all replies are displayed).
the thing is, the above code displays correctly the recent 5 replies, but I want to change the order of its display. It shows the recent most reply on top, and older replies are displayed as we go down, but I want to change this order, showing the recent most reply on bottom.
I think I'm missing a very simple point here, since most of the website have this feature where recent most comments go down, but hey, "no question is small".
I don't think that's very easy in sql.
I would just load the results in an array and use array_reverse() to reverse the order. Then you can loop through the array and display the values like you do now.
Otherwise I think you need to do 2 queries, one to get the total amount and then one to limit your result set to the last x items.
Use a nested query to reverse the order in SQL:
SELECT *
FROM (
SELECT * FROM replies WHERE topicID = $topicnumber ORDER BY time DESC Limit 5
) AS a
ORDER BY time ASC
The inner query will return your most recent 5 records, while the outer query will reverse the sort order of those 5.

How to select the most recent 10 records

I have a mysql database. How do I select the most recent 10 records? Im not storing timestamps. But the most the recent records are the ones at the bottom rite? Also. How so I get the next ten , the next ten and so on on clicking a button. Kinda like a bunch of forum posts. The recent ones show up first.
I believe you have an auto increment column as a primary key you can use this column and to order by desc
select * from table order by id desc limit 10
otherwise you have a very poor database design
If you have an AUTO_INCREMENT column you can order by that in descending order then limit by 10.
But I suggest you store timestamps and order by that instead so you know you're sorting your records according to date, and not some other value that coincides with date of insertion.
In addition to what #BoltClock mentioned, prequerying the maximum ID might help the engine with what other records are retrieved... ie: if you have a million records, and most recent 10, I don't know if it will still try to query out the million, order them, and THEN dump it.. I would try something like
select STRAIGHT_JOIN
YT.*
from
( select max( IDColumn ) as MaxOnFile
from YourTable ) PreQuery,
YourTable YT
where
YT.IDColumn >= PreQuery.MaxOnFile -10
order by
YT.IDColumn DESC
limit 10
However, if for some reason, records are allowed to be deleted, you may opt to subtract a little farther back than the -10... but at least this way, the system won't even TRY to process all the other records...

Getting last and next db-record by date in MySQL-Table?

I've got a certain question related to a blog, which I am developing in OOP (PHP) right now. All blogposts are stored in a MySQL-table.
In the app you can read a specific post by giving the id of the post via GET-parameter. So like http://example.com/?id=2. Under the blogpost I want to show to navigation links like "previous" and "next", to see the next and previous blogpost ordered by date relative to the post the user is reading now. So what I need is the id of the next and the previous record in the mysql-table by date.
How to solve this? Is there any way to solve this in SQL, or do I have to get all records with php and then do some checks to determine if this is the last or next one?
Just a note: I don't want to fetch the last and next posts by id, but by date to get the id of them.
Any help would be appreciated.
Thanks.
To get the newest record older than a certain date:
SELECT id
FROM yourtable
WHERE date < '2010-08-15 14:07:12'
ORDER BY date DESC
LIMIT 1
Or the oldest record newer than a certain date:
SELECT id
FROM yourtable
WHERE date > '2010-08-15 14:07:12'
ORDER BY date
LIMIT 1
Make sure that the date column is indexed.
This works fine if date is unique, but if you have two records with exactly the same date and use next repeatedly this could skip over one of the records. To solve this you could use a tie-breaker column such that (date, tie-breaker) is always unique. You could for example use the primary key as a tie-breaker.
See my answer to this question to see how to do this:
Forward Back Records in MySQL with the same DATA in the primary
the next id:
SELECT TOP 1 id FROM blogposts WHERE blogdate > $given_date_of_actual_blogpost$ ORDER BY blogdate
the previous id:
SELECT TOP 1 id FROM blogposts WHERE blogdate < $given_date_of_actual_blogpost$ ORDER BY blogdate DESC

Categories