/ Forside / Teknologi / Udvikling / SQL / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
SQL
#NavnPoint
pmbruun 1704
niller 962
fehaar 730
Interkril.. 701
ellebye 510
pawel 510
rpje 405
pete 350
gibson 320
10  smorch 260
Autoinc i MySQL
Fra : Harald


Dato : 25-08-03 17:16

Hej

Er det en go ide at benytte et autoinc felt i en MySQL tabel eller skal man
holde sig fra det. Jeg har indtil nu benyttes mig af BDE (Borland Database
Engine) og paradox tabeller og der virker autoinc ikke altid lige godt.

Hvis der ikke er noget man bør benytte hvordan kan man så med SQL finde det
næste frie nummer i en tabel som har et felt der f.eks. hedder Idnr og som
er et Autoinc felt?

Mvh
HK



 
 
Troels Arvin (25-08-2003)
Kommentar
Fra : Troels Arvin


Dato : 25-08-03 22:20

On Mon, 25 Aug 2003 18:16:12 +0200, Harald wrote:

> Er det en go ide at benytte et autoinc felt i en MySQL tabel

Diskussionen om hvorvidt surrogatnøgler er fornuftige har før været
oppe uden at det har affødt nogen endegyldig konklusion. Hvis du har
behov for database-generede værdier må du jo gøre det.

> Jeg har indtil nu benyttes mig af BDE (Borland Database Engine) og
> paradox tabeller og der virker autoinc ikke altid lige godt.

Jeg har i tidernes morgen været ude for, at et autoincrement felt i MySQL
gik amok og umotiveret begyndte at tildele astronomisk høje værdier, men
sådanne bugs er nok for længst rettede.

> Hvis der ikke er noget man bør benytte hvordan kan man så med SQL
> finde det næste frie nummer i en tabel som har et felt der f.eks.
> hedder Idnr og som er et Autoinc felt?

SELECT MAX(Idnr)+1;

Se i øvrigt http://troels.arvin.dk/db/rdbms/#mix-identity

--
Greetings from Troels Arvin, Copenhagen, Denmark


Peter Brodersen (25-08-2003)
Kommentar
Fra : Peter Brodersen


Dato : 25-08-03 22:40

On Mon, 25 Aug 2003 23:19:51 +0200, Troels Arvin <troels@arvin.dk>
wrote:

>Jeg har i tidernes morgen været ude for, at et autoincrement felt i MySQL
>gik amok og umotiveret begyndte at tildele astronomisk høje værdier, men
>sådanne bugs er nok for længst rettede.

Jow, det...! Jeg har oplevet noget lignende i <3.23-tiden.

>> Hvis der ikke er noget man bør benytte hvordan kan man så med SQL
>> finde det næste frie nummer i en tabel som har et felt der f.eks.
>> hedder Idnr og som er et Autoinc felt?
>SELECT MAX(Idnr)+1;

Man bør blot huske på at det at hente MAX plus én ud, og derefter
indsætte en ny række, ikke sker atomisk.

Hvis man alligevel bruger mysql-specifikke funktioner i sine queries,
ser jeg dog ingen problemer i at bruge autoincrement-felter.

--
- Peter Brodersen

Ugens sprogtip: mayonnaise (og ikke mayonaise)

Jimmy (25-08-2003)
Kommentar
Fra : Jimmy


Dato : 25-08-03 22:47


"Troels Arvin" <troels@arvin.dk> wrote in message
news:pan.2003.08.25.21.19.51.173540@arvin.dk...
> On Mon, 25 Aug 2003 18:16:12 +0200, Harald wrote:
>

> > Hvis der ikke er noget man bør benytte hvordan kan man så med SQL
> > finde det næste frie nummer i en tabel som har et felt der f.eks.
> > hedder Idnr og som er et Autoinc felt?
>
> SELECT MAX(Idnr)+1;


Den ide mener jeg ikke er god (beskrevet 100 gange tidligere i forbindelse
med LAST_INSERT_ID() )

Jeg mener den rigtige er at lave følgende udtræk:

SHOW TABLE STATUS LIKE '[table]'

Den giver en række data omkring tabellen, bl.a en der hedder
"Auto_increment", som indeholder det ID, som anvendes næste gang.

Mvh
Jimmy



Harald (26-08-2003)
Kommentar
Fra : Harald


Dato : 26-08-03 02:13

