Multiple entries under the same user id - php

I am building a webapp on a pet shop. A user may have multiple visits to the pet shop. So the unique about the data is phone number of the user. But every time the same user visits the pet shop the data must be entered under the same user. I am having trouble coming up with a solution.

Create two table one for users and another for visits as below
Table structure for table users
CREATE TABLE `users` (
`id` int(11) NOT NULL,
`mobile_number` varchar(15) NOT NULL,
`created_at` datetime NOT NULL,
`modified_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- Table structure for table visits
CREATE TABLE `visits` (
`id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`created_at` datetime NOT NULL,
`modified_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

you can follow the following method
create users table where mobile no. or a unique userId will be present.
create Visitors table where you can store rest of the data of that user

Related

How can mysql not handle two insert request called at same time?

I have created rest api in php (slim framework with mysql as database) for keeping records of multiple android app's users, So when our app is opened by user it calls register api and sends parameters to trigger insert or update operation
Here's structure for users table
CREATE TABLE IF NOT EXISTS `users` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`app_code` varchar(255) NOT NULL,
`api_key` varchar(255) NOT NULL,
`device_id` varchar(100) NOT NULL,
`device_token` varchar(255) NOT NULL,
`device_model` varchar(50) NOT NULL,
`device_name` varchar(50) NOT NULL,
`device_memory` varchar(50) NOT NULL,
`device_os` varchar(100) NOT NULL,
`last_access` int(14) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=2130346 ;
before inserting record api checks if user already present in users table using two parameters app_code & device_id
If its present then just update user's last_access(and device_token if its different than previous one) fields and return flag:2(user already exist)
update query looks like this
UPDATE users SET device_token='asadiwp0qidkqwdpkpka2',last_access='1498912512' WHERE id = '2132079'
and if user is not present return flag:1(new user).
mysql insert query looks like this
"INSERT INTO users(app_code, api_key, device_id, device_token,device_model, device_name, device_memory, device_os, last_access) values('YEVZ6I', 'b005e8a2babe0163a8eb4bfb2fe87b78', '66BBEG13B5F2G3EG', 'asadiwp0qidkqwdpkpka','Moto E3', 'Motorola E3 Power', '2GB', 'M', '1498912256')"
Where mendatory parameters are "app_code, api_key, device_id, device_token".
Now problem is that currently i am getting register request two times from same device at the same time same second, So mysql insert statement is being called twice at the same time and same user record is inserted twice as a new user, it duplicates record.

how to get users information stored in several tables and show in his profile, is it posible with single query?

i have developed an online auction system in which users can sale or buy goods, my problem is with retrieving auctions relative information that are in two separate tables one contains information such as (auction_id,owner,title,description,base_price,..) and the other contains information about requests for each auction: (bid_id,auction_id,bidder,price,date), each user may post several auctions or not, i want to show the highest price and the bidder(some one who gives such price) for that price and number of requests additional to information stored in auction table for each auction
but when i join to table, if there is no request for auction so the result will be zero and you will see the message: there is no information to show but the user has just posted a new auction, what should i do?! should i check if there is a request for each auction and if yes then get these information?! dosent in code duplication? in this way i should connect to db twice in a single request for profile page
here is my tables and current query:
create table `auction`(
`auction_id` INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
`owner` VARCHAR(32) NOT NULL,
`group_id` TINYINT UNSIGNED NOT NULL ,
`title` VARCHAR(100) NOT NULL,
`sale_type` VARCHAR(1) NOT NULL,
`base_price` INT NOT NULL,
`min_increase` INT NULL,
`photo` VARCHAR(200) NULL,
`description` VARCHAR(500) NOT NULL,
`start_date` DATETIME NOT NULL,
`termination_date` DATETIME NULL,
`sold` VARCHAR(1) NOT NULL DEFAULT 0,
`purchaser` VARCHAR(32) NULL,
`deleted` VARCHAR(1) NOT NULL DEFAULT 0,
FOREIGN KEY(owner) REFERENCES users(user_name) on delete cascade on update cascade,
FOREIGN KEY(purchaser) REFERENCES users(user_name) on delete cascade on update cascade,
FOREIGN KEY(group_id) REFERENCES commodity_groups(group_id) on delete cascade on update cascade)
ENGINE=InnoDB default charset=utf8;
create table `bid`(
`bid_id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
`auction_id` INT UNSIGNED NOT NULL,
`bidder` VARCHAR(32) NOT NULL,
`price` INT NOT NULL,
`date` DATETIME NOT NULL,
`deleted` VARCHAR(1) NOT NULL DEFAULT 0,
FOREIGN KEY(auction_id) REFERENCES auction(auction_id) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY(bidder) REFERENCES users(user_name) ON DELETE CASCADE ON UPDATE CASCADE)
ENGINE=InnoDB default charset=utf8;
and here is my query i use prepared statements:
SELECT `auction`.`auction_id` , `title` , `base_price` , `min_increase` , `photo` , `description` , `start_date` , `termination_date` , `max_bidder` , `bids_count` , `max_bid`
FROM `auction` , (
SELECT `bid`.`auction_id` , `bidder` AS max_bidder, `bids_count` , `max_bid`
FROM `bid` , (
SELECT `auction_id` , count( bid_id ) AS bids_count, max( price ) AS max_bid
FROM `bid`
WHERE `auction_id`
IN (
SELECT `auction_id`
FROM `auction`
WHERE `owner` = ?
)
GROUP BY (
auction_id
)
) AS temp
WHERE `bid`.`auction_id` = `temp`.`auction_id`
AND `price` = `max_bid`
) AS temp2
WHERE `auction`.`auction_id` = `temp2`.`auction_id`
it is clear that if there is no request for auction, the result will be zero and no auction will be shown to user in his profile, however he or she has just post a new auction, i will thank if any body could help me
What you have is more of a database design problem and a future scalability problem than an actual problem. You know you can make two requests if you want to.
If you care about scaling things up, you're going to have to think very carefully about what user information you want to replicate across multiple servers, and how you're going to synchronize that. The basic answer is: Yes, you use joins to include the user information you want. But a more complicated answer is that you might want to create mini tables with just a little bit of user information (duplicated and synchronized) that you can join very quickly, which no user would ever write to -- in other words they are written only by the master table either through a slave setup or with some cron job.
A lot depends on how large you expect your site to be and how many people might be writing to the users table. It's assumed that many people will be writing to the auction table, so ideally you don't want ANY foreign key dependencies on that table or you will get deadlocks. It should be an ISAM or Federated table, probably.

