[MySQL]Auto increment recount

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Tjolk
  • Registratie: Juni 2007
  • Laatst online: 05-07 17:07
Ik gebruik voor mijn Added Notes-systeem een auto-increment waarde voor de id's van de notities die opgeslagen worden. Door de aard van het gebeuren (korte notities die je dus weer regelmatig verwijderd) lopen de waardes van dat veld natuurlijk rap op, zeker als het aantal gebruikers gaat groeien. Op termijn zou dat misschien tot problemen kunnen leiden. Ik zou daarom liefst middels een cronjob iedere nacht een recount willen doen van die waarde: Alle notities opnieuw nummeren vanaf 1.

Nu ken ik natuurlijk de methode om via SQL vast te stellen dat nieuwe id's vanaf een bepaalde waarde moeten starten, maar dat werkt alleen als er geen id's zijn met een hoger nummer. Is er ook een methode waarbij ik eenvoudig en efficient (vooral dat laatste) een recount kan doen dat alle id's van een vers nummer voorziet?

Tjolk is lekker. overal en altijd.


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Je gaat pas in de problemen komen ( met een 32-bits id ) als je meer dan 4 miljard records hebt. Dus je bent wel even bezig voordat je tegen die problemen aan loopt.

Als je nu al voorziet dat dat toch een probleem gaat vormen kun je IMHO beter gewoon een 64 bits ID nemen, waardoor je zeker niet meer in de problemen gaat komen.

Het opnieuw berekenen van je PK is gewoon geen goed idee. Je gaat daarmee geheid in de problemen komen, omdat je alle verwijzingen ernaartoe dus ook aan moet passen.

Dat is ook meteen de reden dat je eigenlijk geen PK wilt hebben die enige betekenis heeft. Als die gegevens immers veranderen dan loop je tegen allerlei problemen aan om die te veranderen.

[ Voor 27% gewijzigd door Woy op 16-06-2009 11:15 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • TeeDee
  • Registratie: Februari 2001
  • Laatst online: 05-07 17:18

TeeDee

CQB 241

Als ze toch niet relevant zijn, waarom gebruik je dan überhaupt een AutoIncrement.

Verder, zoals Woy zegt, is het gewoon geen goed idee.

[ Voor 25% gewijzigd door TeeDee op 16-06-2009 11:14 ]

Heart..pumps blood.Has nothing to do with emotion! Bored


Acties:
  • 0 Henk 'm!

  • vandeGerrit
  • Registratie: Januari 2009
  • Laatst online: 01-07 12:18

vandeGerrit

Well, this can't be right

Denk hierbij ook aan alle andere relaties die je hebt. Ook deze moeten gewijzigd worden. Dit is dus niet echt verstandig. Als dit een probleem wordt, kun je ook is denken aan andere sleutels op je tabel. Gewoon de tijd bijvoorbeeld.

[ Voor 7% gewijzigd door vandeGerrit op 16-06-2009 11:16 ]


Acties:
  • 0 Henk 'm!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

Niet dat dit direct je vraag beantwoordt, maar hoeveel gebruikers verwacht jij? Als je ID een unsigned int is heb je 4.294.967.295 mogelijke ID's uit te delen voor je in de problemen komt. Dat is als zeg maar iedere Nederlander (op dit moment zo'n 16.516.723) zo'n 260 notities aanmaakt. Tegen de tijd dat dat gebeurt heb je denk ik andere problemen dan een tellertje dat overloopt.

Meer ontopic, ik ben van mening dat je ID's niet moet (willen) veranderen. Een ID is, zoals de naam al zegt, een identifier. Wat als de gebruiker linkt naar notitie 315, en de volgende dag mag 'ie die ineens niet meer lezen?

https://oneerlijkewoz.nl
Het ergste moet nog komen / Het leven is een straf / Een uitgestrekte kwelling van de wieg tot aan het graf


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
TeeDee schreef op dinsdag 16 juni 2009 @ 11:14:
Als ze toch niet relevant zijn, waarom gebruik je dan überhaupt een AutoIncrement
Juist andersom, puur omdat het niet boeit kan je een triviale oplopende nummering (met gaten, lekker boeiend) hanteren.

Allemaal extra logica rondom synthetic keys: zonde van je tijd.

[ Voor 9% gewijzigd door Voutloos op 16-06-2009 11:20 ]

{signature}


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
CodeCaster schreef op dinsdag 16 juni 2009 @ 11:19:
Niet dat dit direct je vraag beantwoordt, maar hoeveel gebruikers verwacht jij? Als je ID een unsigned int is heb je 4.294.967.295 mogelijke ID's uit te delen voor je in de problemen komt. Dat is als zeg maar iedere Nederlander (op dit moment zo'n 16.516.723) zo'n 260 notities aanmaakt. Tegen de tijd dat dat gebeurt heb je denk ik andere problemen dan een tellertje dat overloopt.
En dan nog kun je zoals ik hierboven al zeg gewoon nog een 64 bits id gebruiken. Om het in hetzelfde perspectief te zetten, dan kunnen alle 6 miljard mensen op deze aarde meer dan 3 miljard notes plaatsen voordat je in de problemen komt.

Dus dan hoef je helemaal niet meer bang te zijn voor problemen, want ik acht de kans groot dat je systeem tegen die tijd niet meer gebruikt word ;)

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • Crazybest
  • Registratie: Januari 2002
  • Laatst online: 15-01-2023
GUID?

Acties:
  • 0 Henk 'm!

  • TeeDee
  • Registratie: Februari 2001
  • Laatst online: 05-07 17:18

TeeDee

CQB 241

Voutloos schreef op dinsdag 16 juni 2009 @ 11:19:
[...]
Juist andersom, puur omdat het niet boeit kan je een triviale oplopende nummering (met gaten, lekker boeiend) hanteren.

Allemaal extra logica rondom synthetic keys: zonde van je tijd.
Kan ook :Y)

Heart..pumps blood.Has nothing to do with emotion! Bored


Acties:
  • 0 Henk 'm!

Anoniem: 295631

offtopic:
Dat introduceert wel wat aandachtspunten ivm performance van de clustered index die standaard voor een PK wordt gemaakt.

[ Voor 4% gewijzigd door Anoniem: 295631 op 16-06-2009 11:39 . Reden: ff offtopic gemaakt... ]


Acties:
  • 0 Henk 'm!

  • Crazybest
  • Registratie: Januari 2002
  • Laatst online: 15-01-2023
Anoniem: 295631 schreef op dinsdag 16 juni 2009 @ 11:39:
[...]

offtopic:
Dat introduceert wel wat aandachtspunten ivm performance van de clustered index die standaard voor een PK wordt gemaakt.
tja, daar tegenop kun je erop aan dat je nooit je id hoeft te wijzigen en dus nooit referenties cascading moet onderhouden. Hoeveel performance winst levert dat?
Je kunt page-fill ratio van de db wellicht wat lager zetten zodat bij inserts van nieuwe ID's die tussen 2 bestaande ID's valt wel past op de page. zodat je niet zo vaak een page-split en daarmee je index moet onderhouden, zoals jij als penalty opgeeft.

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Crazybest schreef op dinsdag 16 juni 2009 @ 11:46:
[...]


