Example:
I have a tab "books" with "id" (int autoincrement) as primary key,
name, author, price etc...(not important). There's 5 books and I delete the book with id=3.
When I add other books the autoincrement value will start from 6 and there's a missed 3 in the id sequence (1 2 4 5 6). So multiple delete/add can create a tab with missing id values if I don't set the autoincrement value or I don't reassign id to books.
Can the situation with missing numbers in id create lowering of performance in queries?
You don't need to worry about performance with missing auto-increment values.
Just make sure you choose the proper data type for the auto-increment column so you do not run out of values.
Thats okay with auto-increment. A normal integer field would do the job for a very big amount of data. You could use "unsigned" option to increase this amount.
Related
I have a child table named case_parties, that consists of the name and address of each plaintiff and defendant to court cases.
The table columns include:
case_id, which is a foreign key to the parent table
party_type, which has coded field values of either 1 or 2 (1 indicating a plaintiff and 2 indicating a defendant). The caveat is that there is not always just 1 plaintiff and 1 defendant in every court case. Often, there are multiple plaintiffs and or multiple defendants in a single case. There can be anywhere from 1 to 1,000 + plaintiffs and or defendants on any given case. I created a new column, lets call it party_id and SET it with a CONCAT on the case_id and party_type columns. Therefore, matching rows in this column include either all the plaintiffs or all the defendants to a given case_id.
To create a simple unique key for each row, I want to run a script that adds an auto generated incremental number or letter to the end of the matching party_id field. For example, if there are 4 plaintiffs in the same court case, there are now 4 columns with matching party_id field values, with the last character being 1, representing the party is a plaintiff;
I want to add an increment on so each column is unique and the last two digits of the 4 rows would reflect something like this: "1A", "1B", "1C", "1D" or "1-1", "1-2", "1-3", "1-4",...etc. I'm thinking adding incremental numbers might be easier than adding incremental letters. No other column values individually or collectively make for an efficient composite index in this case. I'm seeking assistance with auto incrementing the matching column values and would greatly appreciate any assistance. Thank you.
I would suggest creating a separate table to represent the defendant/plaintiffs and have a type column in there. Then have a primary key on that table with a regular auto-increment.
You can then use that as your ID in the case_parties table (a foreign key) and it will address your issue with uniquely identifying each one.
I need to create an append query, that appends many records to a table. this table has a primary key, that is a sequential number. How do I make my append query, append records to the table and automatically assign the next sequential number for the primary key? I woudl need to run this query on a live multi-user MYSQL server throughout the day
thanks!
If the PK is a true auto-incremental field, you should be able to leave the PK out of your 'append' query. The table will automatically assign the next value in sequence to your data row(s) that you are inserting.
ex: If you have this data in table names
id name
1 Ken
2 Jon
3 Steve
And you run this query
INSERT INTO names (name) VALUES ('Peter')
Your table should automatically assign id # 4 to Peter
If the sequential PK is maintained manually, I would suggest you alter that field to be a true auto-incremental field if at all possible, or create a new auto-increment field and drop the old one. Just make sure you update any other related tables before you drop the field.
I'm wondering how to store a list of ID indexes for each id in a table. These will effectively form "relations" between the IDs. Here's the main table so far:
table main:
id, integer, primary key
name, varchar
text_info_1, varchar
text_info_2, varchar
And now for each row, there will be some list of other rows' IDs which will show me how one row relates to the next. For example, the row with id #5 might be related to IDs 6,7,9,25,...etc.
Here are the options I've considered:
Create a new column as a text field and store a serialized list of these integer values. Then just unserialize when I want them.
Create a new table called "relations" with columns relation_id (int auto increment primary key), name1, name2, [and optional other fields specifying the relation type, which would be nice].
I feel like option 1 is a bit of a hack. I've done it before and it works, but perhaps option 2 is better design?
I'm worried about speed though. With option 1 I can just do SELECT relations FROM main WHERE id = $id, and then unserialize the result and have my array with integer indices. But with option 2 I'll have to browse through a table that will be many times (10x or more) larger, and do "SELECT name1, name2 FROM relations".
Speed is my main priority here. I'm not sure which one is better for space, though I would be curious to find out.
So which option should I go with? Are there other good options I haven't considered? I'd also appreciate some good general pointers on database design!
Thanks a bunch.
Second option is better. If you want to get better in database design, you should read about database normalization. Sadly, all the materials I've used were not in English. This wikipedia link
could be a start.
Table relations:
relation_id (int auto increment primary key)
id_one (int)
id_two (int)
...
Instead of storing names in the relations table, you store ids.
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.
I have a table with an auto_increment field and sometimes rows get deleted so auto_increment leaves gaps. Is there any way to avoid this or if not, at the very least, how to write an SQL query that:
Alters the auto_increment value to be the max(current value) + 1
Return the new auto_increment value?
I know how to write part 1 and 2 but can I put them in the same query?
If that is not possible:
How do I "select" (return) the auto_increment value or auto_increment value + 1?
Renumbering will cause confusion. Existing reports will refer to record 99, and yet if the system renumbers it may renumber that record to 98, now all reports (and populated UIs) are wrong. Once you allocate a unique ID it's got to stay fixed.
Using ID fields for anything other than simple unique numbering is going to be problematic. Having a requirement for "no gaps" is simply inconsistent with the requirement to be able to delete. Perhaps you could mark records as deleted rather than delete them. Then there are truly no gaps. Say you are producing numbered invoices: you would have a zero value cancelled invoice with that number rather than delete it.
There is a way to manually insert the id even in an autoinc table. All you would have to do is identify the missing id.
However, don't do this. It can be very dangerous if your database is relational. It is possible that the deleted id was used elsewhere. When removed, it would not present much of an issue, perhaps it would orphan a record. If replaced, it would present a huge issue because the wrong relation would be present.
Consider that I have a table of cars and a table of people
car
carid
ownerid
name
person
personid
name
And that there is some simple data
car
1 1 Van
2 1 Truck
3 2 Car
4 3 Ferrari
5 4 Pinto
person
1 Mike
2 Joe
3 John
4 Steve
and now I delete person John.
person
1 Mike
2 Joe
4 Steve
If I added a new person, Jim, into the table, and he got an id which filled the gap, then he would end up getting id 3
1 Mike
2 Joe
3 Jim
4 Steve
and by relation, would be the owner of the Ferrari.
I generally agree with the wise people on this page (and duplicate questions) advising against reusing auto-incremented id's. It is good advice, but I don't think it's up to us to decide the rights or wrongs of asking the question, let's assume the developer knows what they want to do and why.
The answer is, as mentioned by Travis J, you can reuse an auto-increment id by including the id column in an insert statement and assigning the specific value you want.
Here is a point to put a spanner in the works: MySQL itself (at least 5.6 InnoDB) will reuse an auto-increment ID in the following circumstance:
delete any number rows with the highest auto-increment id
Stop and start MySQL
insert a new row
The inserted row will have an id calculated as max(id)+1, it does not continue from the id that was deleted.
As djna said in her/his answer, it's not a good practice to alter database tables in such a way, also there is no need to that if you have been choosing the right scheme and data types. By the way according to part od your question:
I have a table with an auto_increment field and sometimes rows get deleted so auto_increment leaves gaps. Is there any way to avoid this?
If your table has too many gaps in its auto-increment column, probably as a result of so many test INSERT queries
And if you want to prevent overwhelming id values by removing the gaps
And also if the id column is just a counter and has no relation to any other column in your database
, this may be the thing you ( or any other person looking for such a thing ) are looking for:
SOLUTION
remove the original id column
add it again using auto_increment on
But if you just want to reset the auto_increment to the first available value:
ALTER TABLE `table_name` AUTO_INCREMENT=1
not sure if this will help, but in sql server you can reseed the identity fields. It seems there's an ALTER TABLE statement in mySql to acheive this. Eg to set the id to continue at 59446.
ALTER TABLE table_name AUTO_INCREMENT = 59446;
I'm thinking you should be able to combine a query to get the largest value of auto_increment field, and then use the alter table to update as needed.