Kom ihåg mig?
Home Menu

Menu


Auto_increment och två Primary Keys?

Ämnesverktyg Visningsalternativ
Oläst 2010-06-15, 10:53 #1
Skatan Skatan är inte uppkopplad
Medlem
 
Reg.datum: Apr 2007
Inlägg: 182
Skatan Skatan är inte uppkopplad
Medlem
 
Reg.datum: Apr 2007
Inlägg: 182
Standard Auto_increment och två Primary Keys?

Jag letar efter en lösning som jag vill ha på databasnivå (Mysql), och inte behöva göra fulhack i programmeringen.

Senario (orelevant, kan lika gärna gälla ordersystem eller e-butiker)
Anställda skall skicka in rapporter, varje ny anställd skall rapportID-numret börja på 1.

Tabeller:

Anställda
AnstalldId
Namn
Epost

Rapporter
RapportId
AnstalldId
Arbetade_timmar

Jag vill alltså att RapportId skall vara auto_increment, men jag vill att vid varje AnstalldId så skall det börja om från 1. Men det får givetvis inte kunna skapas en dubblett av RapportId med samma AnstalldId

Detta borde vara basic, men hittar ingen bra lösning på Google.
Skatan är inte uppkopplad   Svara med citatSvara med citat
Oläst 2010-06-15, 11:06 #2
abergmans avatar
abergman abergman är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Feb 2010
Inlägg: 762
abergman abergman är inte uppkopplad
Mycket flitig postare
abergmans avatar
 
Reg.datum: Feb 2010
Inlägg: 762
Citat:
Ursprungligen postat av Skatan Visa inlägg
Jag letar efter en lösning som jag vill ha på databasnivå (Mysql), och inte behöva göra fulhack i programmeringen.

Senario (orelevant, kan lika gärna gälla ordersystem eller e-butiker)
Anställda skall skicka in rapporter, varje ny anställd skall rapportID-numret börja på 1.

Tabeller:

Anställda
AnstalldId
Namn
Epost

Rapporter
RapportId
AnstalldId
Arbetade_timmar

Jag vill alltså att RapportId skall vara auto_increment, men jag vill att vid varje AnstalldId så skall det börja om från 1. Men det får givetvis inte kunna skapas en dubblett av RapportId med samma AnstalldId

Detta borde vara basic, men hittar ingen bra lösning på Google.
Sätt Id kolumnen i varje tabell som PK och autoincrement så är ju problemet löst? Eller har jag massuppfittat dig?
abergman är inte uppkopplad   Svara med citatSvara med citat
Oläst 2010-06-15, 11:25 #3
Skatan Skatan är inte uppkopplad
Medlem
 
Reg.datum: Apr 2007
Inlägg: 182
Skatan Skatan är inte uppkopplad
Medlem
 
Reg.datum: Apr 2007
Inlägg: 182
Citat:
Ursprungligen postat av abergman Visa inlägg
Sätt Id kolumnen i varje tabell som PK och autoincrement så är ju problemet löst? Eller har jag massuppfittat dig?
Jag tror du missuppfattade mig lite.

Data kan se ut som följande


Antällda
1, Nicklas Karlsson
2, Johan Johansson
3, Bengt Karlsson

Rapporter
RapportID, AnställdID
1, 1
2, 1
1, 2
3, 1
2, 2
3, 2
4, 2
1, 3

Och det får aldrig vara dubbletter av Rapporter med samma AnställdID
Skatan är inte uppkopplad   Svara med citatSvara med citat
Oläst 2010-06-15, 13:36 #4
martines avatar
martine martine är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Mar 2005
Inlägg: 767
martine martine är inte uppkopplad
Mycket flitig postare
martines avatar
 
Reg.datum: Mar 2005
Inlägg: 767
Det känns lite som ett feltänk, du vill ha ett rapport-id men det ska inte vara unikt? Är det inte rapport-numrering du är ute efter egentligen? Du kan ha en primary key på båda kolumnerna (med PRIMARY KEY (rapportid,anställdid)) om du nu vill ha det så men frågan är om det inte är bättre med en riktig id med auto_increment och sedan ett numreringsfält om nu det behövs.

Du kan förstås använda din modell men någon automatiskt auto_increment kan du inte få på det viset (eftersom ditt tabellupplägg känns lite som ett hack ;-)

Detta borde göra det du vill:
INSERT INTO Rapporter (RapportId,AnstalldId,Arbetade_timmar) SELECT MAX(RapportId),INSERT_ID(),5 FROM Rapporter WHERE AnstalldId=INSERT_ID();

Och glöm nu inte att ha ett unikt index om du vill vara säker på att inte få dubletter.

Senast redigerad av martine den 2010-06-15 klockan 13:38
martine är inte uppkopplad   Svara med citatSvara med citat
Oläst 2010-06-17, 22:38 #5
Kimpo Kimpo är inte uppkopplad
Medlem
 
Reg.datum: Mar 2009
Inlägg: 185
Kimpo Kimpo är inte uppkopplad
Medlem
 
Reg.datum: Mar 2009
Inlägg: 185
Vill du att flera anställda ska kunna delaktiga i en och samma rapport?
Då kan du ju lägga en kopplingstabell som kopplar ihop Anställda och Rapporter och slipper även en many to many relation.
dvs en tabell där kombinationen av AnställdId och RapportId utgör PK.

Att räkna ut totalsumman av rapporter för en anställd ska du inte lagra i databasen, den kan du dra ut med en sql fråga. Däremot skulle jag nog rekommendera dig att använda dig av en datumkolumn och lagra datumet då rapporten skickades in, så kan du enkelt sortera rapporterna i kronologisk ordning.
Kimpo är inte uppkopplad   Svara med citatSvara med citat
Oläst 2010-06-18, 10:40 #6
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 martine Visa inlägg
Det känns lite som ett feltänk, du vill ha ett rapport-id men det ska inte vara unikt? Är det inte rapport-numrering du är ute efter egentligen? Du kan ha en primary key på båda kolumnerna (med PRIMARY KEY (rapportid,anställdid)) om du nu vill ha det så men frågan är om det inte är bättre med en riktig id med auto_increment och sedan ett numreringsfält om nu det behövs.

Du kan förstås använda din modell men någon automatiskt auto_increment kan du inte få på det viset (eftersom ditt tabellupplägg känns lite som ett hack ;-)

Detta borde göra det du vill:
INSERT INTO Rapporter (RapportId,AnstalldId,Arbetade_timmar) SELECT MAX(RapportId),INSERT_ID(),5 FROM Rapporter WHERE AnstalldId=INSERT_ID();

Och glöm nu inte att ha ett unikt index om du vill vara säker på att inte få dubletter.
Enligt denna lösning så ska givetvis båda kolumnerna i rapport vara PK då blir det automatiskt indexerade på rätt sätt.

Man måste också tänka på att när man lägger upp den första rapporten för en kund så blir max på rapportid NULL och man måste sätta det till 1. i SQL-server finns en funktion som heter ISNULL() som man kan använda vet inte om det finns en motsvarande i MySQL (kollade och det finns syntax: SELECT ISNULL(field,0) FROM TABLE).

Förslag till Kod:
Kod:
INSERT INTO Rapporter (RapportId,AnstalldId,Arbetade_timmar) 
SELECT ISNULL(MAX(RapportId),1),INSERT_ID(),5
FROM Rapporter 
WHERE AnstalldId=INSERT_ID();
Trådskaparen vill använda en nturlig primärnyckel i rapporttabellen för attfå bättre kontroll på informationen och det är bra, det skulle vara omöjligt med autoinkrement i rapport.tabellen.

Mna kan gå ytterligare ett steg och använda en naturlig PK även i kundtabellen med personnr eller orgnr så får du bättre datakvalitet även där (risken för dubletter minimeras).

Att slentrianmässigt använda autoinkrement skapar en databas där man har noll koll på dubbletter. Följaktligen komme rmånga dubbletetr att uppstå med tiden= sämre datakvalitet.

Ett generellt råd är att undvika autoinkrement så långt det är möjligt, använd istället naturliga primärnycklar i så stor utsträckning som möjligt, kombinera kolumner upp till ca 5-6 kolumner till PK vid behov. Först när det blir fler kolumner i PK ska man överväga att gå över till synttiska PK (autoinkrement är en form av syntetisk PK).

Senast redigerad av Conny Westh den 2010-06-18 klockan 10:50
Conny Westh är inte uppkopplad   Svara med citatSvara med citat
Oläst 2010-06-19, 12:17 #7
qson qson är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Sep 2006
Inlägg: 513
qson qson är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Sep 2006
Inlägg: 513
Jag håller på med en liknande lösning, och precis det du frågar om finns i MySQL, eller åtminstone i MyISAM-motorn.
I din tabell har du två kolumner: AnstalldId och RapportId.
Skapa sedan en PRIMARY KEY bestående av båda dessa kolumner
Kod:
PRIMARY KEY (AnstalldId, RapportId)
Sedan sätter du RapportId-kolumnen till auto_increment.
Då kommer MySQL/MyISAM att ha egna auto_increment-värden för varje AnstalldId. Du behöver då heller inte lägga in några värden för detta i SQL-frågan, utan sätt RapportId till NULL så fixar MySQL det själv.

Mer info:
http://dev.mysql.com/doc/refman/5.0/...increment.html
(tredje stycket)
qson är inte uppkopplad   Svara med citatSvara med citat
Oläst 2010-07-07, 00:26 #8
terbon terbon är inte uppkopplad
Medlem
 
Reg.datum: Jul 2008
Inlägg: 69
terbon terbon är inte uppkopplad
Medlem
 
Reg.datum: Jul 2008
Inlägg: 69
Citat:
Ursprungligen postat av qson Visa inlägg
Jag håller på med en liknande lösning, och precis det du frågar om finns i MySQL, eller åtminstone i MyISAM-motorn.
I din tabell har du två kolumner: AnstalldId och RapportId.
Skapa sedan en PRIMARY KEY bestående av båda dessa kolumner
Kod:
PRIMARY KEY (AnstalldId, RapportId)
Sedan sätter du RapportId-kolumnen till auto_increment.
Då kommer MySQL/MyISAM att ha egna auto_increment-värden för varje AnstalldId. Du behöver då heller inte lägga in några värden för detta i SQL-frågan, utan sätt RapportId till NULL så fixar MySQL det själv.

Mer info:
http://dev.mysql.com/doc/refman/5.0/...increment.html
(tredje stycket)
Tänkte tillägga lite, detta medför då att du inte får 2 primary keys som man kan tro. Utan du får en primary key som är kombination av dessa två. Alltså måste endast dessa tillsammans vara unika. Detta då du endast får ha en primärnyckel per tabell (som du även bör ha om det typ inte är en weak entity tabell eller kopplingstabell som du kan läsa om, om du letar lite om ER diagram).
terbon ä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 03:18.

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