tja, daar tegenop kun je erop aan dat je nooit je id hoeft te wijzigen en dus nooit referenties cascading moet onderhouden. Hoeveel performance winst levert dat?
Je kunt page-fill ratio van de db wellicht wat lager zetten zodat bij inserts van nieuwe ID's die tussen 2 bestaande ID's valt wel past op de page. zodat je niet zo vaak een page-split en daarmee je index moet onderhouden, zoals jij als penalty opgeeft.
Tja een guid is in feite gewoon een random 128-bits getal, en met een 64 bits oplopend getal is je probleem ook al opgelost.

En bovendien zul je toch zowiezo al moeten kijken of je een clustered index op je PK nodig hebt, of dat die beter op een ander veld kan zitten.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • Crazybest
  • Registratie: Januari 2002
  • Laatst online: 15-01-2023
Woy schreef op dinsdag 16 juni 2009 @ 11:53:
[...]

Tja een guid is in feite gewoon een random 128-bits getal, en met een 64 bits oplopend getal is je probleem ook al opgelost.

En bovendien zul je toch zowiezo al moeten kijken of je een clustered index op je PK nodig hebt, of dat die beter op een ander veld kan zitten.
zowel voor crud acties vanuit een gridview als voor andere indexes is een Unique-ID gunstig.

andere indexes zullen (bij sql server althans) hun index leggen op de pk van de clusterindex (en niet op de gehele row). En aangezien die nooit hoef te wijzigen, zal de 'andere index' dus ook nooit zijn referentie aan te passen.

Maar uiteraard is het wel handig dat je die andere indexes maakt als je wilt zoeken op andere waarden dan de ID :)

Acties:
  • 0 Henk 'm!

Anoniem: 13701

Ik denk eigenlijk niet dat er een command is om te hernummeren, wat natuurlijk wel gaat werken is kopieren naar tijdelijke tabel, originele tabel legen, tijdelijk tabel alle records opnieuw invoegen in orieineel. Je bent alleen je referenties kwijt.

Wil je echt zonder verlies van referenties alles hernummeren, dan krijg je volgens mij echt een hele smerige query die elk record update naar een nieuw id, met een eigen count o.i.d. Performance technisch gesproken wil je dat niet doen, helemaal niet op een tabel waar zoveel records in moeten komen dat hernummering relevant is.

Zoals bovenstaand ook vermeldt, 2^32 id's niet genoeg? Persoonlijk denk ik dat je sowieso dan performance problemen gaat krijgen, ongeacht of je genoeg id's hebt. Voor de rest zou ik niet zoveel waarde hechten aan een auto_increment id, het gedrag ervan kan je toch niet beinvloeden. Als je meer wilt dan alleen een vanzelf ophogende getalletje, dan denk dat je zelf moet gaan programmeren.

Acties:
  • 0 Henk 'm!

  • ValHallASW
  • Registratie: Februari 2003
  • Niet online
Het idee van GUID's gebruiken als ID in een database 'omdat ze gegarandeerd uniek zijn' ben ik in de .NET-wereld vaker tegengekomen. Snappen mensen werkelijk niet dat de kans op collisions bij een oplopende counter 0 is en bij GUID's dus automatisch oneindig veel groter...?

Acties:
  • 0 Henk 'm!

  • Xiphalon
  • Registratie: Juni 2001
  • Laatst online: 04-07 16:29
Het voordeel van GUIDs waar ik het meeste lol van heb is het feit dat de sleutels door de applicatie zelf gegenereerd kunnen worden, onafhankelijk van de database. Hierdoor kunnen meerdere (instanties van) applicaties zonder veel problemen nieuwe records aanmaken, zonder dat de (met name geclusterde) databases een contentie krijgen op het sleutelgenereren.
Verder hebben levende objecten in de applicatie altijd sleutels, zonder dat ik daarvoor eerst naar de database moet.

Acties:
  • 0 Henk 'm!

  • Crazybest
  • Registratie: Januari 2002
  • Laatst online: 15-01-2023
ValHallASW schreef op dinsdag 16 juni 2009 @ 12:17:
[...]

Het idee van GUID's gebruiken als ID in een database 'omdat ze gegarandeerd uniek zijn' ben ik in de .NET-wereld vaker tegengekomen. Snappen mensen werkelijk niet dat de kans op collisions bij een oplopende counter 0 is en bij GUID's dus automatisch oneindig veel groter...?
APP A haalt DB op (online)
APP B haalt DB op (online)
APP A en APP B voegen een record toe (offline)
APP A update de mutaties naar de DB (online), succesvol
APP B update de mutaties naar de DB, error ID already exist

snappi?

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
ValHallASW schreef op dinsdag 16 juni 2009 @ 12:17:
[...]

Het idee van GUID's gebruiken als ID in een database 'omdat ze gegarandeerd uniek zijn' ben ik in de .NET-wereld vaker tegengekomen. Snappen mensen werkelijk niet dat de kans op collisions bij een oplopende counter 0 is en bij GUID's dus automatisch oneindig veel groter...?
Daar heb je wel gelijk in, maar de kans op een collission is nog steeds (bijna) verwaarloosbaar klein. Ik kan wel systemen bedenken waarbij het gebruik van een GUID voordelen bied.
Crazybest schreef op dinsdag 16 juni 2009 @ 12:44:
[...]
APP A haalt DB op (online)
APP B haalt DB op (online)
APP A en APP B voegen een record toe (offline)
APP A update de mutaties naar de DB (online), succesvol
APP B update de mutaties naar de DB, error ID already exist

snappi?
Maar die situatie is hier helemaal ( athans daar heeft de TS niks over gezegd ) aan de orde.

De claim van ValHallASW is gewoon valide zolang het RDBMS de controle over de generatie van de keys heeft.
ValHallASW schreef op dinsdag 16 juni 2009 @ 12:17:
Snappen mensen werkelijk niet dat de kans op collisions bij een oplopende counter 0 is en bij GUID's dus automatisch oneindig veel groter...?

[ Voor 41% gewijzigd door Woy op 16-06-2009 12:48 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • Crazybest
  • Registratie: Januari 2002
  • Laatst online: 15-01-2023
zijn claim is valide in deze situatie. true.
mijn verhaal ging over de bigger picture.

Maar als dit topic ALLEEN gaat over de vraagstelling van de topicstarter. Waarom grijp je dan niet eerder in over de discussies van referenties (fk), indexes en collisions.

At topic:
ik weet niet welke method waarmee je gaten in je ID's kunt rearrangen zonder gaten tussen de ID's

(Onze vraag is, zou je dat moeten willen)

Acties:
  • 0 Henk 'm!

  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

Woy schreef op dinsdag 16 juni 2009 @ 11:13:
Het opnieuw berekenen van je PK is gewoon geen goed idee. Je gaat daarmee geheid in de problemen komen, omdat je alle verwijzingen ernaartoe dus ook aan moet passen.
Dat is een kwestie van ON UPDATE CASCADE triggers.
ValHallASW schreef op dinsdag 16 juni 2009 @ 12:17:
Het idee van GUID's gebruiken als ID in een database 'omdat ze gegarandeerd uniek zijn' ben ik in de .NET-wereld vaker tegengekomen. Snappen mensen werkelijk niet dat de kans op collisions bij een oplopende counter 0 is en bij GUID's dus automatisch oneindig veel groter...?
Snappen mensen wekelijk niet dat de kans op collisions nog steeds astronomisch klein is? "Oneindig veel groter" is een onzinnige uitspraak... als jij blut bent, heb ik volgens die redenering oneindg veel meer geld dan jij... maar daar wordt ik niet rijker van. Delen door 0 is .... ?

Wie trösten wir uns, die Mörder aller Mörder?


Acties:
  • 0 Henk 'm!

  • Crazybest
  • Registratie: Januari 2002
  • Laatst online: 15-01-2023
error :)

Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Confusion schreef op dinsdag 16 juni 2009 @ 13:01:
[...]
Dat is een kwestie van ON UPDATE CASCADE triggers
WTF. Nee, dat is een kwestie van synthetische keys lekker met rust laten. :X

