This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to fill in the “holes” in auto-incremenet fields?
We are currently using auto-increment on a table where entries come and go constantly. The problem with this, is that eventually the auto-increment id becomes huge, as that is how auto-increment works.
We would like to have it always add +1 to the last entry.
For example:
We have 4 entries and id 4 is deleted. Next added entry should get id 4, and not 5.
I am not sure if this has been asked before. But after searching I was only able to find solutions on how to get the next auto-increment number, which is not what I am looking for at all.
YOU SHOULD NOT DO THAT because auto_increment is designed this way for good reasons (like if you have a backup and you want to restore it when it contains old deleted id that has been rewrote, how do you do ?)
But to answer your question:
You have to use
ALTER TABLE `table` AUTO_INCREMENT = MAX(id)+1;
After a delete, you can make a trigger
If you really want to do that (I personally encourage you to use auto-increment), you need to perform a transaction in order to get the last ID and insert the new row setting its ID incrementing it according to the other one.
It's not a good idea to do this, the ID should always stay unique, no matter if the record exists or is deleted.
However if you really want to do it, you can to it with something like
select max(id) + 1 of bla;
But you need the right transaction level for it because if you don't you have a possibility of duplicated ids.
You can choose maximum id value and just increment it.
SELECT MAX(`id`)+1 as `new id` FROM `table`;
If you have 5 entries and 3rd gets deleted, this will still get you 6 as next id.
Related
This question already has answers here:
Get most recent row for given ID
(7 answers)
Closed 5 days ago.
hi i want to get last id from my table then i will put it in registration form with +1 mean's +1 id will be automatically generated when any form inserted i'm doing this because i have 4 user's i want that id no of registration forms starts from 1 for every user
SELECT *
FROM registration
WHERE id=(SELECT MAX(id) FROM registration);
i use this code but i'm unable to add AND condition i need something like
SELECT *
FROM registration
WHERE id=(SELECT MAX(id) FROM registration)
AND project_name='test2';
this mean i want to add AND condition where it will check this project_name last id
Riggsfolly already warned you about generating your own IDs.
It is MUCH safer to let the database generate UNIQUE ID's.
(Almost) Every table I create gets a primary key that has some form of SERIAL in it.
For example: For Postgres I use SERIAL:
CREATE TABLE registration (
registrationid SERIAL PRIMARY KEY,
project_name VARCHAR(100),
whatever VARCHAR(1000)
)
You seem to use MYSQL: Look up AUTO_INCREMENT.
Now, if you insert into that table, you do it without the registrationid:
INSERT INTO registration (project_name , whatever ) VALUES ('test2', 'hi there');
If this is the first insert in the table registrationid will automagically become 1.
Next insert is will be 2. etc etc.
Now suppose you did this 1000 times, you next one will then be 1001.
When you delete a few, that doesn't matter, the next will be 1002.
Now: If you want the query for the highest registrationid AND some project_name, do it like you did, but make sure you get the MAX() of the ones that have your desired project_name:
SELECT *
FROM registration
WHERE registrationid= (SELECT MAX(registrationid) FROM registration WHERE (project_name='test2') ) ;
2 last observations:
Follow Riggsfolly's advice and do not generate your own uniqueness, but let the database do this using appropriate syntax when defining your table (SERIAL for Postgres, AUTO_INCREMENT for MySQL, etc).
In my example the inserts are naive. It is better to use PDO for databinding when working with strings to avoid SQL-injection.
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
This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
How to set a MySQL row to READ-ONLY?
I need to temporarily protect custom rows of a table from editing by another users.
for example when I'm inserting a row with this feature : tid = 51 ; should not let anybody to insert a row , or at least a row with tid = 51 at the same time.
How can I do this?
Usually, an id is assigned to a row only at the moment it is inserted into the database. It does not exist before this moment. After it, it is already insert, and nobody else will be able to insert another row with the same id (assuming it is a uniquely indexed column).
So, your example seems to be invalid. Anyway, the question still makes sense if we ignore the example and consider the opening phrase: "I need to temporarily protect custom rows of a table from editing by another users."
In this case, you need to store somewhere the value of the IDs being edited, and by which user. Then, you need to check this data to allow / disallow an edit action.
In fact, the main problem here is the UNLOCK phase, due to the stateless nature of web/HTTP applications. If the row is not properly UNLOCKED after its edition or some kind of timeout, it will be permanently locked (instead of temporarily).
What you want goes agains everything a database was designed for. I you want a unique primary key, use a auto increment field. If you want to enforce a unique field value, use a field contraint, perhaps a unique field or a unique combination of fields.
Do NOT lock the table, row or database, in almost any case this is bad design!
Simply define the column (tid) as an AUTO_INCREMENT field in MYSQL (or any other DBMS, this feature is almost supported everywhere). You don't have to look after the locking, the Database will do it for you.
If you NEED this field's value before inserting a row in the database (wich is actually not always a good design), uou should use a random generated UUID. Thus avoiding collision by minimizing the probability of having two identical values.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Problem with autoincrememnted “id” column
My db table looks like this pic. http://prntscr.com/22z1n Recently i've created delete.php page. it works properly but when i deleted 21st user next registered user gets 24th id instead of 21. Is it possible to put newly registered users info to first empty row? (In this situation 21st row)
In my registration form, newly registering user can write names of existing users, and be friends with them after registration. For this friendship i have another table that associates id of newly registered user and existing user.For this purpose i'm using mysql_insert_id during registration to get id for new user. But after deletion of 21st row during next registration process mysql_insert_id gave me number 21. but stored in 24th row. And put to associations table 21 for new user. I wanna solve this problem
You received the answer the last time you posted this question. MySQL maintains an internal counter that is incremented every time a new row is inserted into a table with an auto-increment column. The increment value does not go down when a row is deleted.
To make things work the way you want, you will need to avoid using MySQL autoincrement, and implement your own solution to create and increment IDs.
mysql_insert_id() is a very very bad approach to get your id. You can always set the auto_increment value of your table, but I wouldn't suggest it. You should always do a SELECT of the latest record you insert based on some unique values, and order it by id DESC while limiting it to one result. Don't ever use mysql_insert_id().
It makes no difference - mysql_insert_id will return the autoincremented ID of the last inserted row. If the row gets ID 24, mysql_insert_id will return 24.
However, you can change the next value autoincrement will result it. Read up on it here.
DROP the field you are auto_incrementing
ALTER the table to ADD the field again with the same attributes
All existing rows are renumbered and the next auto_increment number will be equal to the row count plus 1
WARNING:
There really is no reason you would need to do this or should do this! If you have references to these ids anywhere, which I know you do from earlier questions - this can break every single link.
Okay, so let's say I have a mysql database table with two columns, one is for id and the other is for password. If I have three rows of data and the id values go from 1 to 3 and I delete row 3 and then create another row of data, I will see id=4 instead of id=3 on the newly created row. I know this has to do with the auto increment value but I was wondering if I can add some code in a php file that will automatically reset all the id numbers such that you start at id=1 and go up to the last id number in increments of 1 after a row has been deleted?
My goal is to create a form where the user enters a password and the system will match the password with a password value in the database. If there is a match, the row with the matched password will be deleted and the column of id numbers will be reordered such that no id numbers are skipped.
Update: I'm making a rotating banner ad system by setting a random number from 1 to 4 to a variable so that the php file will retrieve a random ad from id=1 to id=4 by using the random number variable. If the random number happens to be 3 and id=3 does not exist, there will be a gap in the row of banner ads. If there is a way to work around big gaps in this situation, please tell me. thanks in advance
Just execute the following SQL query:
ALTER TABLE `tbl_name` AUTO_INCREMENT = 1;
…but it sounds like a terrible idea, so don't do it. Why is the value of your primary key so important? Uniqueness is far more important, and reseting it undermines that.
You can only use
ALTER TABLE 'tbl' AUTO_INCREMENT=#
to reset to a number above the highest value number. If you have 1, 2, 3, and you delete 2, you cannot use this to fill 2. If you delete 3, you could use this to re-use 3 (assuming you haven't put anything higher). That is the best you can do.
ALTER TABLE 'table' AUTO_INCREMENT = 1;
However running this code is not the best idea. There is something wrong with your application if you depend on the column having no gaps. Are you trying to count the number of users? if so use COUNT(id)? Are you trying to deal with other tables? If so use a foreign key.
If you are dead set on doing this the Wrong Way you could try to look for the lowest free number and do the incrementing on your own. Keep in mind the race conditions involves however.
Also, keep in mind that if you change the actual numbers in the database you will need to change all references to it in other tables and in your code.
Well, you can actually just specify the id number you'd like a record to have as part of your insert statement, for example:
INSERT INTO person VALUES(1,'John','Smith','jsmith#devnull.fake','+19995559999');
And if there's not a primary key collision (no record in the database with id=1), then MySQL will happily execute it.
The ALTER TABLE 'tbl' AUTO_INCREMENT=# thing also works, and means you don't have to keep track of the counter.
While you're thinking about this, though, you might want to read some of the discussion on natural vs surrogate keys. The idea of having your id # be specifically important is a bit unusual and might be a sign of a troubled design.
You could do that by:
Inventing a mechanism that provides the next available id when you want to insert (e.g. a transaction involving reading and incrementing an integer column somewhere -- pay special attention to the transaction isolation level!)
Using UPDATE to decrement all ids greater than the one you just deleted (again, with a transaction -- don't forget that foreign keys must be ON UPDATE CASCADE!)
But it begs the question: why do you want this? is it going to be worth the trouble?
It's almost certain that you can achieve whatever your goal is without such witchery.
Update (to address comment):
To select a random number of rows, you can do e.g. in MySQL
SELECT id FROM banners ORDER BY RAND() LIMIT 5
to select 5 random, guaranteed existing banner ids.
A word of caution: there are quite a few people who view ORDER BY RAND() as a bad performance hog. However, it is IMHO not quite right to put every case in the same basket. If the number of rows in the table is manageable (I would consider anything below 10K to be not that many) then ORDER BY RAND() provides a very nice and succint solution. Also, the documentation itself suggests this approach:
However, you can retrieve rows in
random order like this:
mysql> SELECT * FROM tbl_name ORDER BY RAND();
ORDER BY RAND() combined with
LIMIT is useful for selecting a random
sample from a set of rows:
mysql> SELECT * FROM table1, table2 WHERE a=b AND c ORDER BY RAND() LIMIT 1000;
RAND() is not meant to be
a perfect random generator. It is a
fast way to generate random numbers on
demand that is portable between
platforms for the same MySQL version.