Question

I have a parent table and two child tables. We use mysql's AUTO_INCREMENT to increment the primary key. Recently we have decided to archive the data from the parent and child tables to respective archive tables (archive table is identical to the current table). The aim of this activity is to reduce the dataset of the current tables. Because we use INNO DB, at mysql restart, the primary key starts getting reused (say record with ID 2 is archived and later mysql restarts, the 'id' 2 is reused) . When the data is now archived, because of the duplication of primary key (reuse), the integrity constraint fails on the archive table.

A possible solution to this is to stop using AUTO_INCREMENT. The primary key would instead be the epoch time. Since my application is built in java, I decided to use System.nanotime() to generate my PRIMARY key. Is this a good solution?

It could have been easier to instead use [System.nanoTime() + a random string] to be absolutely sure of the uniqueness of the key. But i don't want to alter the Production systems which have ID field defined as BIGINT.

Any good idea's / suggestions?

For clarity , let me give another example. Say there are three records in the artist table

Artist Table

ID NAME TIME
1 JIM 2 JAN 2010
2 Mark 1 JAN 2013
3 John 1 JAN 1975

After time T1, the Housekeeping kicks in and the algorithm decides that its time to archive record with ID 3. SO it moves record to archive table

Artist_Archive

ID NAME TIME
3 John 1 JAN 1975

Note that the ID of the archive table is not AUTO_INCREMENT. It is the exact copy of the current table. The reason for this is that I want to keep the archive logic simple for the child tables.

At time T2 mysql restarts as a part of schedule maintenance. At time T3, a new record is inserted (ID=3 again). So the table snapshot is

Artist Table

ID NAME TIME
1 JIM 2 JAN 2010
2 Mark 1 JAN 2013
3 Peter 10 JAN 1980

At time T4, Housekeeping kicks in again and decides its time to archive record with entry 3 again. This is where the issue arises. Remember, archive table already has a entry with ID 3 . Its simply rejects the record with constraint violations.

This is where I thought of using timestap as the PK. This ensures that I never have a repeat PK.

Was it helpful?

Solution 2

In the comments section of the below link, there is a workaround provided to overcome the limitation.

https://dev.mysql.com/doc/refman/5.0/en/innodb-auto-increment-handling.html

*As InnoDb forgets its highest auto_increment after server restart, you can set it again, if you have stored it anywhere. This happens often if you archive your data in an archive table and then delete it and then restart mysql. When archiving again this will result in duplicate key entries. To work around this you can create a trigger which makes sure your auto_increment is higher than the auto_increment of your archive table:*

delimiter //
drop trigger if exists trigger_autoinc_tbl;
CREATE TRIGGER trigger_autoinc_tbl BEFORE INSERT ON tbl
FOR EACH ROW
BEGIN
declare auto_incr1 BIGINT;
declare auto_incr2 BIGINT;
SELECT AUTO_INCREMENT INTO auto_incr1 FROM information_schema.TABLES WHERE table_schema=DATABASE() AND table_name='tbl';
SELECT AUTO_INCREMENT INTO auto_incr2 FROM information_schema.TABLES WHERE table_schema=DATABASE() AND table_name='tbl_archiv';
IF (auto_incr2 > auto_incr1 and NEW.id<auto_incr2) THEN
SET NEW.id = auto_incr2;
END IF;
END;//
delimiter ;

OTHER TIPS

According to MySQL manual the counter is only initialised to 1 if the table is empty. Thus you could leave the row with the highest ID in the table forcing MySQL to initialise the counter to the next possible value which is MAX_ID+1.

In order to keep your primary key column type BIGINT, you should generate a unique random number. For example, you can generate it using the following code:

Random random = new Random();
Long id = System.nanoTime() * 1000000 + random.nextLong(1000000L);

You can eliminate the use of System.nanoTime() if you don't want to have ordered primary keys. It can be very handy if you want to have range partitions on it though.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top