Er is hier nog altijd geen reden gegeven waarom auto inc. niet volstaat voor het huidige gebruik. En er is nog altijd ook geen reden gegeven waarom er hernummerd moet worden. Zonder onderbouwing is er geen probleem, case closed, okedag.

{signature}


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 03-07 11:38

Janoz

Moderator Devschuur®

!litemod

@Confusion:

Sorry, maar wat je zegt is onzin. Het punt is dat een GUID meer kans heeft op een collision dan een oplopende counter. Het is dus onzin om voor een GUID te kiezen 'omdat hij gegarandeerd uniek zou zijn'.

Sowieso is het hele GUID een noodoplossing voor wanneer alle andere mogelijkheden niet toepasbaar zijn. Helaas zijn er genoeg volgzame schaapjes die die andere mogelijkheden maar helemaal niet gaan overwegen 'omdat het zo in de msdn staat'.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • cariolive23
  • Registratie: Januari 2007
  • Laatst online: 18-10-2024
SFB schreef op dinsdag 16 juni 2009 @ 11:08:
Ik gebruik voor mijn Added Notes-systeem een auto-increment waarde voor de id's van de notities die opgeslagen worden. Door de aard van het gebeuren (korte notities die je dus weer regelmatig verwijderd) lopen de waardes van dat veld natuurlijk rap op, zeker als het aantal gebruikers gaat groeien. Op termijn zou dat misschien tot problemen kunnen leiden.
Klopt, in theorie zou je inderdaad in de problemen kunnen lopen. Alleen niet meer tijdens dit leven, hooguit in een volgend leven. En wie dan leeft, die dan zorgt. Ja toch?

4.000.000.000 records wanneer je een integer gebruikt. (BIGINT zal ik het maar niet over hebben, getal is niet uit te spreken)
Wanneer je dan 1 record per seconde aanmaakt, 24 uur per dag, 365 dagen per jaar, ben je (als ik het goed heb) ruim 126 jaar verder voordat je in de problemen komt. Zelfs al zou je over 10 jaar in de problemen komen, dan is dat nu nog steeds geen probleem. In dat geval kun je dus ongeveer 1 miljoen records per dag aanmaken.... En hoeveel notes maak je nu per dag?

Don't worry, be happy :+

Acties:
  • 0 Henk 'm!

  • Crazybest
  • Registratie: Januari 2002
  • Laatst online: 15-01-2023
bekeken van de vraagstelling.

zou het mogelijk zijn dat je in de front-end graag een genummerd notitielijstje krijgt.

- Genereer het vanuit de frontend met een foreach of gridview property.
- Genereer het vanuit de database: SELECT row_number() over ( ORDER BY [colum_name]), * FROM [table_name]

Acties:
  • 0 Henk 'm!

  • Tjolk
  • Registratie: Juni 2007
  • Laatst online: 05-07 17:07
Bedankt voor alle reacties!

Dat het in de miljarden zou lopen voordat ik in de problemen kom, dat had ik niet verwacht. Ik dacht aan de ordegrootte van honderduizend (nog steeds enorm veel, true). Het probleem is er dus inderdaad praktisch gezien niet.

Het advies "don't worry, be happy" van cariolive23 zal ik dus maar ter harte nemen. :)

Overigens zijn er geen referenties naar het id. Het word wel gebruikt in wat $_GET requests, maar alleen als je aangeeft dat je een bepaalde notitie wil bewerken, printen, mailen, etc. Eenrichtingverkeer dus.

Tjolk is lekker. overal en altijd.


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Crazybest schreef op dinsdag 16 juni 2009 @ 12:56:
zijn claim is valide in deze situatie. true.
mijn verhaal ging over de bigger picture.

Maar als dit topic ALLEEN gaat over de vraagstelling van de topicstarter. Waarom grijp je dan niet eerder in over de discussies van referenties (fk), indexes en collisions.
Tja als je het over "The bigger picture" wil hebben, is daar niks mis mee. Echter post je alleen
Als je er bij verteld waarom je daar voor zou kiezen is er niks mis mee, maar op deze manier voegt het niet echt veel toe.

Verder is het maar een kleine stap van het probleem wat de TS naar FK's waarmee je in de problemen gaat komen, en al een stuk grotere stap naar distibuted systemen die met kopieen van de database werken.

Ik heb ook niemand in het topic horen beweren dat je nooit GUID's moet gebruiken. Maar waarom zou je het risico ( al is het zoals ik eerder al zei verwaarloosbaar klein ) op een conflict introduceren als dat totaal niet nodig is.
Confusion schreef op dinsdag 16 juni 2009 @ 13:01:
[...]
Snappen mensen wekelijk niet dat de kans op collisions nog steeds astronomisch klein is? "Oneindig veel groter" is een onzinnige uitspraak... als jij blut bent, heb ik volgens die redenering oneindg veel meer geld dan jij... maar daar wordt ik niet rijker van. Delen door 0 is .... ?
Ja het risico is astronomisch klein, maar waarom zou je het risico introduceren als het totaal niet nodig is.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04-07 17:03

.oisyn

Moderator Devschuur®

Demotivational Speaker

Confusion schreef op dinsdag 16 juni 2009 @ 13:01:
Snappen mensen wekelijk niet dat de kans op collisions nog steeds astronomisch klein is? "Oneindig veel groter" is een onzinnige uitspraak... als jij blut bent, heb ik volgens die redenering oneindg veel meer geld dan jij... maar daar wordt ik niet rijker van. Delen door 0 is .... ?
Mensen die GUIDs gebuiken gaan er altijd maar gewoon vanuit dat ze uniek zijn. Ik vraag me af hoe bruikbaar dergelijke systemen nog zijn op het moment dat er daadwerkelijk een collision optreedt. Ik geloof niet dat er iemand überhaupt rekening mee houdt.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

