Kom ihåg mig?
Home Menu

Menu


Få MySQL att sluta resetta auto_increment?

 
Ämnesverktyg Visningsalternativ
Oläst 2013-06-02, 20:28 #1
JesperA JesperA är inte uppkopplad
Medlem
 
Reg.datum: Jul 2008
Inlägg: 214
JesperA JesperA är inte uppkopplad
Medlem
 
Reg.datum: Jul 2008
Inlägg: 214
Standard Få MySQL att sluta resetta auto_increment?

Tja!

Stötte på ett problem med MySQL (innodb), detta problemet tog jag för givet att det inte existerade.

Jag har 2st tabeller med liknande struktur och jag använder samma $_POST för att lägga in data i båda tabellerna. Jag använder transaktioner för att säkerhetsställa att datan verkligen läggs in i båda tabellerna, detta fungerar utmärkt.

I tabell 1 har jag ett PostID som är PRIMARY KEY och auto_increment

I tabell 2 har jag också ett PostID som använder "$PostID = $db->lastInsertID();" (i PHP) från ovanstående insert, detta gör ju att PostID bör bli samma i båda tabellerna, vilket det blir.


Problemet är att tabell 1 bara är en temporär tabell vars rader bara existerar i några timmar eller max ett par dagar innan raden tas bort, ibland riskerar den att bli tom, och råkar man då starta om servern just när tabell 1 är tom så defaultar auto_increment ner till 1 igen, detta pajar ju hela consistency grejen mellan dom 2 tabellerna.




Tabell 2 är en arkiverande tabell, jag skulle kunna sätta auto_increment på tabell 2 istället och låta tabell 1 få sitt PostID från tabells 2 "$PostID = $db->lastInsertID();", alltså sätter in i tabell 2 först, och sen i tabell 1.

Men finns ju samma risk där att om jag migrerar tabell 2 vid ett senare tillfälle så kan jag inte garantera någon consistency.


Går det inte få auto_increment att låsa sitt värde oavsett om tabellen blir tömd (alltså inte bara vid truncate utan även när varje rad tas bort 1 och 1 tills tabellen blir tom).
JesperA är inte uppkopplad   Svara med citatSvara med citat
Oläst 2013-06-02, 21:13 #2
Conny Westh Conny Westh är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: Aug 2005
Inlägg: 5 166
Conny Westh Conny Westh är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: Aug 2005
Inlägg: 5 166
En temptabell skapas ju på nytt varje gång så jag skull använda arkiv-tabellens autoincrement som primary copy.
Conny Westh är inte uppkopplad   Svara med citatSvara med citat
Oläst 2013-06-03, 15:39 #3
JesperA JesperA är inte uppkopplad
Medlem
 
Reg.datum: Jul 2008
Inlägg: 214
JesperA JesperA är inte uppkopplad
Medlem
 
Reg.datum: Jul 2008
Inlägg: 214
Jag tror du tänker på en temptabell som skapas tex när man kör subqueries osv, det är inte en sådan tabell jag syftar på, utan jag har en permanent tabell som jag dumpar tillfällig data i.

Iaf, jag kommer ju bli tvungen att köra med tabell 2 som "huvudtabell" nu istället.

Helt sjukt att jag missat detta problemet, har tagit för givet i över 10 år att auto_increment är ett sätt att garantera 100% unikt ID, men det är det ju inte, det går ju bara att garantera på en enskild tabell, inte om man tar ID från en tabell och vill använda som foreign key eller whatever på andra tabeller, ID över flera tabeller kan ju då enbart garanteras om tabellen aldrig blir tom...
JesperA är inte uppkopplad   Svara med citatSvara med citat
Oläst 2013-06-03, 17:57 #4
FredrikMHs avatar
FredrikMH FredrikMH är inte uppkopplad
Supermoderator
 
Reg.datum: Apr 2004
Inlägg: 1 501
FredrikMH FredrikMH är inte uppkopplad
Supermoderator
FredrikMHs avatar
 
Reg.datum: Apr 2004
Inlägg: 1 501
Citat:
Ursprungligen postat av JesperA Visa inlägg
Helt sjukt att jag missat detta problemet, har tagit för givet i över 10 år att auto_increment är ett sätt att garantera 100% unikt ID, men det är det ju inte, det går ju bara att garantera på en enskild tabell, inte om man tar ID från en tabell och vill använda som foreign key eller whatever på andra tabeller, ID över flera tabeller kan ju då enbart garanteras om tabellen aldrig blir tom...
Nej tabellen kan bli tom utan att auto_increment nollställs, men det beror på hur du tömmer tabellen. TRUNCATE kommer återställa auto_increment, men jag tror inte en vanlig DELETE FROM gör det.

Vitsen är ju att om du tar bort data som används som nyckel i andra tabeller så bör du nog även ta bort data där eller fundera på ett annat databasupplägg.
FredrikMH är inte uppkopplad   Svara med citatSvara med citat
Oläst 2013-06-03, 18:07 #5
JesperA JesperA är inte uppkopplad
Medlem
 
Reg.datum: Jul 2008
Inlägg: 214
JesperA JesperA är inte uppkopplad
Medlem
 
Reg.datum: Jul 2008
Inlägg: 214
Citat:
Ursprungligen postat av FredrikMH Visa inlägg
Nej tabellen kan bli tom utan att auto_increment nollställs, men det beror på hur du tömmer tabellen. TRUNCATE kommer återställa auto_increment, men jag tror inte en vanlig DELETE FROM gör det.
Som sagt, auto_increment nollställs om du har tömt raderna en och en, är då tabellen tom när man startar om servern eller mysql service så resettas auto_increment.

