3

Following is my database in mysql:

Id  Username    Password
1   admin       admin
2   jay         jay1
3   suman       xyza
4   chintan     abcde

This is my code in php:

$fetchid = mysql_query(" SELECT MAX(Id) As max From user;");
$row = mysql_fetch_array($fetchid);
$largest = $row['max'];
$largest++;

$user= $_POST['username'];
$pass= $_POST['password'];

$result = mysql_query(" INSERT INTO `proshell`.`user` (
`Id` ,
`Username` ,
`Password`
)"."
VALUES (
'".$largest."', '".$user."', '".$pass."'
);");

Problem: Now if I delete row with Id=1 and then re-enter the data then it should use ID=1 then Again I reinsert the data it use ID=5

It works like this: if I delete row with Id=1 and then re-enter the data the Id it gets is 5 but then 1 is free so,

What should I write to perform that task.

  • http://stackoverflow.com/questions/12325132/mysql-get-missing-ids-from-table – Chetan Ameta Feb 12 '16 at 08:14
  • No it shouldn't use ID 1, it should simply use a new and unique ID..... AUTOINCREMENT is about getting unique IDs, not consecutive IDs..... if you need a consecutive value, then you need to manipulate it yourself, or (more probably) rethink why you believe you need consecutive ids numbered from 1 and with no gaps – Mark Baker Feb 12 '16 at 08:18
  • If you need to change the record at ID 1, why are you trying to delete and re-insert rather than simply to update – Mark Baker Feb 12 '16 at 08:18
  • @MarkBaker I am stating that there are two users of this database okay? So If one person lefts than it will delete his ID. okay. The if new person comes then it has to create a new ID then at that time it will cause problem. Here I have small application. But in future this can be the issue when more than people expected joins and then leaves the application permanently. –  Feb 12 '16 at 08:35
  • at that time you can reuse those IDs.. So out of curiosity I asked this question and if I get the answer one of my problem will be solved –  Feb 12 '16 at 08:35
  • @ChetanAmeta I can find the Id man but how can implement it. Thats my question? Sometimes I find rows sometime the DB is perfect so I can't find rows –  Feb 12 '16 at 08:59
  • 1
    If you care about the ids, then you probably have bigger problems with your data. See normalisation. – Strawberry Feb 12 '16 at 09:39
  • If you've designed your system so that id values must always be consecutive, then you have designed yourself with a major problem that will become harder and harder to manage as the number of users grows, and you've completely misunderstood the purpose of an id – Mark Baker Feb 12 '16 at 09:50
  • `The if new person comes then it has to create a new ID then at that time it will cause problem.` Why should it cause a problem? What is so special about your design that you must have consecutive ids? – Mark Baker Feb 12 '16 at 09:51

2 Answers2

1

First, if you set your Id column to AUTO_INCREMENT you don't need the following part in your code at all:

$fetchid = mysql_query(" SELECT MAX(Id) As max From user;");
$row = mysql_fetch_array($fetchid);
$largest = $row['max'];
$largest++;

Because AUTO_INCREMENT will automatic add new value to your ID colume.

But if you don't set it to AUTO_INCREMENT, the above code will grab the MAXIMUM ID value (in this case, 4).

When you re-enter your data again after you delete the row 1, the MAXIMUM ID still 4, so your new ID value will be 5 (from $largest++;).

.....

If you really need to use consecutive ids as you PK, you need to re-write you code but I suggest you to use UUID for you ID column instead.

You can easily generate UUID by using uuid().

How about the UUID performance? Refer to Dancrumb's answer about this:

A UUID is a Universally Unique ID. It's the universally part that you should be considering here.

Do you really need the IDs to be universally unique? If so, then UUIDs may be your only choice.

I would strongly suggest that if you do use UUIDs, you store them as a number and not as a string. If you have 50M+ records, then the saving in storage space will improve your performance (although I couldn't say by how much).

If your IDs do not need to be universally unique, then I don't think that you can do much better then just using auto_increment, which guarantees that IDs will be unique within a table (since the value will increment each time)

see. UUID performance in MySQL?


EDIT: I don't suggest you run query on the whole table just to find the MAX ID value before inserting new value everytime, because it will give you a performance penalty (Imagine that if you have million rows and must query on them everytime just to insert a new row, how much workload causes to your server).

It is better to do the INSERT just as INSERT, no more than that.


EDIT2:

If you really want to use consecutive ids, then how about this solution?

Create new TABLE just for store the ids for insert (new ids and the ids that you deleted).

For example:

CREATE TABLE cons_ids (
  ids INT PRIMARY KEY,
  is_marker TINYINT DEFAULT 0
);

then initial ids with values from 1-100 and set marker to be '1' on some position, e.g. 80th of whole table. This 'marker' uses to fill your ids when it's nearly to empty.

When you need to INSERT new Id to your first table, use:

$result = mysql_query("SELECT ids, marker FROM cons_ids ORDER BY ids ASC LIMIT 1;");
$row = mysql_fetch_row($result);

and use $row[0] for the following code:

INSERT INTO yourtable (Id, Username, Password)
VALUES ($row[0], $username, $password);

DELETE FROM cons_ids
WHERE ids = $row[0];

This code will automatically insert the lowest number in cons_ids as your Id and remove it from the cons_ids table. (so next time you do insert, it will be the next lowest number)

Then following with this code:

if ($row[1] == 1) {
  //add new 100 ids start from the highest ids number in cons_ids table
  //and set new marker to 80th position again
}

Now each time you delete a row from your first table, you just add the Id from the row that you deleted to cons_ids, and when you do INSERT again, it will use the Id number that you just deleted.

For example: your current ids in cons_ids is 46-150 and you delete row with Id = 14 from first table, this 14 will add to your cons_ids and the value will become 14, and 46-150. So next time you do INSERT to your first table, your Id will be 14!!.

Hope my little trick will help you solve your problem :)

P.S. This is just an example, you can modify it to improve its performance.

Community
  • 1
  • 1
madooc
  • 89
  • 5
0

First of all, as I understand, you are selecting highest column ID which should be always the last one (since you set auto-increment on ID column).

But what are you trying to do is actually filling up holes after delete query, right?

If you are really looking for such approach, try to bypass delete operation by making new boolean column where you flag record if it is active or not (true/false).

SQL table change:

    Id  Username    Password Active
1   admin       admin       false
2   jay         jay1        true
3   suman       xyza        false
4   chintan     abcde       true

PHP request:

$fetchid = mysql_query(" SELECT MIN(Id) As min FROM user WHERE active = false;");

$result = mysql_query(" INSERT INTO `proshell`.`user` (
`Id` ,
`Username` ,
`Password`
`Active`
)"."
VALUES (
'".$largest."', '".$user."', '".$pass."', 'true'
);");
Andrej Buday
  • 559
  • 5
  • 14
  • This is not feasible solution. Because If I have million entries then I have go through every value. And if the case is I have empty Id just one less than max(1 million) then I have to go through 999998 rows first. So heck of a task to do. –  Feb 12 '16 at 08:47