how to maintain records current as well as previous in mysql

Hi any one please help i have a contact table in which i can Insert,Delete,Modify database using PHP web pages....but only current changes will be updated to database. what i want is how i can maintain history of database...
Is there any tutorial for this using (PHP/MYSQL).
I tried creating version of MySQL table for patient... how to proceed further.
CREATE TABLE IF NOT EXISTS `contact` (
`name` varchar(30) NOT NULL,
`phone` varchar(12) NOT NULL,
`mobile` varchar(12) NOT NULL,
`email` varchar(30) NOT NULL,
`address` text NOT NULL,
`conid` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`conid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ; # MySQL returned an empty result set (i.e. zero rows).
CREATE TABLE IF NOT EXISTS `contactversion` (
`name` varchar(30) NOT NULL,
`phone` varchar(12) NOT NULL,
`mobile` varchar(12) NOT NULL,
`email` varchar(30) NOT NULL,
`address` text NOT NULL,
`conid` int(11) NOT NULL,
`revision_id` int(11) AUTO_INCREMENT,
type ENUM('INSERT', 'UPDATE', 'DELETE') NOT NULL,
`change_time` DEFAULT current_timestamp,
PRIMARY KEY (`revision_id`)
);
what to do next....
When running the queries to contact, just simply run this right before to take the current contact and copy it in your revision table...
"INSERT INTO
contactversion (name,phone,mobile,email,address,conid,type)
SELECT
name,phone,mobile,email,address,conid,'".$type."' as type
FROM contact
WHERE conid='".$conid."'"
Both tables will require to be identical, with contactversion having type and change_time as additionnal last columns.
It is obvious that this query should be ran before UPDATE and DELETE of the contact table, but after an INSERT. If you are updating multiple contacts with another where clause than the conid, you'll want to consider building the where statement in a variable to use it inside the INSERT's SELECT and the UPDATE/DELETE
While creating contactversions table make sure conid should not be primary key and auto incremented. I hope that is causing the problem.

Different user roles for logging in with PHP and Mysql

I have a project coming up for doing Admin functions so my question is this. I will try and be clear as possible.
I will have one SUPER-USER who updates all information for other regular-users/people(being our clients).
The clients/regular-users when they log in will only see their info and download files uploaded by SUPER-USER and not see for regular-users.
So if you are Client:#01 you will see the dashboard (welcome page) and your info. Can anyone suggest possible database designs for this.
How to use left/right sql-joins between the user and files table?
UPDATE
I have a users table as well as a company table that the user belongs to. So essentially I want something like this::
$sql = select everything in the users table where the username and pass = to the given form, then left or right join that username to the company that he belong to.
Then they will see their information. if logged in successfully. Because user #01 belongs to company #03 /#01 etc...
USER TABLE looks so
`id` int(11) NOT NULL AUTO_INCREMENT,
`fname` varchar(50) NOT NULL,
'lname` varchar(100) NOT NULL,
`username` varchar(50) ,
`password` varchar(100) ,
`company` varchar(50) // the company name that ther user belongs to
PRIMARY KEY (`id`)
COMPANY table
'id' int(11) not null auto_increment,
'user_id' int(11) //This is to tie the users to this table
'description' varchar(text),
'filename' varchar(25) not null,
'mimetype' varchar (25) not null
PRIMARY KEY ('id')
Well, it depends on how simple or complex you want to go. with something like this I usually will keep it relatively simple and have a main user database (for all users) example:
CREATE TABLE IF NOT EXISTS `user` (
`user_id` int(255) NOT NULL AUTO_INCREMENT,
`user_name` varchar(50) NOT NULL,
`user_pass` varchar(100) NOT NULL,
`user_permissions` tinyint(1) NOT NULL DEFAULT '0',
`active` tinyint(1) NOT NULL DEFAULT '1',
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=MYISAM;
Then I would have possible a second table of permissions depending on how many permissions I was going to have. If all you are going to have is users and super users then you could probably just assign users a value of 0 and then super user a value of 1.
Then in your PHP script it would treat the users different based on their "user_permissions" value.
Now if you are intending to have lots of different levels of permissions then I would definitely create at least one more table to define permissions example:
CREATE TABLE IF NOT EXISTS `permission` (
`permission_id` int(255) NOT NULL AUTO_INCREMENT,
`permission_name` varchar(100) NOT NULL,
`permission_value` int(10) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MYISAM;
Then in the permissions table you could assign all sorts of different permissions... read, write, publish, admin, regular user, super user etc.
This is just a very simple starting point. hope that helps.

Timeline from 2 related tables

Let's say I have a screenshots table and a replies table. So: every screenshot can have multiple replies (one-to-many). Now, I want to create a combined timeline of the two, but in reality, they're pretty unrelated (in structure).
How can I select data from both tables, ordering by their publish time, descending; when for example, I can have a post, a few comments, then another post; because that would be how the timeline happened?
Normally selecting from both combines the tables; but I don't want that to happen. On that subject, I also need the tables to be distinguishable. Here's the structure for the tables...
--
-- Table structure for table `screenshots`
--
CREATE TABLE IF NOT EXISTS `screenshots` (
`id` int(11) NOT NULL auto_increment,
`user` int(11) NOT NULL,
`description` text NOT NULL,
`time` timestamp NOT NULL default CURRENT_TIMESTAMP,
`ext` varchar(4) NOT NULL default 'png',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=14 ;
-- --------------------------------------------------------
--
-- Table structure for table `screenshot_replies`
--
CREATE TABLE IF NOT EXISTS `screenshot_replies` (
`id` int(11) NOT NULL auto_increment,
`user` int(11) NOT NULL,
`parent` int(11) NOT NULL,
`time` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
`text` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=27 ;
Note: I realize this may be a duplicate of this question but I didn't find the solution there working for me.
Thanks in advance! :)
You should use UNION in this case:
(SELECT id, time, 'screenshots' as tableName FROM screenshots)
UNION
(SELECT id, time, 'replies' as tableName FROM screenshot_replies)
ORDER BY time ASC
You can get the tablename of a field by using the mysql_tablename function in php
You can indicate the tablename as a column in the result set
Whenever I come across a problem like this, where you're finding it impossible to do something because you can't built a query which will extract the data, I have to start wondering do you have the right data model?
Start with what data you want to extract, and then build a model which allows that, not the reverse, and you'll find it much easiler in the long term, and also probably faster performance and quite often better flexibility.
Looking at those tables, I'd have to ask why have two of them? What's wrong with:
CREATE TABLE IF NOT EXISTS `screenshots` (
`id` int(11) NOT NULL auto_increment,
`user` int(11) NOT NULL,
`description` text NOT NULL,
`time` timestamp NOT NULL default CURRENT_TIMESTAMP,
`ext` varchar(4) default 'png',
`parent` int(11),
`text` text,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
That would allow you to do what you want, easily telling if it's a screen shot (if ext is set), a reply (if parent is set) or ... since the model now allows it ... a screenshot which is a reply!!!

Categories