Voutloos schreef op dinsdag 16 juni 2009 @ 13:05:
[...]
WTF. Nee, dat is een kwestie van synthetische keys lekker met rust laten. :X
Not an option, als het probleem is dat je over de 4 miljard heen gaat. Overigens gaf ik gewoon een oplossing voor het probleem dat Woy signaleerde.
Er is hier nog altijd geen reden gegeven waarom auto inc. niet volstaat voor het huidige gebruik. En er is nog altijd ook geen reden gegeven waarom er hernummerd moet worden.
Daar is een prima reden voor gegeven: het geval dat je auto inc. over de 4 miljard records heengaat. Handig voor de topicstarter dat blijkt dat hij niet tegen dat probleem aan gaat lopen, maar dat betekent niet dat het geen probleem is waar mensen in de praktijk tegenaan lopen.
Janoz schreef op dinsdag 16 juni 2009 @ 13:11:
@Confusion:

Sorry, maar wat je zegt is onzin.
Welke van de dingen die ik zei is onzin: dat de kans op een GUID collision astronomisch klein is of dat de vergelijking van ValHallASW geen goed argument was? Ik zeg toch niks om gebruik van GUID's als synthetische PK te stimuleren? Tenzij je het weerleggen van een slecht tegenargument een argument voor het gebruik ergens van noemt.
.oisyn schreef op dinsdag 16 juni 2009 @ 13:50:
Mensen die GUIDs gebuiken gaan er altijd maar gewoon vanuit dat ze uniek zijn. Ik vraag me af hoe bruikbaar dergelijke systemen nog zijn op het moment dat er daadwerkelijk een collision optreedt. Ik geloof niet dat er iemand überhaupt rekening mee houdt.
Als er bij deze toepassing een collision optreedt, dan faalt je insert. Het goed transactioneel afhandelen van dat falen is toch al vereist. Overigens is de kans groter dat je server door een meteoriet wordt geraakt.

[ Voor 46% gewijzigd door Confusion op 16-06-2009 15:01 ]

Wie trösten wir uns, die Mörder aller Mörder?


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Confusion schreef op dinsdag 16 juni 2009 @ 14:48:
[...]
Not an option, als het probleem is dat je over de 4 miljard heen gaat.
Dan reserveer je tzt wat extra bitjes. :z Het echte probleem is dan* het aantal mogelijke waarden, een beetje lafjes hernummeren zal geen orde van grootte schelen maar slechts uitstel zijn.

*: In dat geval, hier niet van toepassing, net als in 9 vd 10 apps. Dus offtopic en daarom laat ik het hierbij. Ik heb het al een paar keer gezegd, maar als je met slechte beargumentering dit soort extra logica tegen synthetisch geneuzel aan gooit heb je echt totaal geen benul van waar je mee bezig bent. GUIDs hebben uiteraard wel hun toepassing, maar hier allemaal 100% offtopic.

{signature}


Acties:
  • 0 Henk 'm!

  • cariolive23
  • Registratie: Januari 2007
  • Laatst online: 18-10-2024
Confusion schreef op dinsdag 16 juni 2009 @ 14:48:
[...]

Not an option, als het probleem is dat je over de 4 miljard heen gaat.
Precies, dan gebruik je een BIGINT als datatype en kun je zomaar nog 10.000 jaar doorwerken zonder dat je in de problemen kunt komen.

En mocht je toch na een jaar of 5.000 de problemen zien aankomen, verkoop de applicatie dan voor veel geld (het is blijkbaar een heel groot succes), dan ben jij in elk geval van het probleem verlost.

Waar hebben we het over? Theorie en praktijk liggen hier wel heel ver uitelkaar.

Acties:
  • 0 Henk 'm!

  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

Voutloos schreef op dinsdag 16 juni 2009 @ 15:00:
[...]
Dan reserveer je tzt wat extra bitjes. :z
Mee eens, meestal is overstappen op een 64 bit int de beste oplossing.
cariolive23 schreef op dinsdag 16 juni 2009 @ 15:07:
Waar hebben we het over? Theorie en praktijk liggen hier wel heel ver uitelkaar.
Als je daadwerkelijk een miljard records hebt, dan is het verschil tussen een 32 bits int en een 64 bits int zo'n 4 GB schijfruimte voor de opslag zelf, maar bovendien een forse vergroting van je index. Daar kon je weleens heel erg niet blij van worden. Als je een miljard records hebt, waarvan je elke dag de helft vervangt, dan kan het weleens fijner zijn om elke paar dagen het overgebleven deel om te nummeren. Om maar een zijstraat te noemen.

[ Voor 58% gewijzigd door Confusion op 16-06-2009 15:10 ]

Wie trösten wir uns, die Mörder aller Mörder?


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04-07 17:03

.oisyn

Moderator Devschuur®

Demotivational Speaker

Confusion schreef op dinsdag 16 juni 2009 @ 14:48:
Als er bij deze toepassing een collision optreedt, dan faalt je insert.
Als je hele systeem van GUIDs gebruik maakt zodat hij al ID's weet voordat ze in de database staan, dan heb je een groter probleem dan alleen een falende insert, aangezien dat id dus al als virtuele FK wordt gebruikt in allerlei andere levende objecten.
Overigens is de kans groter dat je server door een meteoriet wordt geraakt.
Als je er vanuit gaat dat de GUID generator perfect uniform gedistribueerd is ja.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 03-07 11:38

Janoz

Moderator Devschuur®

!litemod

Confusion schreef op dinsdag 16 juni 2009 @ 14:48:
Welke van de dingen die ik zei is onzin: dat de kans op een GUID collision astronomisch klein is of dat de vergelijking van ValHallASW geen goed argument was? Ik zeg toch niks om gebruik van GUID's als synthetische PK te stimuleren? Tenzij je het weerleggen van een slecht tegenargument een argument voor het gebruik ergens van noemt.
Het is onzinnig om op een valide verhaal te reageren met 'snap je niet hoe klein die kans is'. Murphy's law? Hoe klein die kans ook is, waarom zou je hem nemen wanneer je met dezelfde moeite een kans van 0* kunt hebben?

Ik heb al een keer in het wild een conflict gezien bij random gegenereerde keys.



* goed, niet helemaal nul. De kans op een collission is 1 bij insert 232+1, maar die kun je keurig aan zien komen. Wanneer de collision bij een GUID optreed is compleet random.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

Janoz schreef op dinsdag 16 juni 2009 @ 16:23:
Het is onzinnig om op een valide verhaal te reageren met 'snap je niet hoe klein die kans is'. Murphy's law? Hoe klein die kans ook is, waarom zou je hem nemen wanneer je met dezelfde moeite een kans van 0* kunt hebben?

Ik heb al een keer in het wild een conflict gezien bij random gegenereerde keys.
Gezien de manier waarop de meeste mensen en DBMS'en met sequences omgaan, denk ik dat GUID's minder kans op een collision geven. In SQL Server 2003 is het ronduit moeilijk om te garanderen dat twee transacties niet hetzelfde 'nieuwe' id toegewezen krijgen; dat het vrijwel altijd goed gaat is meer geluk dan wijsheid.

