Mysql restart auto int primary key - mysql

Hello is it possible to save the deleted auto incremented primary key in my database. For example
I have
Name_ID
1
2
3
4
If I delete primary key 4 and I insert again the primary key of I inserted should be four.
so. Name 1 2 3 4 5
I deleted primary key 5 (Name 1 2 3 4)
I added a data primary key should be 5 again not 6. THANKS!

Auto generated fields always have gaps in these cases.
What if you have an audit or history table that stored the rows with ID = 4, ID = 5? Then delete them again? How do you differentiate rows?
In your example, you've only deleted the last row? What is you delete ID = 1? Then what?
That is, they are just internal numbers unique to that table (and any associated tables like audit ones): no external meaning should be attached

As with other comments and answers here, I would not recommend this, especially if the data in the auto increment column is referenced externally, but you can set the next auto increment number to a specific value via an ALTER TABLE query
ALTER TABLE T_YourTable AUTO_INCREMENT=4
You could also drop the column and then re-add the column with the same attributes (this could be expensive if you have a lot of rows).

Why?
It's only intended to be a unique identifier.
You'll also get gaps with database clusters and whenever you rollback an insert transaction which overlaps a commited transaction - not just when you delete data.
A mechanism to fill-in-the-gaps would be complex, slow and difficult to maintain - and it's not needed.

Related

MySQL - update row if some column value equals else insert row (NO DUPLICATE KEY)

I have a table that stores meta values, however, in insert/update I want to perform - there is no unique key (not even a combination of columns).
1 column stores ID of a post, 1 a varchar key of a meta value and 1 holds the meta value...
Now the thing is, the table CAN contain duplicate rows, easily, this can happen:
id_post | key | value
5 'bobber' 4
3 'locer' 2
5 'bobber' 4
Now what I want to do is to do a variation of insert or duplicate key update, problem is, I don't have the key that would trigger the update.
If the key value is already existing in the table, I want to update the corresponding value column(s). If it is not, I want to insert a brand new row.
All I found ends up with adding a key constraint, which is something I can't do.Also, I do not want to create a stored procedure/function.
Any help please? Thank you :-)

Auto incrementing part of a composite key

Currently I have a composite-primary key consisting of (user, id). My user is John Smith and there are say 30 rows that pertain to him, hence id auto increments each time a new entry is made.
However, if i wanted to add a new user, say Jill Smith to the same table, is there a way in which I can start at (Jill Smith, 1) and have the id auto increment without messing up the previous entries?
No. AUTO_INCREMENT in MySQL cannot have multiple "states" to keep track of multiple counters. To have the described behaviour, you need to implement your own application logic (w/o using the autoincrement feature) and calculate the number part of the key before inserting new rows.
UPDATE
The above is true in general in MySQL but how AUTO_INCREMENT works depends on the storage engine.
The documentation is quite specific on your particular scenario for MyISAM tables:
If the AUTO_INCREMENT column is part of multiple indexes, MySQL
generates sequence values using the index that begins with the
AUTO_INCREMENT column, if there is one. For example, if the animals
table contained indexes PRIMARY KEY (grp, id) and INDEX (id), MySQL
would ignore the PRIMARY KEY for generating sequence values. As a
result, the table would contain a single sequence, not a sequence per
grp value.
https://dev.mysql.com/doc/refman/5.6/en/example-auto-increment.html

How to re-arrange database primary key

