Setting up a MySQL table to track user link clicks - php

This is a followup to a question I posted a few days ago.
basically, I have a site with six links. In order to access the site, users must log in using LDAP authentication. When they do this, I grab some of their account credentials (username, firstname, lastname), and store it in a PHP $_SESSION variable.
That works; the user can log in, and the session data is being stored successfully.
Now, I want to set up a way to track which links have been clicked by what users. Basically just store a time stamp in the database of when they clicked the link. I want to be able to see who has (or has not) clicked each link, and when.
Can I do this in a single table / would that be a bad idea? I was thinking setting up the table like this:
TABLE (each bullet indicative of a column)
auto-incrementing ID
user account name: abc1234
user account first name: John
link 1: Last Accessed 5/2/2012 at 4:15PM
link 2: NULL
link 3: NULL
link 4: Last Accessed 5/1/2012 at 2:20PM
link 5: NULL
link 6: NULL
basically the above would say that "John" had only clicked the first and 4th links. The rest are null because he has never accessed them. If he were to click #1 again, it would overwrite with the more recent date/time.
Can I do this in a single table? or will that create complications? I feel like the thing I will have the hardest time with is checking to see if the user is already in the database before adding the info (ie so that if John logs in a second time, a whole new row isn't created for him)
Thanks for any help!

That would be a bad idea. What if you wanted to have a seventh link? What if the user format would change?
This solution requires 3 tables:
Users - contains user data (And a user ID).
Links - contains link data (And a link ID).
Clicks - many-to-many relationship between users and links.
That third table would look like this:
user_id | link_id | timestamp
-----------------------------
1 | 2 | ...
2 | 2 | ...
1 | 3 | ...
............

why not just have
increment_ID
Account_ID
Link_URL
Timestamp
Then just insert a new record for each click. You also don't need to manage links since you'll store the entire URL path

Related

Query and Display referrer details

I have a website built with PHP and mysqli and now I am building administration panel for this website. I am facing some difficulties for querying and displaying referral data I do not have any idea how to do it.
I have a table called user_registration and the fields include, user_name, email, password, referrer. Whenever any of the registered member is referring others the referrer username will be saved in the field "referrer".
Now what I want is to fetch only the rows of the members who has referrals (means referred by my registered members) and also want to count how many referrals a member have and echo it.
For example: I have 20 registered members and from it 5 members have some referrals so I want to query and echo those member's username who has referrals and also count how many referrals they have:
Member's Username Total Referrals
user7 8
user6 6
user1 5
user9 3
user5 2
My solution would be. Make a new column in your user table like "totalreferrals". In this way you can easily keep track of the amount of people they have referred. You could also make a new table "referral". In here you would save the referrals name, the new persons name and a timestamp or something. Now it is even possible to make queries for different periods.
I think that you need to rethink about your database setup, instead of trying to make way to complicated queries, to make your database work.
I am just giving an idea in short which may help you to complete your project -
Suppose your site URL is http://yoursite.com.
1) Whenever a user is registered, you can generate a random key for that user and save it in the database for that particular user. e.g. user1 => abc123
2) Now, you can tell your user (may be on a page after their successful registration) that his/her referrer id is http://yoursite.com/?ref_id=abc123 (by appending it as a new parameter)
or if your register page is http://yoursite.com/register then http://yoursite.com/register/?ref_id=abc123
3) Now, they can share this link to their friends, colleague etc to whomever they want.
4) Now, suppose if a person (may be his friend to whom the user1 referred) clicks on the above link. He will land on your site with the parameter 'ref_id' appended.
5) Just using $_REQUEST['ref_id'] or $_GET['ref_id'], capture its value and store it in a SESSION variable. This you can do on the main page of your site e.g. index.php
6) Now, if that user does the registration, you can make an entry in the database that he has been referred once by the user who has referrer id abc123 i.e. user1.
7) So, you can add count = 1 for user1. If more people come with the same value for the 'ref_id' parameter, you can keep on increment the count.
8) If no such parameter is exists when user lands on your site, then that means he has not referred by anyone. So, that means he is the first kind of user i.e. user in point no. 1).
9) You may also need to take care of some validation part at some places in this.
EDIT:
SELECT user_name, referrer FROM user_registration WHERE referrer > 0;
Assuming that you have a proper insert query ready which gives you the result as you shown the table in your question.

SQL boolean relationship

I have a table dislikes which contains two columns, idone and idtwo.
These are unique ids' from users, for example:
| idone | idtwo |
-----------------
| 5 | 4 |
This means that user with id=5 does not like user with id=4. What I have in PHP is an array containing the ids' of all the users that the current user has selected as not liking them.
So say dislikes={1,2,3}, this means that the current user does not like user 1,2, or 3. There is an unknown number of users in the database.
So if user 1 chooses to dislike user 2 and user 3 (this is done via HTML dropdown), I pass dislike={2,3} to a PHP page which processes this data.
I want the PHP page to then add entries (1,2) and (1,3). Here is the first problem, how can I make sure only to add unique entries?
Also say that user 1 changes the fact that he dislikes user 2. Then I pass dislike={3} to the php page and must somehow remove all entries (1,!3), i.e. all entries in which user 1 dislikes anyone except user 3. How can I achieve this? Or is there a better way?
Since you're using MySQL the easiest thing is probably to use REPLACE INTO instead of INSERT with a primary key or unique index on the pair of columns (idone, idtwo).
Alternatively, on update, you can run a transaction that does any one of:
Remove existing rows for this user, add all rows, commit
Select existing rows, remove the rows from your local set that you would duplicate, add only new rows, commit

Mysql foreign key constraint, update on delete (assign all linked to another)

