on duplicate key update results in a high index key - php

so im using ON DUPLICATE KEY UPDATE when logging in - i am using it at every login because im getting the data from an external page and the users can only update their settings there. thats because the lack of an api by the software on that page.
actually im using this query to update their settings. if the account isnt listed in my database, its getting created with their credentials on success.
my problem is, that if the user isnt listed in my database and they are inserted into it, their id (auto increament) is not 1, 2, 3, 4 and so on. its starting at 32, then it goes to 54, after that 185 and so on. the ID raises so fast. is this an issue in my query or is this actually a bug?
http://puu.sh/8iXv7.png
heres my query
mysqli_query($database, " INSERT INTO `benutzer` (`id`, `login`, `vorname`, `nachname`, `gruppen`, `email`, `adresse`, `telefon`, `telefon2`, `telefon3`, `bemerkungen`)
VALUES (NULL, '".$userdata[0]."', '".$userdata[1]."', '".$userdata[2]."', '".implode(";", $gruppen)."', '".$userdata[3]."', '".$userdata[4]."', '".$userdata[5]."', '".$userdata[6]."', '".$userdata[7]."', '".$userdata[8]."')
ON DUPLICATE KEY UPDATE `vorname` = '".$userdata[1]."', `nachname` = '".$userdata[2]."', `gruppen` = '".implode(";", $gruppen)."', `email` = '".$userdata[3]."', `adresse` = '".$userdata[4]."', `telefon` = '".$userdata[5]."', `telefon2` = '".$userdata[6]."', `telefon3` = '".$userdata[7]."', `bemerkungen` = '".$userdata[8]."'") or die(mysql_error());
aand this is the structure of the table
CREATE TABLE IF NOT EXISTS `benutzer` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`login` varchar(32) NOT NULL,
`vorname` text NOT NULL,
`nachname` text NOT NULL,
`gruppen` text NOT NULL,
`email` text NOT NULL,
`adresse` text NOT NULL,
`telefon` text NOT NULL,
`telefon2` text NOT NULL,
`telefon3` text NOT NULL,
`bemerkungen` text NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `login` (`login`),
KEY `login_2` (`login`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=32 ;
thanks in advance

It's expected and documented behavior.
If you don't like it - then don't use the tool on the wrong purpose.
However, I wouldn't call it a problem at all. Id is an abstract identifier and lasts up to four billion, which ought to be enough for everyone

Related

How to allow mutilple page to insert multiple data at the same time (will not clash) in MySQL PHP

I have a online page which will allow user to create an account for them in order to acceess our page.
I worry in some period, there will be a lots of user who create at the same time.
In that case, I worry my database will be clash or conflict.
Can I know is that anyway to prevent that happens?
My table as below:
CREATE TABLE `user` (
`id` int(11) NOT NULL,
`userid` varchar(30) DEFAULT NULL,
`password` varchar(20) DEFAULT NULL,
`name` varchar(40) DEFAULT NULL
)
ALTER TABLE `user`
ADD PRIMARY KEY (`id`);
ADD UNIQUE KEY `userid` (`participant_id`);
ALTER TABLE `user`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=1;
COMMIT;
So my id will be just number and auto increment.
userid wil be unique.
I created the page by using PHP.
And I use following insert command at my page:
do {
$query = "INSERT IGNORE INTO user(userid, password, name) VALUES ('$userid','$password','$name')";
$insert = $conn->query($query);
} while( $insert && ($conn -> affected_rows == 0) );
Are this code can work perfectly to prevent the date conflit?
Another extra question is, how about if I create another extra page which will insert information 'user' table and can I used the same code at the new page?

error on local mysql but not on RDS mysql

I have a mysql insert query which runs on aws RDS(Live env) but throws an error on my local(local env).
on local I'am using mysql V-5.6
$sql = "INSERT INTO `users` (`id`,
`name`,
`email`,
`pass`)
values('','omi','omi#gmail.com','123123')
id is not null and auto_increment.
The error which i get on local is 'Incorrect integer value: '' for column 'id' at row 1'
but when this executed on live env all the data gets inserted into table.
I cant understand what exactly is happening here. please help. thank you.
DDL of users table.
local
CREATE TABLE `users`
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(256) DEFAULT '',
`email` varchar(256) NOT NULL,
`pass` varchar(256) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=25986 DEFAULT CHARSET=utf8;
Live
CREATE TABLE `users` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(254) DEFAULT '',
`email` varchar(256) NOT NULL,
`pass` varchar(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=26046 DEFAULT CHARSET=utf8;
I believe the error is with those quotes (''). When you want to do an insert with an auto_increment field, you have to use null as argument in the auto_increment field position.
See if this works:
$sql = "INSERT INTO `users`
(`id`, `name`, `email`, `pass`)
values(null,'omi','omi#gmail.com','123123');
EDIT 1
Using null doesn't generate any error because internally the DBMS is prepared to receive such an argument. It understands that is its duty to generate the next number of the sequence and if it hasn't any, 0 (of type integer in your case) is inserted first. I know defining "not null" in the DDL of a field and then using "null" in the DML insert statement for that exact field may look confusing, but it's just the right way to use the auto_increment feature.
From the documentation:
If the column is declared NOT NULL, it is also possible to assign NULL to the column to generate sequence numbers.
Also, if using an empty string as argument in an statement doesn't generate any error, it could maybe be because RDS interface has an internal function that converts empty to null. Something like the nullif function in MySQL.
You can't do it like that. Either dont even mention 'id' or give it null value.
$sql = "INSERT INTO `users` (
`name`,
`email`,
`pass`)
values('omi','omi#gmail.com','123123')
OR:
$sql = "INSERT INTO `users` (`id`,
`name`,
`email`,
`pass`)
values('NULL','omi','omi#gmail.com','123123')