Good day
I create database at localhost for website. and put some info, than i delete and re-enter info from database. and now for 'id' primary key i have more than 200 rows. I want to re-arrange primary key.
for example
id |name
1 |Samuel
2 |Smith
4 |Gorge
15 |Adam
19 |David
i want to have
id |name
1 |Samuel
2 |Smith
3 |Gorge
4 |Adam
5 |David
Is it possible to do with any command?
You could drop the primary key column and re-create it. All the ids will then be reassigned, I assume in the order in which the rows were inserted.
alter table your_table drop column id;
then to create it
ALTER TABLE `your_table_name` ADD `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST;
The purpose of a primary key is to uniquely identify each row, so rows in one table can be related to rows in another table. Remember, this is a relational database and part of the meaning of "relational" is that entities are related to each other.
In other words, you don't want to change the primary key of rows, because that will break links from other tables. MySQL does not guarantee that auto incremented values are inserted without holes. In fact, as you have discovered, deletions and re-inserts cause problems.
Your interpretation of the "primary key" as a sequential number with no gaps assigned to each row maintained by the database is simply not correct.
Even though you don't want to do this, you can. I advise against it, but you can:
declare #rn := 0;
update t
set id = (#rn := #rn + 1)
order by id;
If you want to enforce this over time, you will need to learn about triggers.
Consider this scenario: Gorge sends some offensive emails, and people complain and his account (#4) is denylisted.
Then you reorder your primary key values, and Adam is now assigned id 4. Suddenly, he finds himself banned! And lots of people mistrust him without cause.
Primary keys are not required to be consecutive -- they're only required to be unique. It's normal for there to be gaps, if you sometimes ROLLBACK transactions, or DELETE rows.
Most likely the primary key is being auto generated from some sort of auto increment sequence. In that case you can take the following steps:
1) update all the primary keys to the next value of the sequence: this will collapse all of the values into a contiguous range. In your case those ids will be 20, 21, 22, 23, 24. Postgres example:
UPDATE my_table SET id = nextval(my_table_id_sequence)
2) reset the sequence to start at 1: In Postgres this would look like the following:
ALTER SEQUENCE my_table_id_sequence RESTART WITH 1
3) update the values to the next value of the sequence again: Now can move all the rows back "down" to start at 1, and in your case they will be 1, 2, 3, 4, 5. It is important to first consolidate all the values at the "top" of the sequence before resetting, because that way we guarantee that there wont be any primary key collisions at the "bottom"
UPDATE my_table SET id = nextval(my_table_id_sequence)
NOTE: this approach only works if there are no foriegn keys which are referring to the primary key of the table. If there are foreign keys you can still take the same approach, but first do these 3 steps:
1) find all of the related tables/columns that are referencing this primary key column
2) create a function that will cascade updates to the pk out to all fks
3) create a trigger that will execute the above function whenever the pk is updated: at this point, when we update the primary key column, all of the related foreign keys will also be updated. Depending on the database, you might need to explicitly defer constraint validation, or do the whole thing in one transaction.
For an example of what the above might look like in Postgres you can take a look at my answer here How Do I Deep Copy a Set of Data, and Change FK References to Point to All the Copies?

If I delete a row from a table in a database how to rename the primary keys

So I want to delete a row from a table e.g
1
2
3
4
5
7
8
How do I rename the tables rows primary keys so they are equal to
1
2
3
4
5
6
7
This question comes frequently but it's a false problem. You don't have to care about id. It's just an identifier. Leave it as it is.
You can add a progressive number programmatically, using your favourite programming language or via sql.
select *,#row:=#row+1 as progressive_number
from table, (select #row:=0) as t
You shouldn't rename primary keys. Their function is to provide a unique internal identifier in your database. Even it has a sequence like 1, 10, 43, 88 .. it doesn't matter as it should have no cosmetic meaning whatsoever.
You can delete the row by its primary key...
delete from my_table where id = 4
And then decrement all subsequent keys:
update my_table set id = id - 1 where id > 4;
Assuming all the foreign keys referencing the primary key are set to on update cascade, the internal referential integrity will be maintained. If you're using the numeric id to build URLs, your URLs are all now broken.
But you absolutely should not do this. This is not how databases work. It is not a case of aesthetics, it is outright wrong to do this with your data. This is literally no good reason to do this, and a ton of reasons not to.

How can I change auto increment primary key values on row deletion?

I have a problem that whenever I delete a row, the row ID corresponding to that row gets deleted, but I don't want this. What I want is if any row is deleted, then other rows after that row should shift one (the no. of rows deleted) position up.
Example:
Suppose there is a user table(id and name)
id(auto incremented primary key) name
1 xyz
2 aaa
3 ray
4 mark
5 allen
now delete row with id=3 and table should look like
id(auto incremented primary key) name
1 xyz
2 aaa
3 mark
4 allen
Is there any way to accomplish this?
No! Don't do this!
Your Autoincrement ID is the IDENTITY of a row. Other tables use this ID to refer to a certain row. If you update the ID, you would have to update all other tables referencing this row, which is not at all the point of a relational database.
Furthermore, there never is a need to do this: you won't run out of autoincrement columns fast (and if you do, just pick a bigger datatype).
An autoincrement ID is a purely technical number, your application users should never see or use it. If you want to display an identificator to your users, add another column!
You've completely got the wrong end of the stick. Auto numbers should not be changed as this would break the link between any other referencing tables.
What you want, by the sounds of it, is a row counter, not a primary key.
While its generally not recommended to change these values, there do exists instances where you may need to change them. If you have the appropriate Foreign Key relationships setup to cascade on UPDATE then you could do this. Granted you need to be 100% all FK relationships are defined as expected.