Create Unique MYSQL Primary Key Where Only Part Of is Incremntal - php

In one of my mysql table, I need to generate the primary key field which is 15 digit in length.
Structure is 2+2+2+2+2+5 as ex: 010101010100001.
First 10 Digit values comes from five 2 digit form/input fields and last 5 character is unique and incremental. So, whenever a form/data is submitted that value will be increased.
now how can I achieve that?
I think of following method but thinking of 2 issue:
First use select query to get the last used id/number. Then add +1 to it.**
Issue-1:
For this I have to make 2 query 1 for select and 1 for update, but I think there is much better way than this?
Issue-2:
What if multiple like hundreds/thousands of users submit the form at the very same time? how can I make sure it will be unique and wont cause a db error?
any suggestion/idea would be highly appreciated.

Having a UNIQUE/PRIMARY KEY ensures that you cannot have any duplicate entries in the database. You will get an error message from MySQL if you try to create a duplicate entry. So you don't need to check for duplicates, MySQL will do so for you. However you have to check for error messages and react accordingly by changing the value like adding +1 on it, depending on your requirements.

Related

Most optimized/efficient way to update Database

I have a data set with more than 10000 (this will be more in future) records as below:
[[name=>'name1',url=>'url1', visit=>120],
[name=>'name2',url=>'url2'], visit=>250,
..........
]
It is possible to have duplicate values for the key combination name,url. In such situations I need to get the sum of each records have the duplicate name,url.
Finally I want insert this values into a database. When I do this I have two method to do this:
Create another array with unique combination (name,url) and sum of visit
Update/insert db for each record in a loop.
What is the optimal solution to do this or is there better way to do this?
I know there will be memory issues for a large data set in the first method. In second method there are many db hits and I need to know the disadvantage(s) if I follow 2nd way.
Any help or insight would be appreciated.
I do some big database update like this myself and spent ages trying different solutions.
Instead of:
Check if record exists, eg select count(id) from data where
name='name' and url='url'
Not found, insert record
Found, sum result
I would try this
Set the unique primary keys on your data table on the url and name field.
Try to do a normal insert and see if you get a successful result.
On unsuccessful result (there already is value for name and url because these 2 fields must be unique), sum the result.

How do i set the increment value of autoincrement in mysql