Om even een collega te citeren
Ik wil jullie dit even niet onthouden, omdat het mij net enkele uren
> heeft gekost om e.e.a. uit te vinden. Uiteraard ben ik weer eens heel
> erg _NIET_BLIJ_ met de software^Hrotzooi van ome Bill...
>
> MS-SQL kent identity columns, dat is handig om je database nummertjes
> uit te laten delen. Tot zover geen klachten, dat werkt geloof ik wel.
>
> Maar als je database een nummer uitdeelt, wil je die vaak ook daarna nog
> direct kunnen gebruiken, bijvoorbeeld in je applicatie. MS SQL server
> kent drie manieren om zoeits te pakken te krijgen:
>
>
> SELECT @@IDENTITY
> is zelfs gedocumenteerd als brak en onbruikbaar, omdat die bijvoorbeeld
> de ID van een trigger teruggeeft.
>
> SELECT IDENT_CURRENT("tablename")
> werkt mogelijk... Alleen negeert deze functie elke vorm van scheiding
> (werkt over "any session, any scope", wat dus ook transacties betekent).
> Met meerdere parallelle transacties krijgen dus vrolijk de laatste ID
> van iedere mogelijke transactie. Je transaction isolation level heeft
> hier geen enkele invloed op. Hoewel dit dus een vorm is die je vrijwel
> overal tegekomt als "de juiste manier", werkt dit dus eigenlijk alleen
> als je maar 1 applicatie connectie hebt.
>
>
> SELECT SCOPE_IDENTITY()
> werkt mogelijk... Dit geeft de ID terug, maar dan zonder verwarring met
> triggers e.d. Deze is beperkt tot de huidige sessie en scope. Dit lijkt
> dus de gewenste methode, maar...
>
> Ook hier zit een heel groot nest adders onder het gras. Als je deze
> namelijk vanuit JDBC uitvoert op de naieve manier (twee statements,
> eerst de insert, dan select scope_identity()) krijg je altijd 0 terug.
>
> De scope is in SQL-server namelijk de functie, procedure of batch. Dus
> niet je transactie, wat je wil. Een batch is natuurlijk weer een mooi MS
> verzinsel. Als je twee JDBC statements uitvoert na elkaar, dan zijn dit
> blijkbaar andere "batches". Je moet dit dus als 1 "batch" zien te doen.
>
> Je kan het in 1 statement krijgen:
>
> INSERT INTO tablename (column) values (value) select scope_identity();
>
> Juist, let op: geen puntkomma na de insert, direct de select erachter!
> In dit geval levert scope_identity wel je nieuwe auto-identity key op.
> Als je dus denkt deze met SQL direct in een andere column te kunnen
> gebruiken, kan je dat dus ook vergeten, je zal deze nu dus eerst in je
> applicatie moeten inlezen, en daar aan je volgende gerelateerde insert
> moeten binden.
>
> Ronduit heel erg ZIEK! Maar goed, dat zijn we wel gewend van de prutsers
> uit Redmond... Wellicht heeft iemand nog eens iets aan deze post.
>
En als je denkt dat MySql beter is: guess again.

Wie trösten wir uns, die Mörder aller Mörder?


Acties:
  • 0 Henk 'm!

  • cariolive23
  • Registratie: Januari 2007
  • Laatst online: 18-10-2024
Confusion schreef op dinsdag 16 juni 2009 @ 20:47:
In SQL Server 2003 is het ronduit moeilijk om te garanderen dat twee transacties niet hetzelfde 'nieuwe' id toegewezen krijgen; dat het vrijwel altijd goed gaat is meer geluk dan wijsheid.
Ik ken SQL Server niet goed genoeg om daar een mening over te hebben, maar in PostgreSQL is het onmogelijk om met een sequence (of serial) 2x hetzelfde nummer uit te delen, dat is echt waterdicht.

Het gaat zelfs zover dat je met een ROLLBACK niet de sequence terugzet, die kan alleen maar doortellen. De achterliggende reden hiervoor is het MVCC-model. Ook een afgekeurde INSERT (met dank aan de rollback) staat wel in de database, je ziet hem alleen niet. Daarnaast wilde men absoluut zeker weten dat er geen dubbele nummers worden uitgedeeld, ook niet wanneer je met 1000 concurrent users een uniek nummer op gaat vragen.
En als je denkt dat MySql beter is: guess again.
:+

Acties:
  • 0 Henk 'm!

  • RobertMe
  • Registratie: Maart 2009
  • Laatst online: 22:44
Dan ben ik benieuwd hoe het met andere db's zit, dat MS SQL bagger is weet ik uit eigen ervaring (en heb er niet veel mee gedaan), dat MySQL bagger is, is zo ongeveer basis kennis voor elke programmeur/database gebruiker.

Ik meen dat bijv. postgresql met sequences deze altijd uniek genereerd, onafhankelijk van transactie e.d., en dat het ophalen van het laatste id, op de sessie zit, maar is dit dan connectie, of is een transactie ook een sessie? (wat ook een optie is is van tevoren een id genereren/opvragen, en die vervolgens zelf aan de insert geven, dan voorkom je problemen met naderhand opvragen, en of dat over alle transacties/connecties/... gaat)
Bij het ophalen van een nieuwe waarde in een transactie, die vervolgens een rollback krijgt, doet dit op de sequence niks, die trekt zich niks van de transactie aan.

Bij oracle heb ik gezien, dat deze bij sequences rechtstreeks op een tabel een trigger aanmaakt, die onvoorwaardelijk :NEW.<sequence kolom> doet overschrijven, dus daar kun je zelf geen waarde in doen (omdat de trigger hem weer overschrijft), tenzij je de trigger doet overschrijven/aanpassen (if is null, dan sequence ophalen), of de trigger weg haalt en voor een NOT NULL DEFAULT of handmatig ophalen + toewijzen doet. Maar hoe die nieuwe waarde word gegenereerd met tegelijktijdig opvragen, wat je terug krijgt als je de laatste opvraagd, en hoe deze reageerd op een rollback van de transactie waar die in staat, weet ik weer niet.

Dus misschien kan iemand aangeven hoe "veilig" andere databases zijn op dit gebied, PostgreSQL lijkt mij veilig, maar hoe zit het bijvoorbeeld met Oracle.

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
RobertMe schreef op dinsdag 16 juni 2009 @ 21:30:
wat ook een optie is is van tevoren een id genereren/opvragen, en die vervolgens zelf aan de insert geven, dan voorkom je problemen met naderhand opvragen, en of dat over alle transacties/connecties/... gaat
1 Tip, pas heel erg op met zelfbrouwsels, of vertrouw op de dbase, of gebruik een GUID.

De kans dat je in een zelfbrouwsel een nog groter probleem introduceert is veel en veel groter dan dat een "proven" technology de fout ingaat.

Simpel voorbeeldje wat ik laatst zag : iemand gebruikte een combinatie van computernaam / loginnaam / timestamp om iets uniek te maken. App heeft 5 jaar perfect gedraaid in een intern netwerk. Toen werd er besloten om de app ook via internet voor andere partijen ( enkele 1000'en wereldwijd inclusief consumenten ) beschikbaar te maken. Toen kwamen de problemen naar boven, uiteindelijk bleek computernaam / loginnaam ( admin was veelgebruikt bij consumenten ) bij lange na niet uniek te zijn in de wereld en de app grotendeels te rusten op de timestamp...
Alleen kostte dit achterhalen wel enkele weken ( iedereen focuste zich op de inet code, de rest werkte namelijk al 5 jaar )
Laat ik het maar houden op dat dit een duur foutje was...

Acties:
  • 0 Henk 'm!

  • cariolive23
  • Registratie: Januari 2007
  • Laatst online: 18-10-2024
@Gomez12: In PostgreSQL (en andere databases die een sequence gebruiken) kun je prima vooraf een nieuw nummer opvragen bij de nummergenerator, daar is niets mis mee. Dit valt niet in de categorie "zelfbrouwsel", eerder in de categorie RTFM... ;)

SQL:
1
SELECT NEXTVAL('naam_van_de_sequence') AS new_id;


http://www.postgresql.org...e/functions-sequence.html

Acties:
  • 0 Henk 'm!

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 05-07 18:08

Creepy

Tactical Espionage Splatterer

Dat werkt overigens op dezelfde manier als in Oracle. Als je de sequence opvraagt zorgt de database dat dit gelijk wordt opgehoogt en er dus geen dubbele sequences worden uitgegeven.

Dat zelfs SELECT SCOPE_IDENTITY() faalt in MS SQL server verbaasd me eerlijk gezegd. Als ik het verhaal zo lees lijkt het eerder op een bug in JDBC dan in MS SQL. Het is dat ik geen MS SQl bij de hand heb hier want ik het het graag even getest. Buiten JDBC om heb ik regelmatig de SCOPE_IDENTITY gebruikt (ook via losse queries binnen dezelfde transactie).

Het commantaar dat je dan eerst de waarde op moet vragen en daarna moet binden voordat je er wat mee kan doen snap ik niet. Lijkt me niet meer dan normaal.

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Het is ook gewoon een probleem in de JDBC drivers ( Er valt nog te twisten of dat door een design beslissing van MS SQL komt ). Volgens mij zou het met http://java.sun.com/j2se/...t.html#getGeneratedKeys() wel goed moeten gaan.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

Creepy schreef op woensdag 17 juni 2009 @ 10:53:
Dat zelfs SELECT SCOPE_IDENTITY() faalt in MS SQL server verbaasd me eerlijk gezegd. Als ik het verhaal zo lees lijkt het eerder op een bug in JDBC dan in MS SQL. Het is dat ik geen MS SQl bij de hand heb hier want ik het het graag even getest. Buiten JDBC om heb ik regelmatig de SCOPE_IDENTITY gebruikt (ook via losse queries binnen dezelfde transactie).
Het zou een JDBC bug kunnen zijn, maar dat neemt niet weg dat er in ieder geval twee manieren zijn om een identity op te halen die ongetwijfeld veel gebruikt worden, terwijl ze niet goed werken en nooit hadden moeten bestaan.
Het commantaar dat je dan eerst de waarde op moet vragen en daarna moet binden voordat je er wat mee kan doen snap ik niet. Lijkt me niet meer dan normaal.
Als je de string "select scope_identity()" rechtstreeks in een volgende query in dezelfde transactie zou gebruiken, dan hoef je die waarde niet eerst op te vragen en te binden: je applicatie hoeft die waarde nooit te weten.

Wie trösten wir uns, die Mörder aller Mörder?


Acties:
  • 0 Henk 'm!

  • RobertMe
  • Registratie: Maart 2009
  • Laatst online: 22:44
Creepy schreef op woensdag 17 juni 2009 @ 10:53:
Dat werkt overigens op dezelfde manier als in Oracle. Als je de sequence opvraagt zorgt de database dat dit gelijk wordt opgehoogt en er dus geen dubbele sequences worden uitgegeven.
Maar als je in Oracle zelf de waarde in een sequence kolom wil zetten (dus als je in sql developer een tabel maakt, en daar ook de sequence aanmaakt), word de waarde die je zelf invult weer overschreven, omdat de trigger die bij de sequence hoort niet kijkt of er al een waarde in zit (SELECT sequence.nextval INTO :NEW.id FROM dual, zonder controle of :NEW.id al waarde heeft). Hoe PostgreSQL het doet vind ik ook handiger, die zegt gewoon NOT NULL DEFAULT nextval('een of andere sequence'), en die genereerd dus alleen zelf een nummer als je een NULL erin wil zetten.

Acties:
  • 0 Henk 'm!

  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

RobertMe schreef op woensdag 17 juni 2009 @ 11:03:
[...]
Maar als je in Oracle zelf de waarde in een sequence kolom wil zetten (dus als je in sql developer een tabel maakt, en daar ook de sequence aanmaakt), word de waarde die je zelf invult weer overschreven, omdat de trigger die bij de sequence hoort niet kijkt of er al een waarde in zit (SELECT sequence.nextval INTO :NEW.id FROM dual, zonder controle of :NEW.id al waarde heeft). Hoe PostgreSQL het doet vind ik ook handiger, die zegt gewoon NOT NULL DEFAULT nextval('een of andere sequence'), en die genereerd dus alleen zelf een nummer als je een NULL erin wil zetten.
Dat heeft allerbei niet mijn voorkeur. Dan pak ik liever de DB2 manier: daar zijn identity columns standaard zo geconfigureerd dat je er niet eens zelf een waarde in mag zetten. Als je het wel probeert, dan krijg je een error voor je kiezen. Het is net als met cryptography: laat het over aan de experts en hun grondig geteste implementaties. Zelf gaan rommelen en toch proberen zelf iets te genereren en toe te voegen is de beste manier om de uniciteit alsnog om zeep te helpen.

[ Voor 11% gewijzigd door Confusion op 17-06-2009 11:40 ]

Wie trösten wir uns, die Mörder aller Mörder?


Acties:
  • 0 Henk 'm!

  • iH8
  • Registratie: December 2001
  • Laatst online: 17-06-2024

iH8

erhmz hernummeren, heb ik ook eens gemoeten, is niets voor. wat ik toen gedaan heb is de hele id column met auto-increment weggooid en opnieuw toegevoegd. dat werkte.

Aunt bunny is coming to get me!


Acties:
  • 0 Henk 'm!

  • RobertMe
  • Registratie: Maart 2009
  • Laatst online: 22:44
En vervolgens kun je tegen problemen lopen als je de laatst gebruike waarde wil ophalen.

Wat in posgresql mogelijk is is:
[code=sql]
--ophalen nieuwe nummer
SELECT nextval('order_seq');
-- insert draaien op order
INSERT INTO orders (order_id, klant_id, ...) VALUES (<net gegenereerde id>, 3);
-- insert draaien op order regel
INSERT INTO order_regels (order_id, product_id) VALUES (<net gegenereerde id>, 2);
INSERT INTO order_regels (order_id, product_id) VALUES (<net gegenereerde id>, 5);
[/code=sql]
Nu hoef ik dus niet na de insert in orders, het laatst gebruikte/gegenereerde id op te halen, waardoor ik ook niet in de problemen kan komen met of het het in het totaal laatst gebruikte id is (zeg maar MAX(order_id), doet iemand na jouw nog insert, krijg je zijn id), of dat het per transactie het laatste id is, of per connectie, of, of. Ik weet dat nextval mij altijd een uniek id geeft, ongeacht transacties, connecties what so ever. Dus als ik eerst het id ophaal/genereer, en vervolgens dat id handmatig in de INSERT INTO gebruik, zit ik altijd safe.