I might be approaching the problem from the wrong point of view so please correct me if my technique is wrong.
I'm creating guest users on a website with php. When someone visits the website, a guest user is automatically created. But if that person logs into a "normal" account (non guest) then whatever that person did in the guest account is transferred to the new account.
Example, someone visits a website without authenticating, add products from the shop in his cart and then logs in. I will need to transfer the cart items from the old user (guest) to the new user.
But it would be too time consuming (and possibly too resource hungry) to find every item in every table that is linked to the guest user account and then change them all. Right?
But I've got constraints! Yay! If I update the guest user id, all the constraints change. Fabulous! But what if I need to assign them to another user id? How would I do that?
Any help is greatly appreciated.
I am using session array to manage it, previously i was doing through database table but it was too tedious.
When user add any product to cart if he is logged in then insert in order tables and if not then add in session array. Now when guest login into system then check session array and if it is not null then add all entries in user order tables.
You can't do exactly what you're suggesting because the user row (for the logged in user) presumably already exists. The only option would be to go through each table and update the UserID there, like you suggest. The feasability of this depends on what they can do as a guest user. If it's only one or two tables, just do it this way.
But, every problem can always be solved by another layer of abstraction, right? Put another single table (I'll call it "pseudousers") in between the real users table and everything else. Link everything else to this new table, and use the "psuedousers" to link up to the users table. When the guest user logs in, just change the UserID in the pseudousers table and you're done.
What I mean is:
+---------+ +-----------+ +-------+
| Users |----|Pseudousers|----| Carts |
+---------+ +-----------+ +-------+
|
| +-------+
|------------| ... |
+-------+
When you create a guest user, you create a new row in Users and Pseudousers. When they log in, update the UserID in Pseudousers to point to that user, and then you can safely delete the guest user row in Users (it's no longer in use).
Hopefully someone can come up with a better name than "Pseudousers" though.

Friends table for a social network website

Now i am working on a social network website and i already built the friends table for this website but i need some suggestion before i moved forward.
I have a user table where user_id is the primary field.
So for friends i made a friends table with fields like
friend1,friend2,is_active
what i do actually when user1 send a friend request to user2 then at that moment i insert the two rows into the friends table like
1- friend1->user1,friend2->user2,inactive
2- friend1->user2,friend2->user1,inactive
So when somebody accept the friend request at that moment i made the both rows as active.
I made this two entries as i want whenever one user block another then easily made that corresponding row belongs to that user will be inactive.
And if a user remove the user then at that time i delete the both entries.
So please i need some suggestion regarding this please help me out to solve this asap.
I need to know is there any other way which will be more optimized than this and giving proper result.
I think that
Friends_table
with
User_id1, User_id2 and Rleationship_id
is easier, index on both first and second column.
relationship id will be 1 - id1 request, 2- id2 request, 3 - friends, 4- id1 blocked, 5 - id2 blocked...
just an idea.

Preserving old data changed by user

I have a users table that has the following fields: userid, phone, and address. Since this is user data, I'm letting the user change them whenever he wants. Problem is I'd like to keep track of those changes and preserve the old data too. Here's some of the ideas I considered:
appending the new data to the old data and using a separator like a pipe. When retrieving the field, I would check for the existence of that separator and if exists, get the chars after it as the new data. (feels cumbersome and doesn't feel right)
setting up a different changes table with the following fields: userid, fieldname, fieldcontent. When/if a user changes data (any data), I would log the event in this separate table under the user's userid, and the name/id of the field and the old content of the field, then I can now overwrite his old data in users with the new. If I want to find all changes made by this user, I would search the changes table by his userid. Problem with this is that I'm mixing all data changes (of all fields) into one table and so the fieldcontent field in changes has to be text to accommodate the varying field types. This still seems better than the first idea, but still not sure if I'm doing the right thing.
What other ideas are there or known best practices to keep old data?
Thanks in advance
Whatever you do don't do the first one.
The changes table is a better approach. It's also called an audit or history table. I wouldn't do a history of key-value pairs however. Instead do a history per relevant table. You can do this in application code or via database triggers. Basically whenever an insert, update or delete happens you record which happened and what data was changed.
Table user:
id
username
email address
phone
address
Table user_history:
id
change_type (I, U or D for insert, update or delete)
user_id (FK user.id)
email address
phone
address
date/time of change
optionally, also store who changed the record
A very simple way that we have used to track such changes is this:
users_history`
userid
changenumber smallint not null
changedate datetime not null
changeaddr varchar(32) not null
phone NULL,
address NULL
primary key on (userid, linenumber)
Each time you INSERT or UPDATE a record in the users table, simply INSERT a new record in the users_history table. changenumber starts at 1 and increments from there. changedate and changeaddr could be used to track when and where.
If a field value has not changed, feel free to put NULL in the respective users_history table field.
At the end of the day, your app does not need to change or store bulky history data in the users table, but you have all if it at your fingertips.
Edit:
This does preserve the old data. See the following example where the user started with a given address and phone, and then 4 days later updated the address, and 5 days later updated the phone. You have everything.
Current users record:
100 | 234-567-8901 | 123 Sesame Street
Sample History Table
100 | 1 | 2009-10-01 12:00 | 123-456-7890 | 555 Johnson Street
100 | 2 | 2009-10-05 13:00 | NULL | 123 Sesame Street
100 | 3 | 2009-10-10 15:00 | 234-567-8901 | NULL
The simplest way to implement this will be have another table just for history purpose, a snapshot. You don't need to mirror all the fields, just
change_id // row id (just for easy management later on if you need to delete specific row, otherwise its not really necessary)
user_id // Original user id
change_time // time of change
data // serialized data before change.

Categories