"Jimmy" <nyhedsgruppe@get2net.dk> skrev i en meddelelse
news:gtv2b.536$o14.247@news.get2net.dk...
>
> "Troels Arvin" <troels@arvin.dk> wrote in message
> news:pan.2003.08.25.21.19.51.173540@arvin.dk...
> > On Mon, 25 Aug 2003 18:16:12 +0200, Harald wrote:
> >
>
> > > Hvis der ikke er noget man bør benytte hvordan kan man så med SQL
> > > finde det næste frie nummer i en tabel som har et felt der f.eks.
> > > hedder Idnr og som er et Autoinc felt?
> >
> > SELECT MAX(Idnr)+1;
>
>
> Den ide mener jeg ikke er god (beskrevet 100 gange tidligere i forbindelse
> med LAST_INSERT_ID() )
>
> Jeg mener den rigtige er at lave følgende udtræk:
>
> SHOW TABLE STATUS LIKE '[table]'
>
> Den giver en række data omkring tabellen, bl.a en der hedder
> "Auto_increment", som indeholder det ID, som anvendes næste gang.

Kunne der i teorien ikke ske det at man kalder SHOW TABLE STATUS og får
Auto_increment men så det det øjeblik der går til man kalder f.eks. INSERT
så har en anden indsat en record og så er Auto_increment ikke den rigtige
længere.

/HK



Jimmy (26-08-2003)
Kommentar
Fra : Jimmy


Dato : 26-08-03 06:29


> > SHOW TABLE STATUS LIKE '[table]'
> >
> > Den giver en række data omkring tabellen, bl.a en der hedder
> > "Auto_increment", som indeholder det ID, som anvendes næste gang.
>
> Kunne der i teorien ikke ske det at man kalder SHOW TABLE STATUS og får
> Auto_increment men så det det øjeblik der går til man kalder f.eks. INSERT
> så har en anden indsat en record og så er Auto_increment ikke den rigtige
> længere.


Det kunne man i høj grad forestille sig.
Det kan man modvirke ved hjælp af:

LOCK TABLES tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE}
[, tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE}
....]
....
UNLOCK TABLES


http://www.mysql.com/doc/en/LOCK_TABLES.html


Mvh
Jimmy



Troels Arvin (26-08-2003)
Kommentar
Fra : Troels Arvin


Dato : 26-08-03 07:08

On Mon, 25 Aug 2003 23:47:18 +0200, Jimmy wrote:

>>> hvordan kan man så med SQL finde det næste frie nummer

>> SELECT MAX(Idnr)+1;

> Den ide mener jeg ikke er god (beskrevet 100 gange tidligere i
> forbindelse med LAST_INSERT_ID() )

LAST_INSERT_ID() er ikke så fed til at finde næste frie nummer, hvis
ikke man forinden har indsat en række. Eller er der noget, jeg har
misforstået omkring LAST_INSERT_ID()?

> SHOW TABLE STATUS LIKE '[table]'
>
> Den giver en række data omkring tabellen, bl.a en der hedder
> "Auto_increment"

Hvorfor er det bedre end SELECT MAX(...)?

SELECT MAX(...) er dog trods alt standard SQL og umiddelbart genkendeligt
for enhver - også folk, der ikke har sat sig ind i MySQL's særheder.
Tænker du, at den MySQL-specifikke løsning er hurtigere?

--
Greetings from Troels Arvin, Copenhagen, Denmark


Jimmy (26-08-2003)
Kommentar
Fra : Jimmy


Dato : 26-08-03 11:13


"Troels Arvin" <troels@arvin.dk> wrote in message
news:pan.2003.08.26.06.08.07.857155@arvin.dk...
> On Mon, 25 Aug 2003 23:47:18 +0200, Jimmy wrote:
>
> >>> hvordan kan man så med SQL finde det næste frie nummer
>
> >> SELECT MAX(Idnr)+1;
>
> > Den ide mener jeg ikke er god (beskrevet 100 gange tidligere i
> > forbindelse med LAST_INSERT_ID() )
>
> LAST_INSERT_ID() er ikke så fed til at finde næste frie nummer, hvis
> ikke man forinden har indsat en række. Eller er der noget, jeg har
> misforstået omkring LAST_INSERT_ID()?

Nej nej - Grunden til at jeg ikke vil vælge MAX er beskrevet i forbindelse
med LAST_INSERT_ID() 100 gange


> > SHOW TABLE STATUS LIKE '[table]'
> >
> > Den giver en række data omkring tabellen, bl.a en der hedder
> > "Auto_increment"
>
> Hvorfor er det bedre end SELECT MAX(...)?

Det er den MySQL *selv* siger den vil bruge næste gang.
MAX(ID)+1 er din *forventning* om at den altid lægger een til højeste
nummer.