Het enige nadeel is dat ik handmatig id 300 erin kan zetten, als de sequence dan id 300 genereerd, krijg je een unique violation, maar dan moet je maar niet handmatig id's invullen :+ (tenzij ze uit de sequence komen)

Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

SFB schreef op dinsdag 16 juni 2009 @ 13:45:
Overigens zijn er geen referenties naar het id. Het word wel gebruikt in wat $_GET requests, maar alleen als je aangeeft dat je een bepaalde notitie wil bewerken, printen, mailen, etc. Eenrichtingverkeer dus.
En wat als iemand zo'n bewerkings-pagina opvraagt net voor het id van het onderliggende item verandert, en submit er net na? Wat gebeurt er dan? ;)
.oisyn schreef op dinsdag 16 juni 2009 @ 13:50:
Mensen die GUIDs gebuiken gaan er altijd maar gewoon vanuit dat ze uniek zijn. Ik vraag me af hoe bruikbaar dergelijke systemen nog zijn op het moment dat er daadwerkelijk een collision optreedt. Ik geloof niet dat er iemand überhaupt rekening mee houdt.
Inderdaad, de sessie-ids die wij genereren zijn volstrekt random gegenereerde "md5"-hashes (aka 32 willekeurige hex-getallen), in de praktijk lopen we vziw geregeld tegen een collision op en dan hebben we slechts een paar miljoen andere sessies.
Bij GUID's zit er natuurlijk wat meer scheiding in, door tijdscomponenten en het verwerken van hardwareidentificaties en dergelijke. Maar dat zorgt er tegelijkertijd ook weer voor dat je een heel groot deel van de beschikbare "ruimte" van de 128bits domweg weggooit in ruil voor een verlaging van de kans op die collisions.
Confusion schreef op dinsdag 16 juni 2009 @ 14:48:
Not an option, als het probleem is dat je over de 4 miljard heen gaat. Overigens gaf ik gewoon een oplossing voor het probleem dat Woy signaleerde.
De oplossing die Woy zelf geeft, 64-bits getallen gebruiken, levert je een veel simpelere oplossing tegen hetzelfde probleem op.
Confusion schreef op dinsdag 16 juni 2009 @ 15:07:
Als je daadwerkelijk een miljard records hebt, dan is het verschil tussen een 32 bits int en een 64 bits int zo'n 4 GB schijfruimte voor de opslag zelf, maar bovendien een forse vergroting van je index. Daar kon je weleens heel erg niet blij van worden.
Dan nog is het een relatief kleine hoeveelheid data tov de rest van je tabel. Tenzij je natuurlijk alleen de id's wilt bewaren, maar dat is een nogal vreemde dataset :P
Wat in dit geval waarschijnlijk erger is, is dat je bij een innodb-tabel in MySQL die primary key ook in alle andere indexen verwerkt krijgt, dus dat je niet alleen die ene index vergroot...
Confusion schreef op dinsdag 16 juni 2009 @ 20:47:
Gezien de manier waarop de meeste mensen en DBMS'en met sequences omgaan, denk ik dat GUID's minder kans op een collision geven. In SQL Server 2003 is het ronduit moeilijk om te garanderen dat twee transacties niet hetzelfde 'nieuwe' id toegewezen krijgen; dat het vrijwel altijd goed gaat is meer geluk dan wijsheid.
Vziw is het in MySQL niet mogelijk om meerdere id's uit te delen en/of daar een ander uitgedeelde waarde te krijgen. Helaas is het wel zo dat de auto_increment minder goed schaalbaar geimplementeerd is dan diverse andere databases, maar dat is dan weer een heel ander probleem.
En als je denkt dat MySql beter is: guess again.
Vertel? De beperkingen die ik ken is dat de auto-increment counter voor innodb-tabellen door een SELECT MAX(...) bepaald wordt bij startup en dat ie niet super-schaalbaar geimplementeerd is. Maar zelf heb ik nooit voorbeelden gezien waarbij de net uitgedeelde waarde van een auto-increment niet daarna met de API-functie voor het opvragen van de insert-id werkt. Misschien dat het met non-api implementaties als JDBC lastiger gaat, dat heb ik verder niet uitgebreid op die manier gebruikt.
Confusion schreef op woensdag 17 juni 2009 @ 11:03:
Het zou een JDBC bug kunnen zijn, maar dat neemt niet weg dat er in ieder geval twee manieren zijn om een identity op te halen die ongetwijfeld veel gebruikt worden, terwijl ze niet goed werken en nooit hadden moeten bestaan.
Maar beide zijn dus blijkbaar fout gebruik van de API :P

Acties:
  • 0 Henk 'm!

  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

ACM schreef op woensdag 17 juni 2009 @ 12:21:
Dan nog is het een relatief kleine hoeveelheid data tov de rest van je tabel. Tenzij je natuurlijk alleen de id's wilt bewaren, maar dat is een nogal vreemde dataset :P
Wat in dit geval waarschijnlijk erger is, is dat je bij een innodb-tabel in MySQL die primary key ook in alle andere indexen verwerkt krijgt, dus dat je niet alleen die ene index vergroot...
Sowieso is verdubbeling van een index die toch al GB's groot is meestal niet fijn en niet goed voor je performance.
Vziw is het in MySQL niet mogelijk om meerdere id's uit te delen en/of daar een ander uitgedeelde waarde te krijgen. Helaas is het wel zo dat de auto_increment minder goed schaalbaar geimplementeerd is dan diverse andere databases, maar dat is dan weer een heel ander probleem.
Eerst hit als je Googled op "mysql auto increment concurrency": http://bugs.mysql.com/bug.php?id=39407
en dat is niet de eerste of enige die ik de afgelopen jaren langs heb zien komen.
Maar beide zijn dus blijkbaar fout gebruik van de API :P
Ja, maar de beste bescherming daartegen is om dit soort dingen uberhaupt nooit als API aan te bieden. Die @@IDENTITY, zeker met de manier waarop dat gedocumenteerd was, is vragen om gebruikers die tegen een probleem aanlopen.

Wie trösten wir uns, die Mörder aller Mörder?


Acties:
  • 0 Henk 'm!

  • cariolive23
  • Registratie: Januari 2007
  • Laatst online: 18-10-2024
@RobertMe:
De SQL kan nog anders, je kunt in de INSERT's van de orderregels verwijzen naar de sequence van het order_id:
SQL:
1
2
3
4
5
6
BEGIN;
INSERT INTO orders (order_id, klant_id, ...) VALUES (nextval('order_seq'), 3, ...) RETURNING order_id;
-- insert draaien op order regel
INSERT INTO order_regels (order_id, product_id) VALUES (currval('order_seq'), 2);
INSERT INTO order_regels (order_id, product_id) VALUES (currval('order_seq'), 5);
COMMIT;

Het aangemaakte order_id krijg je retour dankzij returning, maar je hoeft deze niet in de INSERT's van de orderregels te zetten, daarin vraag je gewoon met CURRVAL() het laatste aangemaakte nummer op voor het ordernummer. En omdat je alles binnen een transactie uitvoert, krijg je nooit problemen met verbroken connecties of halve bestellingen.

