Ik kom er net achter dat we een serieus probleem hebben in de relationele integriteit van onze database:
InnoDB "reset" soms de AUTO_INCREMENT! Ik zag dat toen na een ALTER TABLE statement de AUTO_INCREMENT veranderde in SELECT MAX(id) + 1. Ik dacht eerst dat hem om een bug ging, maar het blijkt een feature te zijn:
Het specifieke probleem hoef ik niet eens uit te leggen denk ik. Overal waar je refereert naar tuples op basis van een auto_increment veld zonder foreign key en tuples verwijderd kunnen worden kan het dus zijn dat er twee keer data op dezelfde id komt, en je referentie niet meer klopt.
De reden voor dit topic is niet alleen om jullie bang te maken
, maar ook om te vragen of jullie dit zijn tegen gekomen en om te discussiëren teren wat de mogelijke oplossingen hiervoor zijn. Hier zijn alvast vier alternatieven:
1. Foreign Keys gebruiken
Uiteraard kan dat, en dat lost het probleem ook compleet op. Helaas is het niet overal mogelijk of gewenst. (Zo gebruiken wij een tabel die voor data in meerdere tabellen een centrale audit trail opslaat. Om voor elke tabel een aparte audit trail tabel aan te maken is niet gewenst, (want chaos, en lastig/onmogelijk om aggregate functions te gebruiken))
2. pre-INSERT triggers / constraints?
Ik heb niet gekeken of dit mogelijk is, maar als dit mogelijk is kun je het werk tenminste weer uit handen geven.
3. Op applicatie niveau de juiste id bepalen
Zo zouden wij in de "centrale" audit trail tabel de max id voor een tabel kunnen opvragen, en die + 1 gebruiken voor de volgende INSERT. Zeker geen ideale oplossing, je moet overal extra code schrijven.
4. Een aparte auto_increment tabel bijhouden
Ook dit is een lelijke oplossing eigenlijk, omdat je het werk doet wat je database eigenlijk voor je zou moeten doen.
Oplossingen 1 en 2 zitten in de database, 3 en 4 in de applicatie. Uiteraard is het eerste geprefereerd!
InnoDB "reset" soms de AUTO_INCREMENT! Ik zag dat toen na een ALTER TABLE statement de AUTO_INCREMENT veranderde in SELECT MAX(id) + 1. Ik dacht eerst dat hem om een bug ging, maar het blijkt een feature te zijn:
Ik ben niet de enige die dit onverwachte (en raar) gedrag tegen komt, maar denk op de andere kant ook dat wel meer mensen schrikken als ze dit horen (zo kon ik in de GoT search geen topics hierover vinden!).If you specify an AUTO_INCREMENT column for an InnoDB table, [...] this counter is stored only in main memory, not on disk.
InnoDB uses the following algorithm to initialize the auto-increment counter for a table [..] After a server startup, for the first insert into a table t, InnoDB executes the equivalent of this statement:
SELECT MAX(ai_col) FROM t FOR UPDATE;
Het specifieke probleem hoef ik niet eens uit te leggen denk ik. Overal waar je refereert naar tuples op basis van een auto_increment veld zonder foreign key en tuples verwijderd kunnen worden kan het dus zijn dat er twee keer data op dezelfde id komt, en je referentie niet meer klopt.
De reden voor dit topic is niet alleen om jullie bang te maken
1. Foreign Keys gebruiken
Uiteraard kan dat, en dat lost het probleem ook compleet op. Helaas is het niet overal mogelijk of gewenst. (Zo gebruiken wij een tabel die voor data in meerdere tabellen een centrale audit trail opslaat. Om voor elke tabel een aparte audit trail tabel aan te maken is niet gewenst, (want chaos, en lastig/onmogelijk om aggregate functions te gebruiken))
2. pre-INSERT triggers / constraints?
Ik heb niet gekeken of dit mogelijk is, maar als dit mogelijk is kun je het werk tenminste weer uit handen geven.
3. Op applicatie niveau de juiste id bepalen
Zo zouden wij in de "centrale" audit trail tabel de max id voor een tabel kunnen opvragen, en die + 1 gebruiken voor de volgende INSERT. Zeker geen ideale oplossing, je moet overal extra code schrijven.
4. Een aparte auto_increment tabel bijhouden
Ook dit is een lelijke oplossing eigenlijk, omdat je het werk doet wat je database eigenlijk voor je zou moeten doen.
Oplossingen 1 en 2 zitten in de database, 3 en 4 in de applicatie. Uiteraard is het eerste geprefereerd!
[ Voor 0% gewijzigd door JayVee op 24-10-2008 17:22 . Reden: slechte spelling ]
ASCII stupid question, get a stupid ANSI!