MySQL: UNIQUE keys

I have a weird issue, well, weird in my eyes anyway.
I've got a database with ID, username, email, password etc...
The ID is the Primary key, and both the username and email have the UNIQUE key assigned.
Now the strange thing is, when I submit, lets say the following values;
username: ActionHank
email: ah#ah.com
it is added.
Now when I try adding the same values again, I get an error that it is not allowed since it would be a duplicate entry. This works great.
But, when I put in the following next;
username: ActionHank2
email: ah#ah.com
It just adds it again, so 2 users have the same e-mail address while I've given the email row the UNIQUE key. I could also just change the e-mail address instead of the username and it will be added. So somehow the MySQL only registers one of the UNIQUE keys or something, I'm confused.
Could someone help me on this matter? Thanks
Edit: I've used phpMyAdmin to create the table and exported it to SQL, here's how the create table looks:
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(25) NOT NULL,
`email` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
`date_registered` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`ip_address` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`,`email`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=54 ;
So I think it has a composite as Michael and Kingkero suggested. How can I solve this within phpMyAdmin?
You have defined the combination of username and email to be unique. If you want each to be unique, you need to define separate unique constraints:
create table . . .
unique username,
unique email
)
Or, because these are single columns, you can just do:
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`username` varchar(25) NOT NULL UNIQUE,
`email` varchar(255) NOT NULL UNIQUE,
`password` varchar(255) NOT NULL,
`date_registered` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`ip_address` varchar(50) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=54 ;
Try this:
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`),
UNIQUE KEY `email` (`email`)

$wpdb->insert is not respacting unique fields

I have been creating Wordpress plugin for a while. This is example of mysql table:
$sql = "CREATE TABLE IF NOT EXISTS $table_name (
id INT(11) NOT NULL AUTO_INCREMENT,
email VARCHAR(100) DEFAULT NULL,
telephone VARCHAR(15) DEFAULT NULL,
PRIMARY KEY(id),
UNIQUE (email, telephone)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='WP plugin sesa_players db' AUTO_INCREMENT=1 ;
";
Email should be unique, right? phpMyAdmin says it it.
This is wordpress code that inserts data into that table:
$err = $wpdb->insert($wpdb->prefix.$table_name, $data, $format);
var_dump($err);
It works, even more than it should. Assume email is m#m.com. First insert goes well. Second try fails because of duplicate entry as it should. var_dump is false.
BUT if I refresh wp page, third try with same email passes flawlessly, var_dump 1. Any repeated wp refresh opens db for duplicate entry.
Why? What am I doing wrong?
No, email is not UNIQUE here. Pair of email and telephone is UNIQUE in your table definition.
$sql = "CREATE TABLE IF NOT EXISTS $table_name (
id INT(11) NOT NULL AUTO_INCREMENT,
email VARCHAR(100) DEFAULT NULL,
telephone VARCHAR(15) DEFAULT NULL,
PRIMARY KEY(id),
UNIQUE (email),
UNIQUE (telephone)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='WP plugin sesa_players db' AUTO_INCREMENT=1 ;
";
Probably this is what you want.

PHP MYSQL Insert/Update

I have a simple table as below.
CREATE TABLE `stats` (
`id` int(11) NOT NULL auto_increment,
`zones` varchar(100) default NULL,
`date` date default NULL,
`hits` int(100) default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;
So just storing simple hits counter per zone per day.
But I just want to increment the hits value for the same day.
I have tried the MYSQL DUPLICATE KEY UPDATE but this wont work as I may have many zones on different dates so I cant make them unique or dates.
So the only way I can think is first to do a query to see if a date exists then do a simple if() for insert/update
Is their a better way of doing such a task as there maybe be many 1000's hits per day.
Hope this makes sense :-).
And thanks if you can advise.
Declare the tuple (zone, date) as unique in your CREATE statement. This will make INSERT ... ON DUPLICATE UPDATE work as expected:
CREATE TABLE `stats` (
`id` int(11) NOT NULL auto_increment,
`zone` varchar(100) default NULL,
`date` date default NULL,
`hits` int(100) default NULL,
PRIMARY KEY (`id`),
UNIQUE (`zone`, `date`)
) ENGINE=MyISAM AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;
INSERT INTO stats (zone, date, hits) values ('zone1', 'date1', 1) ON DUPLICATE KEY UPDATE hits = hits + 1;
$result = mysql_query("SELECT id FROM stats WHERE zone=$zone AND date=$today LIMIT 1");
if(mysql_num_rows($result)) {
$id = mysql_result($result,0);
mysql_query("UPDATE stats SET hits=hits+1 WHERE id=$id");
} else {
mysql_query("INSERT INTO stats (zone, date, hits) VALUES ($zone, $today, 1)");
}
Something like that, if I've interpreted you correctly... that's completely untested. You can figure out what the variables are.

Categories