Citat:
Ursprungligen postat av FredrikMH Visa inlägg
Vitsen är ju att om du tar bort data som används som nyckel i andra tabeller så bör du nog även ta bort data där eller fundera på ett annat databasupplägg.
Foreign key var bara ett exempel.
JesperA är inte uppkopplad   Svara med citatSvara med citat
Oläst 2013-06-03, 21:06 #6
FredrikMHs avatar
FredrikMH FredrikMH är inte uppkopplad
Supermoderator
 
Reg.datum: Apr 2004
Inlägg: 1 501
FredrikMH FredrikMH är inte uppkopplad
Supermoderator
FredrikMHs avatar
 
Reg.datum: Apr 2004
Inlägg: 1 501
Citat:
Ursprungligen postat av JesperA Visa inlägg
Som sagt, auto_increment nollställs om du har tömt raderna en och en, är då tabellen tom när man startar om servern eller mysql service så resettas auto_increment.
Det stämmer det du säger med InnoDB. För MyISAM stämmer det dock inte, då är auto_increment sparat trots att MySQL service startar om och tabellen är tom.

Är du bunden till InnoDBs funktioner eller skulle MyISAM kunna fungera?
FredrikMH är inte uppkopplad   Svara med citatSvara med citat
Oläst 2013-06-03, 21:53 #7
Conny Westh Conny Westh är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: Aug 2005
Inlägg: 5 166
Conny Westh Conny Westh är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: Aug 2005
Inlägg: 5 166
Stopp och belägg!!!


Skapa först en databas, sen kör du Create enligt nedan med InnoDB....
Kod:
use wn;

delimiter $$

CREATE TABLE `test` (
  `idTest` int(11) NOT NULL AUTO_INCREMENT,
  `Testcol` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`idTest`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1$$

Sen kör du denna kod dvs först rensar hela tabellen Test från alla poster med en vanlig SQL Delete...

Sen lägger du till nya poster med INSERT och sen raderar igen och skapar nya med INSERT så kommer INTE autoincrement att nollställas, tvärtom förtsätter den att öka.

Nedanstående kod kan du köra flera gånger och då kommer hela tiden primärnyckeln att öka från gång till gång, trots att alla poster raderas varje gång....
Kod:
delete from test;
insert into test(testcol) values('a');
insert into test(testcol) values('b');
insert into test(testcol) values('c');
insert into test(testcol) values('d');
insert into test(testcol) values('e');
select * from test;
delete from test;
insert into test(testcol) values('f');
insert into test(testcol) values('g');
insert into test(testcol) values('h');
insert into test(testcol) values('i');
insert into test(testcol) values('j');
insert into test(testcol) values('k');
select * from test;

Senast redigerad av Conny Westh den 2013-06-03 klockan 21:57
Conny Westh är inte uppkopplad   Svara med citatSvara med citat
Oläst 2013-06-03, 22:52 #8
lubic lubic är inte uppkopplad
Medlem
 
Reg.datum: Aug 2005
Inlägg: 205
lubic lubic är inte uppkopplad
Medlem
 
Reg.datum: Aug 2005
Inlägg: 205
Conny: Tror du missade punkten om att servern startas om efter att man har tagit bort raderna. Sen tycker jag iofs det låter märkligt/dumt att autoincrement nollställs vid en omstart? Men så är det kanske tänkt att fungera av någon anledning?

http://dev.mysql.com/doc/refman/5.0/...-handling.html
lubic är inte uppkopplad   Svara med citatSvara med citat
Oläst 2013-06-04, 00:10 #9
Conny Westh Conny Westh är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: Aug 2005
Inlägg: 5 166
Conny Westh Conny Westh är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: Aug 2005
Inlägg: 5 166
Citat:
Ursprungligen postat av lubic Visa inlägg
Conny: Tror du missade punkten om att servern startas om efter att man har tagit bort raderna. Sen tycker jag iofs det låter märkligt/dumt att autoincrement nollställs vid en omstart? Men så är det kanske tänkt att fungera av någon anledning?

http://dev.mysql.com/doc/refman/5.0/...-handling.html
OK, det missade jag.

Då kan man ju faktiskt aldrig använda auto_increment i MySQL.

Man får skapa en egen tabell som håller koll på nästa ID och anropa en SP som ger nästa lediga ID för just den tabellen.
Conny Westh är inte uppkopplad   Svara med citatSvara med citat
Oläst 2013-06-04, 02:12 #10
Conny Westh Conny Westh är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: Aug 2005
Inlägg: 5 166
Conny Westh Conny Westh är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: Aug 2005
Inlägg: 5 166
Hittade följande länk (otestat): http://dev.mysql.com/doc/refman/5.0/...increment.html

Kod:
-- Posted by Thomas Mayer on January 20 2012 3:17pm
-- 
-- 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 ;

-- Further reading: http://www.slicewise.net/index.php?id=82
Conny Westh är inte uppkopplad   Svara med citatSvara med citat
Svara


Aktiva användare som för närvarande tittar på det här ämnet: 1 (0 medlemmar och 1 gäster)
 

Regler för att posta
Du får inte posta nya ämnen
Du får inte posta svar
Du får inte posta bifogade filer
Du får inte redigera dina inlägg

BB-kod är
Smilies är
[IMG]-kod är
HTML-kod är av

Forumhopp


Alla tider är GMT +2. Klockan är nu 23:57.

Programvara från: vBulletin® Version 3.8.2
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Svensk översättning av: Anders Pettersson
 
Copyright © 2017