I am trying to develop a system to assign room numbers to tenants of a hostel upon registration, using the auto increment feature of sql.
However, it automatically increases by one after every entry. Because the hostel accommodates four people in one room, I want to change this to 4, so that after every 4 entries I get only one id/room number.
How do I go about this? I am using php and sql. If the autoincrement feature is not possible can you please suggest another way to achieve this? Thanks.
You would need:
http://dev.mysql.com/doc/refman/5.1/en/replication-options-master.html#sysvar_auto_increment_increment
It works like this:
mysql> SET ##auto_increment_increment=4;
So when you insert 4 rows, the auto increment column will be:
4,8,12,16
as best of my knowledge you cannot change the steps of auto-increment field. I suggest add another field and write a trigger to update its value based on auto-increment field (auto-increment/4).
I don't think this is possible with autoincrement..
Maybe you can do something like this:
//Pseudo code
//First you get the count of the highest id, to see how many users are in the last room.
SELECT COUNT(*) FROM table WHERE id=(SELECT id FROM table ORDER BY id DESC LIMIT 1)
//If the result of the last query is >= 4 then insert the next customer with id +1
Don't use auto_increment for this - it can't handle a situation where multiple records will share the same number and although you can reset it manually (see below) it's also not designed for a situation where numbers may get reused in a random order.
You could just have a room_number field with one of the mysql integer types (e.g. tinyint, smallint, mediumint…) or you could separate your database into two tables, one for people (each of whom have an id) and a second to map those ids to rooms.
However you do it, you'd then write a select query to check which room numbers are available before you add the person's details to the database.
You may need to read up on relational databases if that doesn't sound very clear.
If you do need to reset the auto_increment (sometimes it's nice to do it if you've filled a database with test data which you're about to wipe, and you want the real "production" data to begin at 1) you can use:
ALTER TABLE [tablename] AUTO_INCREMENT = 1
https://dev.mysql.com/doc/refman/5.0/en/example-auto-increment.html

How to run a MYSQL INSERT query that doesn't replace duplicates based on multiple columns where auto-increment id is present?

I have searched around for the answer to this and have come across IGNORE and WHERE NOT EXISTS however they both seem to do slightly differently than what I am trying to accomplish. My MYSQL table appears as follows:
id(auto increment INT), charactername(VARCHAR), characterregion(VARCHAR), characterrealm(VARCHAR)
My data is retrieved from a website that returns all of the characters of a game, even the ones I already have in my database.
I wish to keep a list of all of the characters but no duplicates. My issue seems to be that I need to compare the name, realm and region of the character before deciding if it is a duplicate as the same name can appear on different region/realm combinations.
I have tried comparing all of the values of the 3 non-auto incrementing columns as follows:
REPLACE INTO characters (charactername, characterregion, characterrealm) VALUES ('Peter','AMERICA','Realm1') WHERE NOT EXISTS(SELECT * FROM characters WHERE charactername='Peter' AND characterregion='AMERICA' AND characterrealm='Realm1')
This however returns a MYSQL error as the syntax is incorrect. I have also tried INSERT IGNORE INTO... however that only seems to be checking the id value. I don't believe I need to check the id at all as I have it set to auto increment.
Any help would be greatly appreciated, I am using PHP for the other parts of this if it helps. Thanks again.
Just add a composite index on all 3 columns.
alter ignore table mytable add unique index(charactername, characterregion, characterrealm);
then do
INSERT INTO characters (charactername, characterregion, characterrealm)
VALUES ('Peter','AMERICA','Realm1')
ON DUPLICATE KEY
UPDATE
charactername='Peter1',characterregion='AMERICA1',characterrealm='Realm11'
The update will trigger only if all 3 columns are identical.Or you could do just an INSERT and it will fail if all 3 columns are identical.

Check duplicates SQL or php?

I have a field in my users database, a 6 digit number that is generated upon registration. I use mt_rand(100000, 999999) to generate the numbers.
Now to the question, to make sure no one gets the same number I need to either make the field UNIQUE (which i think seems the best) instead of some PHP code. Maybe theres some other way I don't know. The question is, whats the best way to do this?
You can do this way using PHP.
First give a unique constraint to the field.
if (mysqli_errno() == 2027)
mysqli_query("INSERT INTO ... {mt_rand()}");
So, once you insert a duplicate value, it gives out an error code 2027, saying duplicate. You can resubmit the query.
Why don't you
use a nested select to get the max(user_id), increase it and use that value for the new user?
create a table that holds just the current user-id and fetch, increase and use that value to create the new user?
use an AUTO_INCREMENT column?
Use an AUTO_INCREMENT column.
Performing a query to check if a generated number already exists is a bad solution and become worse with more and more users registered because more number are used, so you need to keep trace of all generated numbers to always generate a valid number.
With an AUTO_INCREMENT column, this occurs "automatically" .

ID's in phpmyadmin

I have a table in my phpmyadmin that contains some data for items that will be posted on a website. I'm adding these rows to the database manually. I want to show the number of the posted item. The first one will be '1', second one will be '2', etc. However if I use auto increment and delete the 2nd row there will be a gap in between. Suggestions to fix this?
I used PHP to display the ID of the row but when the second is deleted it shows the gap.
The structure starts with a column named 'id' which has a primary key and auto increment.
You don't want to do that! Period. You'll create yourself a lot of problems.
Your real issue is somewhere else. You think not having gaps between your ids will solve it. Solve that problem differently but leave the autoincremented id column alone. It is being implemented like that for a reason. The autoincrement makes sure you will never confuse two entries, it doesn't matter if there are gaps, you can always sort, you can always identify! If you need nice straight numbers, store your entries in a numeric array and use the keys for numbering. Or loop over your entries with a for loop and use the incrementor for numbering, or introduce an order column in your database.
Suggestions to fix this?
It's not broken!
You should not care or consider database ids as a developer, it is for internal use and data integrity.
If you really want to use incrementing numbers without gaps, use this in your query:
LIMIT 1 OFFSET X
Where X is the "id" in your url (not the real id).
However, listen to the folks here that are advising against this. It's not a very good idea and trust me, no one will care or even notice the forward facing database ids.

Categories