MAX() fejler i det tilfælde jeg sletter seneste række.
Det næste ID vil *ikke* være MAX(ID)+1, men derimod den MySQL selv angiver.

Mvh
Jimmy



Troels Arvin (26-08-2003)
Kommentar
Fra : Troels Arvin


Dato : 26-08-03 16:12

On Tue, 26 Aug 2003 12:12:50 +0200, Jimmy wrote:

> Grunden til at jeg ikke vil vælge MAX er beskrevet i forbindelse med
> LAST_INSERT_ID() 100 gange

Jeg har googlet lidt og kan ikke umiddelbart finde det. Kan du ikke
opsummere hurtigt?

>> > SHOW TABLE STATUS LIKE '[table]'
>> >
>> > Den giver en række data omkring tabellen, bl.a en der hedder
>> > "Auto_increment"
>>
>> Hvorfor er det bedre end SELECT MAX(...)?
>
> Det er den MySQL *selv* siger den vil bruge næste gang. MAX(ID)+1 er
> din *forventning* om at den altid lægger een til højeste nummer.

Men hvis du først aflæser næstkommende auto_increment-værdi, for
derefter at benytte værdien i en insert, kan det samme da også ske: I
mellemtiden kan der være tilføjet eller slettet en række fra
pågældende tabel. At forhindre den slags kræver samtidigheds-kontrol,
fx. i form af låsning af tabellen eller passende valg af
isolations-niveau, hvis éns MySQL understøtter transaktioner.

--
Greetings from Troels Arvin, Copenhagen, Denmark


Jimmy (27-08-2003)
Kommentar
Fra : Jimmy


Dato : 27-08-03 10:58


"Troels Arvin" <troels@arvin.dk> wrote in message
news:pan.2003.08.26.15.12.19.313198@arvin.dk...
> On Tue, 26 Aug 2003 12:12:50 +0200, Jimmy wrote:
>
> > Grunden til at jeg ikke vil vælge MAX er beskrevet i forbindelse med
> > LAST_INSERT_ID() 100 gange
>
> Jeg har googlet lidt og kan ikke umiddelbart finde det. Kan du ikke
> opsummere hurtigt?

Naturligvis - Der er dog intet nyt i det for dig.
Vi snakker her om at finde det senest indsatte ID, som mange finder via
SELECT MAX(ID).


Du ønsker nu at finde det ID, som du lige har fået tildelt af MySQL, og
anvender SELECT MAX(ID).
MEN du har ingen garanti for, at det returnede tal svarer til *dit* senest
indsatte ID, da 10000 personer kan indsætte rækker på samme tid som dig.
Dérfor skal man anvende LAST_INSERT_ID() til at finde ens eget senest
indsatte ID.



> >> > SHOW TABLE STATUS LIKE '[table]'
> >> >
> >> > Den giver en række data omkring tabellen, bl.a en der hedder
> >> > "Auto_increment"
> >>
> >> Hvorfor er det bedre end SELECT MAX(...)?
> >
> > Det er den MySQL *selv* siger den vil bruge næste gang. MAX(ID)+1 er
> > din *forventning* om at den altid lægger een til højeste nummer.
>
> Men hvis du først aflæser næstkommende auto_increment-værdi, for
> derefter at benytte værdien i en insert, kan det samme da også ske: I
> mellemtiden kan der være tilføjet eller slettet en række fra
> pågældende tabel. At forhindre den slags kræver samtidigheds-kontrol,
> fx. i form af låsning af tabellen eller passende valg af
> isolations-niveau, hvis éns MySQL understøtter transaktioner.


Dette er fuldstændigt korrekt.
Det blev også bemærket af Harald, hvor jeg skrev stort set det samme som
dig.


Opsummering:
- Ønsker man at finde det ID MySQL netop anvendte i ens egen netop indsatte
række,
skal man anvende LAST_INSERT_ID()

- Ønsker man at finde det ID MySQL har tænkt sig at anvende ved næste
INSERT skal man anvende
SHOW TABLE STATUS LIKE '[table]' og suge informationen derfra.


Man kan ikke stole på at MAX(ID)+1 vil returnere det næste ID, da en slettet
rækkes ID ikke vil genbruges.

Min personlige holdning er dog, at det er en fejl at anvende datatypen
AUTO_INCREMENT, hvis man oplever behov for at finde det næste ID.
Der skal man generere sine egne unikke primærnøgler.


Mvh
Jimmy




Søg
Reklame
Statistik
Spørgsmål : 177501
Tips : 31968
Nyheder : 719565
Indlæg : 6408521
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste