FAQ |
Kalender |
![]() |
#1 | |||
|
||||
Medlem
|
En tabell med ett Id enligt
CREATE TABLE MinTabell ( Id bigint unsigned NOT NULL AUTO_INCREMENT, ... ... Efterhand har vissa poster raderats och det blir "hål" i följden av Id:en Låt säga att Id ser ut så sorterade asc. 1 2 3 4 5 6 11 12 13 14 ... ... ... Finns det någon sql-sats som leter upp första lediga Id, i detta fall Id = 7 ? Dessutom vill jag har svar på hur stort "hålet" är, dvs hur många oanvända Id det finns iföljd från och med 7. I detta fall 4 st ( 7,8,9,10 )? Två tillfällen som jag vill använda detta. a. När en ny post ska läggas till så ska första lediga Id användas. b. "Packa" ihop posterna så att alla "hål" försvinner. på Serverversion: 5.0.51b så letar denna SQL-sats upp första lediga Id select Id+1 as lastId from MinTabell where (select count(*) from MinTabell where Id = lastId) = 0 limit 1 På Server version: 5.0.75 Server version: 5.1.42 Server version: 5.1.50 får jag ERROR 1054 (42S22): Unknown column 'lastId' in 'where clause' Varför göra detta nu då? Jo det kan man ju fråga sig. Varför ska osten skäras på ett visst sätt? Varför ska ljusen på bordet så i exakta rader? osv Fobier kanske ... Har det någon betydelse ur effektivitetssynpunkt? Kan tillägga att en tabell för närvarande innehåller drygt 68 milj poster. |
|||
![]() |
![]() |
![]() |
#2 | |||
|
||||
Mycket flitig postare
|
Återanvänd inte id:n. Vad händer om det finns kvar referenser i andra tabeller till den gamla raden?
Unsigned bigint har maxvärde 18446744073709551615 så du har mao ett tag kvar innan du behöver oroa dig för att få slut på dem ![]() Om du nödvändigtvis någon gång vill bli av med "hålen" så föreslår jag en export av datan + en import utan att importera id-kolumnen, med en återställd auto_increment-räknare. På så sätt får alla rader nya id:n från 1 och uppåt. Men att göra det är nog snarare lätt neurotiskt än effektivitetsbefrämjande ![]() |
|||
![]() |
![]() |
![]() |
#3 | |||
|
||||
Bara ett inlägg till!
|
Nej, det har ingen som helst betydelse ur effektivitetssynpunkt. Enda gången det skulle kunna påverka effektiviteten är om datatypen tar slut så du måste välja en större datatyp, till exempel använda BIGINT istället för INT. Då krävs mer RAM för att hålla indexet i minnet och det tar större plats på disk (båda två saker som kan påverka prestandan).
Men så länge du bara har hål och långt kvar till "taket" verkar det bara trassligt att "täppa igen" hålen. Som MMC säger ställer det till med problem om du har andra tabeller som relaterar till den du jobbar med nu. Tänk om du har gamla data kvar som då plötsligt ofrivilligt kopplas till den här tabellen? Eller om du har externa tjänster som också använder id-numret. Om du till exempel tagit bort en webbsida så kanske det är bättre att besökaren får veta det än att de kommer till en helt ny sida. |
|||
![]() |
![]() |
![]() |
#4 | |||
|
||||
Medlem
|
Citat:
Men dina ord är nog kloka ändå. Jag får försöka komma över mina "städfobier" :-) |
|||
![]() |
![]() |
![]() |
#5 | ||
|
|||
Klarade millennium-buggen
|
Generellt bör man vara försiktig med att använda autoincrement om det finns en naturlig primärnycken man kan använda i stället. Det är viktigt att man tänker igenom hur man definierar primärnyckel i varje tabell.
Jag skulle aldrig ge mig in på att "återanvända" första lediga nyckel just i en autoincrement PK. när man använder naturliga primärnycklar kan man göra det får då finns värdet definierat utanför systemet. Syftet med autoincrement är att kunna använda en PK där inga naturliga nycklar skulle passa, exempelvis för ordernummer, fakturanummer m.m. |
||
![]() |
![]() |
![]() |
#6 | |||
|
||||
Har WN som tidsfördriv
|
Citat:
Jag tycker det är bra att ha en autoincrement primärnyckel så ofta som möjligt. Jag tycker det är en bra struktur när man alltid kan referera till en rad med tabell.id. Om man ska naturliga primärnycklar så blir det oftast strängar och då blir indexen gigantiska(och därmed långsamma) i många fall när man har stora tabeller. Ordernummer och fakturanummer tycker jag är bra exempel på tillfällen då man inte ska använda autoincrement utan här borde varje ID slumpas fram av säkerhetsskäl. |
|||
![]() |
![]() |
![]() |
#7 | |||
|
||||
Bara ett inlägg till!
|
Citat:
I övrigt håller jag med dig om att tekniska heltalsnycklar är bra för att få ner indexstorleken, men de är trots allt inte alltid att föredra. Det beror ju mycket på tabellen och så också. För små tabeller finns det ju liten eller ingen anledning att använda annat än naturliga primärnycklar. |
|||
![]() |
![]() |
![]() |
#8 | ||
|
|||
Klarade millennium-buggen
|
En stor del av syftet/fördelen med att använda en relationsdatabas är att man kan använda s.k. uppslagstabeller av olika nyckelvärden. För att ta ett enkelt exempel; LAndskoder som SE, DE, US, FI mfl så lägger man dessa koder som primärnyckel i en tabell.
Då kan man använda denna nyckel som Främmande nyckel i andra tabeller och därmed garantera att inga ogiltiga värden lagras i de tabeller som använder dessa främmande nycklar. Du får även en inbyggd kontroll mot dubbletter i samma kolumn. Använder man autoincrement så måste man ändå lägga på ett extra unikt index på motsvarande kod-kolumnen och då har man inte vunnit något utan försämrat prestanda i databasen. Fördelen med att använda just externt definierade nycklar är då att de erfarba användarna kan skriva in värdet direkt i inmatningsfältet och de kan då snabba upp registreringen av olika uppgifter. Detta är ett mycket viktigt användningsområde för naturliga primärnycklar. Det är rekommenderat att man ska försöka använda dessa naturliga prmärnycklar så mycket som möjligt. Det ger bland annat även fördelar om man ska integrera två olika system, om de använt samma naturliga externa källa för sina nycklar, det blir hiskeligt mycket enklare att göra integrationen då. Fler och fler system bygger på principen att de ska vara små och specialicerade på färre ansvarsområden, så integrationsproblematiken blir bara mer och mer vanlig. Senast redigerad av Conny Westh den 2010-12-21 klockan 14:24 |
||
![]() |
![]() |
![]() |
#9 | |||
|
||||
Har WN som tidsfördriv
|
Ja, i exemplet med landskoder är det ju såklart en bra idé att använda landskoden som primärnyckeln.
Men jag har sett system där man t.ex. använder person-/organisationsnummer som primärnycken och sparar dessa med strecket som en stäng, dvs 000000-0000. Det ger väldigt dåliga index tycker jag även om det är ett "bra" naturligt index. Är det verkligen så? Jag vill inte skicka ut fakturor med ett autoincrementnummer som fakturanummer. Då kan ju alla se exakt hur många fakturor man skickar ut under en viss tidsperiod och det ser jag som en företagshemlighet... Men det kanske bara gäller i bokföringen så man kan skriva ett annat referensnummer på fakturan man skickar ut? |
|||
![]() |
![]() |
![]() |
#10 | |||
|
||||
Bara ett inlägg till!
|
Citat:
http://www.skatteverket.se/rattsinfo...800028340.html |
|||
![]() |
![]() |
Svara |
|
|