Unique IP Counter with Laravel and MySQL - php

I'm trying to make a simple Unique IP counter for gallery page views.
The idea I have is to keep the views records separate from the image records in 2 tables.
Database Tables
gallery
Holds Image: id, name, category, views columns
unique_ips
Holds a visitor ip for the Image name viewed
This example screenshot shows 3 visitors each viewing 3 images. I used free proxy ips.
View Counter
If New IP detected:
Add name+ip to unique_ips.
Increment gallery → name → views +1.
$name = "Image 1";
$ip = getenv('REMOTE_ADDR');
// Increment Views if New IP visitor
// Proceed if name + ip record does not exist in table
if (!DB::table('unique_ips')->where('name', '=', $name)->where('ip', '=', $ip)->exists()) {
// Add Name/IP Record
DB::table('unique_ips')->insert([
['name' => $name, 'ip' => $ip]
]);
// Views +1
DB::table('gallery')
->where('name', $name)
->increment('views', 1);
}
Problem
This view counter works, but all unique ip records are grouped together under 2 columns. It would have to search through all records to find a match, which might slow down with thousands of ip's.
Other Ideas
Use only the gallery table and add a
unique_ips column, which would hold an array of ip's. But how many
could it hold if string/text is limited to a number of characters?
Each name could have it's own Column containing ip's. But then I'd have thousands of Columns.
I could store ip's in name text files instead of in the database.
Is there a better way to design this?

At first it would be faster to use gallery_id instead of name with relationship.
And if you don't want to slow down process on clients side, you can make queued event-listener, that will handle checking and adding record to database.
Check out following link about Queued event listeners

Related

PHP SQL: Dynamically Creating and Deleting Columns in Database

I'm creating a carousel/image slider plugin for WordPress and I've hit a wall. There's going to be an indefinite amount of user input and I need to know how to handle this.
I currently have six static inputs: transition_time, loop_carousel, stop_on_hover, reverse_order, navigation_arrows, and show_pagination and the variable amount of info will come from the images the user wants to use. So this could be anywhere from zero to infinite.
I want to be able to create/delete X amount of columns in the DB.
So starting out there will be zero images, meaning six columns. If a user adds two images I want to have eight columns, two created. If the user deletes them then I want to go back to my original six.
I'm guessing this is possible but how and is this a good idea or should I just have a set amount of images?
You Are Doing It Wrong™.
Changing a table definition should be an exceptional event.
Use two tables, one to model the Carousel, one to store image information, then link them.
Table Carousel:
id
[more fields here]
Table Image:
id
carousel_id (reference to the containing Carrousel)
[more fields]

Php song like counter

This is more of a general question on how I would approach this.
I have a audio player. No data about songs is stored in the database. I would like to use database for counting likes for each song. My question is how would I organize this?
1.
If I list all my songs in database beforehand and add a column for like, then where would I keep track of user ip address? (not sure if there is a better way than using ip address?) So I prevent of same user voting multiple times.
2.
Every time user likes a song I would store {song title, like count, user ip} (maybe something else) in database. But then I would end up with multiple rows of same song with different user ip addresses, so how would I keep track of likes for every song in this case?
No data about songs is stored in the database
If you want to store data about each song, you should probably add a table for the songs.
not sure if there is a better way than using ip address?
If you have a table with user IDs, use that because the same user can log on from different IPs, and different users can log on from the same IP.
As for database structure, what you proposed is probably the right answer. Once you have a table set up for songs, have a dedicated column just for likes to you can retrieve it easily.
If you want to know which user liked which song (and when) then you need to make a new table like you suggested in your second point. This is called a junction-table, and is used for many:many relationships (m:m). There is no unique id. It joins two tables with many keys (users:songs) and stores any relationship between the two.
Every time user likes a song I would store {song title, like count, user ip} (maybe something else) in database. But then I would end up with multiple rows of same song with different user ip addresses, so how would I keep track of likes for every song in this case?
Even if you end up with many rows of the same song, they are all unique since each has a different user liking it (and vice-versa, you can get all the songs a specific user liked). You wouldn't need to store a like-count in here, since you can just count the number of records in the database. {song title, user id, datestamp} would be fine.

Count Page views each separate