Je wint er ook performance mee en je zou ook nog prepared statements kunnen gebruiken voor nog meer performance.

Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Confusion schreef op woensdag 17 juni 2009 @ 15:16:
Sowieso is verdubbeling van een index die toch al GB's groot is meestal niet fijn en niet goed voor je performance.
Uiteraard, maar het voorstel om dan maar GUID's te gebruiken maakt het natuurlijk alleen maar nog erger :P De enige manier om dat te voorkomen is inderdaad er voor zorgen dat je onder de 4 miljard items blijft. En als je met het opruimen van je id's dat kan regelen, kan dat nog best interessant worden, maar het blijft imho iets dat je alleen in het uiterste geval moet doen. Maar de schaalgrootte is bij de topicstarter niet echt aanwezig.
Bovendien is zoals ook al door anderen gezegd die indexgrootte e.d. dan waarschijnlijk verre van je grootste probleem. De kans is groot dat je dan om hele andere reden al veel eerder bent begonnen met "sharding" en dergelijke.
Eerst hit als je Googled op "mysql auto increment concurrency": http://bugs.mysql.com/bug.php?id=39407
en dat is niet de eerste of enige die ik de afgelopen jaren langs heb zien komen.
En gelijk een slecht voorbeeld, want het is iets waarbij blijkbaar de beschikbare uit te delen id's heel snel oplopen. Niet iets waarbij duplicate's ofzo uitgedeeld proberen te worden. Ik heb geen idee wat de precieze oorzaak van die bug is, maar een dergelijk scenario kan je sowieso simuleren door hele reeksen insert-transacties te starten en terug te rollen.
Ja, maar de beste bescherming daartegen is om dit soort dingen uberhaupt nooit als API aan te bieden. Die @@IDENTITY, zeker met de manier waarop dat gedocumenteerd was, is vragen om gebruikers die tegen een probleem aanlopen.
Er is hoe-dan-ook een redelijk low-level call voor nodig om dat id op te vragen. Dan valt er zowel voor een uitbreiding van de lokale api waar je toch al mee werkt (jdbc, php-functie-calls, etc) als een extra query-type te zeggen. Dat eerste is in de huidige praktijk uniformer, hoewel dat laatste flexibeler is, zeker als je zoals bij PostgreSQL in principe honderd keer achter elkaar opnieuw de zonet uitgedeelde waarde op kan vragen van tig verschillende sequences.

Acties:
  • 0 Henk 'm!

  • Tjolk
  • Registratie: Juni 2007
  • Laatst online: 05-07 17:07
ACM schreef op woensdag 17 juni 2009 @ 12:21:
[...]
En wat als iemand zo'n bewerkings-pagina opvraagt net voor het id van het onderliggende item verandert, en submit er net na? Wat gebeurt er dan? ;)
Nah, da's simpel af te vangen. Het is (vooralsnog tenminste) een puur Nederlandstalig systeem, dus ik kan er eenvoudig voor kiezen om dit om 04:00 uur te laten uitvoeren. Het aantal gebruikers rond die tijd zal minimaal zijn. Omdat je dat natuurlijk niet kunt uitsluiten, zorg je er in het rebuildscript voor dat de boel heel even offline gaat met een melding dat er even onderhoud gepleegd wordt. Om te zorgen dat mensen die vlak voor die melding al met een bewerking bezig zijn niet hun bewerkingen kwijt raken, sla je dat even op in een buffer. Dat zou dus allemaal best te fixen zijn, als ik dat nog zou willen.

PS: toch grappig dat deze hele discussie is losgekomen n.a.v. mijn vraag. :)

Tjolk is lekker. overal en altijd.


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
SFB schreef op donderdag 18 juni 2009 @ 08:25:
Om te zorgen dat mensen die vlak voor die melding al met een bewerking bezig zijn niet hun bewerkingen kwijt raken, sla je dat even op in een buffer. Dat zou dus allemaal best te fixen zijn, als ik dat nog zou willen.
Holy shit wat een stunts.

{signature}


Acties:
  • 0 Henk 'm!

  • Remus
  • Registratie: Juli 2000
  • Laatst online: 15-08-2021
Creepy schreef op woensdag 17 juni 2009 @ 10:53:
Dat zelfs SELECT SCOPE_IDENTITY() faalt in MS SQL server verbaasd me eerlijk gezegd. Als ik het verhaal zo lees lijkt het eerder op een bug in JDBC dan in MS SQL. Het is dat ik geen MS SQl bij de hand heb hier want ik het het graag even getest. Buiten JDBC om heb ik regelmatig de SCOPE_IDENTITY gebruikt (ook via losse queries binnen dezelfde transactie).
Ik verwacht eerder dat men werkte met autocommit aan. Dan zit je na het uitvoeren van een query in JDBC in een nieuwe transactie en dus geeft scope_identity geen waarde terug.

Acties:
  • 0 Henk 'm!

  • Remus
  • Registratie: Juli 2000
  • Laatst online: 15-08-2021
RobertMe schreef op woensdag 17 juni 2009 @ 11:03:
[...]

Maar als je in Oracle zelf de waarde in een sequence kolom wil zetten (dus als je in sql developer een tabel maakt, en daar ook de sequence aanmaakt), word de waarde die je zelf invult weer overschreven, omdat de trigger die bij de sequence hoort niet kijkt of er al een waarde in zit (SELECT sequence.nextval INTO :NEW.id FROM dual, zonder controle of :NEW.id al waarde heeft).
Die sequence-trigger moet je altijd zelf schrijven als developer, dus dat ligt niet aan Oracle, maar aan de developer van de trigger. Daarbij is het een keuze: in sommige situaties wil je helemaal niet dat een gebruiker het id kan toewijzen.

Acties:
  • 0 Henk 'm!

  • RobertMe
  • Registratie: Maart 2009
  • Laatst online: 22:44
Remus schreef op donderdag 18 juni 2009 @ 10:16:
[...]

Die sequence-trigger moet je altijd zelf schrijven als developer, dus dat ligt niet aan Oracle, maar aan de developer van de trigger. Daarbij is het een keuze: in sommige situaties wil je helemaal niet dat een gebruiker het id kan toewijzen.
Klopt, maar SQL Developer (wat ik op school moet gebruiken, en volgensmij ook "de officiele" van Oracle is) doet automatisch die trigger maken, als je in de new table dialog de sequence aanmaakt (waarbij je de sequence meteen aan een kolom koppeld)

Acties:
  • 0 Henk 'm!

  • Remus
  • Registratie: Juli 2000
  • Laatst online: 15-08-2021
RobertMe schreef op donderdag 18 juni 2009 @ 10:32:
[...]

Klopt, maar SQL Developer (wat ik op school moet gebruiken, en volgensmij ook "de officiele" van Oracle is) doet automatisch die trigger maken, als je in de new table dialog de sequence aanmaakt (waarbij je de sequence meteen aan een kolom koppeld)
Dat is dan waarschijnlijk omdat dat gewoon de meeste gebruikte optie is. Dus nog steeds: dat ligt niet aan Oracle. Je kan zelf naar hartelust die trigger aanpassen.

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Modbreak:Ik heb de discussie over collissions van Session ID's afgesplitst naar Collisions van Session ID's

[ Voor 7% gewijzigd door Woy op 24-06-2009 09:18 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”

Pagina: 1