I am making a basic CMS system which allows for page edits by registered users.
I wish to store a list of users who have submitted some page content to each a specific page. In my database table for pages, I have a column called contributed, and in there I want to have all the user id’s of each user who contributed to each page, separated with a common. Looking something like this ...
Page Name | Author | Comments | Contributed
---------------------------------------------------------------
Home | 1 | 0 |1, 2, 3, 4
About | 1 | 0 |1, 3, 4, 7, 9
Contact | 2 | 0 |2, 4
Download | 8 | 0 |8
Using MySql, how can I write an update query that appends another user id to this column when a user makes a contribution instead of updating the entire row, removing the ids of those who have previously contributed?
For this, it would be best to create some sort of history table. Example:
**page_history**
id
page_id //ID of the page
user_id //ID of the user making the change
date //Date and time of the change
from //The old content
to //The changed content
Then you'd insert a new row into page_history every time a user edits a page. Note: You should read up on the concept of Database Normalization.
I might end up doing this on one level up - without any knowledge of size of your CMS:
CREATE TABLE test(pageid INT, contributed VARCHAR(1024));
INSERT INTO test(pageid, contributed) VALUES (1, "kala");
UPDATE test SET contributed = CONCAT((SELECT contributed FROM (SELECT * FROM test) as a WHERE pageid = 1),',','new_user_name') WHERE pageid = 1;
For SELECT * FROM test there is good description at
You can't specify target table for update in FROM clause
Related
let me say that I have a table in my phpmyadmin that looks like this:
id | name
1 | John
2 | Dave
5 | Tiffany
As U can see by id - i've deleted 2 records between 'Dave' and 'Tiffany'.
My question:
Is there a way to 'reset' or repopulate the id so that the 'Tiffany' record would have id=3 and so on ?
The only way to start counting id again I've found is a 'TRUNCATE' but it deletes all my records which I dont want
I do this sometimes when I create a new table and want to get 'clean' ids. If there is no reference to / connection with other table, you can do:
SET #var:=0;
UPDATE `table` SET `id`=(#var:=#var+1);
ALTER TABLE `table` AUTO_INCREMENT = 1;
Do not do this for ids already used in other tables!
My question is a little bit confusing, i understand that my question may sound similar to other questions here. I have a form that is numbered and increase by 1 depending what is the last value in the database.
For example in the database:
ID | ApplicationNumber
1 | 1
2 | 2
So if the user will generate another form it will display as: Application Number 3. And it will be save in the database as application number 3. But what if there are two users who will submit the form at the same time? Both are filling up the form numbered as: Application Number 3 and before my INSERT INTOi perform the query of looking the last value in the database so i can +1 to the value of Application Number value before submitting it to the database. I let two users submit the form at the same time and what i received in the database is like this:
ID | ApplicationNumber
1 | 1
2 | 2
3 | 3
4 | 3
My query for getting the last value and BEFORE inserting something to the database:
$query = mysqli_query($con,"SELECT table1.ApplicationNumber FROM table1 INNER JOIN table2 ON table1.AdminID = table2.AdminID AND table2.Username = '$user' ORDER BY table1.ApplicationNumber DESC LIMIT 1");
while($row = mysqli_fetch_array($query)) {
$aNumber = $row['ApplicationNumber'] + 1;
}
If I'm getting you right there are few straightforward options from the database point of view:
Use autoincrement for the ApplicationNumber column in mysql
Create Unique-key constraint for this column and handle this error somehow
Also you can just LOCK the table before select, so you have exclusive access to the data. Beware, you should especially care for unlock and understand that other users won't be able to use this table, while lock in effect.
I want to create an up vote and down vote system for my website where a unique user can vote up/down for one post and next time he only allow to opposite to get off from database and after that he again can up or down vote.
In this case I have:
users table :
id
name
debates table :
id
post
upvotes table:
id
user_id
debate_id
and similarly downvote table:
id
user_id
debate_id
Is that a good way to manage and track up vote and down vote concept?
I think, you can use a single table to track the votes and the structure could be something like this
Table : votes
id | user_id | debate_id | vote
Here, vote field could be tinyInt with defauld null.
And, in vote field, you just keep two different values depending on the vote type, for example, if a user up votes then insert a value of 1 in the vote field and for down vote, insert the value of 0. So, your table may look something like this
id | user_id | debate_id| vote
1 | 10 | 4 | 1 <-- up
2 | 11 | 4 | 0 <-- down
3 | 12 | 4 | 1 <-- up
In this case, two users with id = 10 and id = 12 up voted the post whose debate_id = 4 and another user with user_id = 11 down voted on the same post.
IN this case, you may find out how many up or down votes a post got by counting the vote field's value, for example, you may count for up votes for debate_id = 4 using something like this
$count = Debate::where('debate_id', '=', 4)->where('vote', '=', 1)->count();
Also, you may use something Query Scope, this is just an idea and it's not possible to make an answer which covers everything in this scope. You should start using some basic idea and if you stuck at a certain point, then you may ask specific questions with your code.
Also, I would like to mention that, if you find a user id in the votes table with a certain debate_id then this user has voted on this post and to find out the vote type, just check the vote field 1 or 0.
I would prefer to only have one table containing the votes, this could be done with an extra column such as is_downvote int(1).
It seems that you havn't tried much which is always a negative. For this scenario the Laravel Eloquent Documentation should be plenty to figure this out.
I would of written this as a comment but it's pretty lengthy now.
I am currently developing an article driven site and would like to know the best way to track page hits so I can display something along the lines of "Most Viewed" or "Most Popular Articles". I display my articles through a $_GET on a single PHP page (e.g article.php?id=2). I read somewhere that an INSERT INTO was the way to go and I tried to do:
$page_views = $conn->query("INSERT INTO blog_posts (views) VALUES (views = views+1");
Alas, this did not work.
In summary I want to be able to:
Add 1 to the number of page views on an specific id for each time someone lands on the page (e.g articles.php?id=3) not just articles.php
Thanks in advance.
(Sorry if I haven't made this clear enough. If you want anything clarifying just ask.)
Do you intend to keep a separate table for the counts? If so,
|page_views |
|blog_id|count|
+-------+-----+
| 1 | 12 |
| 2 | 33 |
with blog_id being a primay key with unique enforced
you could use on duplicate key to create a row if it doesn't exist and update the count if it does
("INSERT INTO page_views (blog_id,count) VALUES ($blog_id,1) ON DUPLICATE KEY UPDATE count = count + 1")
Why don't you try with update statement:
"UPDATE blog_posts SET views = views+1 WHERE id = $id"
Your insert statement will add a new row in the database, what probably is not what you want.
Use an update query to increment the counter.
UPDATE blog_posts SET views = views+1 WHERE id = 'SOME NUMBER'
Where your each row in the blog_posts table has a numberic views field and an id.
SQL Fiddle:
http://sqlfiddle.com/#!2/0915b/1
If we look at the stackoverflow website we have votes. But the question is what is the bestway to store who has voted and who has not. Lets also simplify this even more and say that we can only vote Up, and we can only Remove the Up vote.
I was thinking having the table to be in such form
question - Id(INT) | userId(INT) | title(TEXT) | vote(INT) | ratedBy(TEXT)
Thre rest is self explanitory but ratedBy is a Comma Seperated Id values of the Users.
I was thinking to read the ratedBy and compare it with the userId of the current logged in User. If he dosent exist in the ratedBy he can vote Up, otherwise he can remove his vote. Which in turn will remove the value from ratedBy
I think to make another table "vote" is better. The relationship between users and votes is n to n, therefore a new table should be created. It should be something like this:
question id (int) | user id (int) | permanent (bool) | timestamp (datetime)
Permanent field can be used to make votes stay after a given time, as SO does.
Other fields may be added according to desired features.
As each row will take at least 16B, you can have up to 250M rows in the table before the table uses 4GB (fat32 limit if there is one archive per table, which is the case for MyISAM and InnoDB).
Also, as Matthew Scharley points out in a comment, don't load all votes at once into memory (as fetching all the table in a resultset). You can always use LIMIT clause to narrow your query results.
A new table:
Article ID | User ID | Rating
Where Article ID and User ID make up the composite key, and rating would be 1, indicating upvote, -1 for a downvote and 0 for a removed vote (or just remove the row).
I believe your design won't be able to scale for large numbers of voters.
The typical thing to do is to create to tables
Table 1: question - Id(INT) | userId(INT) | title(TEXT)
Table 2: question - ID(INT) | vote(INT) | ratedBy(TEXT)
Then you can count the votes with a query like this:
SELECT t1.question_Id, t1.userId, t1.title, t2.sum(vote)
FROM table1 t1
LEFT JOIN table2 t2 ON t1.question_id = t2.question_id