I want to make a count views system ,I have one for the site count views , but that's in general for the main site , dunno how to do it individually but it seems like this one will not be easy !
So I will show you my old system and in what way does the new should work, so I got this Running so far
$guest_ip = $_SERVER['REMOTE_ADDR'];
$visits = mysql_query("INSERT INTO visitors(ip) VALUES('".$guest_ip."')");
$visitoronsite = mysql_query("SELECT * FROM visitors");
$onlinevisits = mysql_num_rows($visitoronsite);
?>
Visitors: <?PHP echo $onlinevisits; ?>
Of Course It is great to keep track of who and how many , but As my site is with videos and each video has link with php ID which is something like site/index.php?id=8 and that page , What I want to do is to put a counter on that page saying that many people watched using this link and I already have a teory but Has Few Issues
So I created a table called pageviews with 2 columns one ip and the other one page , now here's my question , I cannot use unique because I want to show that that IP has also watched this link but it wount insert it because it will be unique so what do I do to keep one ip unique as for that page only?
On your pageviews table, you should create a unique index based on two columns (ip and video or link id).
You add a unique on your table like this:
ALTER TABLE `pageviews` ADD UNIQUE INDEX `ip_video_unique` (`ip`, `video_id`);
Than you would be able to store unique video views per IP.
On the page, you can get the count of how many IPs have viewed that video by doing a query such as:
SELECT * FROM `pageviews` WHERE video_id = x
where x in this query is the id of the video. In case of site/index.php?id=8 it would be 8.
Its also better if you separate the IPs on a separate table where you store visitors with a unique id and their respective IP and on pageviews table you reference the unique visitor id instead of the IP. Later on, this would allow you to count video views on a table and something else's views on another table but have the visitors(and their IPs) aggregated on a single table.

Storing multiple values in one field (IDs of images liked by user)

I have a site that allows users to vote on images. Each image has a unique id number. For voting restriction purposes, I'd like to keep track of what each user has liked. How would I go about setting up a row in the USERS table that holds all the different id numbers of the images liked by this particular user?
You should not have all this information in your users table. I persume that you have one table with all your images and one with all your users. Create a table called "user_image_like" for example. And store "user_id" and "image_id". When the user presses like on the image your script will add "user_id" and "image_id" to the table.
When you wan't to see all images liked by a user you can easly get this by a simple sql query.
If you want to store such information in one table and in one field, I have the answer for you.
You can use either ways:
Store the IDs in a CSV format. When you fetch these values you can deal with them as you deal with a CSV file.
Store the IDs in an XML format. Then, you deal with it as any other XML file.
Regards,
This is a Many to Many relation. i.e. one user can like multiple Images and one image can be liked by multiple users.
According to normalization standards you should use these relation in separate table with user_id and image_id. whenever user like an image add a row to this table.
If you still want to store it in single table (users) then store ids in CSV format. be sure to store only unique image ids for each row.
Check this article
http://www.tonymarston.net/php-mysql/many-to-many.html

php/mysql classifieds view counter by date

Im building a classifieds website of adverts where I want to store a count of the number of views of each advert which I want to be able to display in a graph at a later date by day and month etc.. for each user and each of their adverts. Im just struggling with deciding how best to implement the mysql database to store potentially a large amount of data for each advert.
I am going to create a table for the page views as follows which would store a record for each view for each advert, for example if advert (id 1) has 200 views the table will store 200 records:
Advert_id (unique id of advert)
date_time (date and time of view)
ip_address ( unique ip address of person viewing advert)
page_referrer (url of referrer page)
As mentioned I am going to create the functionality for each member of the site to view a graph for the view statistics for each of their adverts so they can see how many total views each of their adverts have had, and also how many views their advert has had each day (between 2 given dates) and also how many views per month each advert has had. I'll do this by grouping by the date_time field.
If my site grows quite large and for example has 40,000 adverts and each advert has on average 3,000 page views, that would mean the table has 120 Million records. Is this too large ? and would the mysql queries to produce the graphs be very slow?
Do you think the table and method above is the best way to store these advert view statistics or is there a better way to do this?
Unless you really need to store all that data it would probably be better to just increment the count when the advert is viewed. So you just have one row for each advert (or even a column in the row for the advert).
Another option is to save this into a text file and then process it offline but it's generally better to process data as you get it and incorporate that into your applications process.
If you really need to save all of that data then rotating the log table weekly maybe (after processing it) would reduce the overhead of storing all of that information indefinitely.
I was working with website with 50.000 unique visitors per day, and i had same table as you.
Table was growthing ~200-500 MB/day, but i was able to clean table every day.
Best option is make second table, count visitors every day, add result to 2nd table, and flush 1st table.
first table example:
advert_id
date & time
ip address
page referrer
second table example (for graph):
advert_id
date
visitors
unique visitors
Example SQL query to count unqiue visitors:
SELECT
advert_id,
Count(DISTINCT ip_address),
SUBSTRING(Date,1,10) as Date
FROM
adverts
GROUP BY
advert_id,
Date
Problem is not even perfomance (MySQL ISAM Engine is quite smart and fast), problem is storage such big data.
90% statistics tools (even google analytics or webalyzer) is making graphs only once per day, not in real-time.
And quite good idea is store IP as INT using function ip2long()

Categories