Vinnaren i pepparkakshustävlingen!
2013-09-21, 21:28
  #1
Medlem
Hej!

Jag håller på med ett projekt som jag har stött på ett problem med. Det jag vill göra är en hemsida där jag kan lägga in koder i en databas för att sedan dela ut dem till användare. Databasen är uppdelad som exemplet under:

ID | Ägare | Kod
--------------------
1 | Anton| 512
2 | - | 632
3 | - | 743

Det jag gör på sidan är alltså att skriva in koder som sparas i databasen. De sparas då med Ägare "-". Det som nu ska göras är att när jag fyller i en ny användare så ska den användaren bli tilldelad den första i listan som just nu inte har någon Ägare. I exemplet ovan skulle det bli rad #2.

Hoppas att jag har lyckats förklara mitt problem väl nog för att ni ska kunna förstå.

Tack på förhand,
Pyret
Citera
2013-09-21, 21:54
  #2
Medlem
Jag lyckades till slut lösa problemet själv. Det var faktisk pinsamt enkelt. Löste det med:

SELECT * FROM table WHERE owner='-' ORDER BY ID LIMIT 1
Citera
2013-09-21, 23:08
  #3
Medlem
Bongomans avatar
Har du tagit hänsyn till race-conditions? Vad händer om två användare ska ha ut kod samtidigt? Kan olika få samma kod?
Citera
2013-09-21, 23:12
  #4
Medlem
fnirps avatar
Om man skulle göra en normaliserad lösning, så har du tre tabeller:

USER: user_id, user_name
CODE: code_id, code_string
USER_CODE: user_id, code_id

dvs du lägger till en rad i USER_CODE varje gång du tilldelar en användare en kod. Men ibland kan det vara bättre att förenkla tabellstrukturen och om man då gör som du gör är det bara nästan rätt. Använd NULL istället för -, så blir det tydligt att ingen användare har tilldelats den där koden.

CODE: code_id, user_id, code_string

SELECT *
FROM code
WHERE user_id IS NULL
ORDER BY ID
LIMIT 1

Som du ser använder jag mig av ett user_id-värde istället för namnet i klartext. En användares namn ska bara stå i klartext på ett ställe, i användartabellen. För vad händer annars om användaren byter namn? Byter du överallt i alla tabeller där namnet står i klartext? Det är risk för inkonsistens i databasen och sånt vill man undvika.
Citera
2013-09-21, 23:20
  #5
Medlem
fnirps avatar
Citat:
Ursprungligen postat av Bongoman
Har du tagit hänsyn till race-conditions? Vad händer om två användare ska ha ut kod samtidigt? Kan olika få samma kod?

Misstänker att det handlar om en webbsida och så länge det är en webbserver och en databasmotor som har hand om alla anrop, så kommer databasen, precis som webbservern att jobba seriellt. Men vill man säkra upp det hela kan man köra med transaktioner i databasen, eller kanske ännu bättre att generera koder on-the-fly istället.
Citera
2013-09-22, 01:06
  #6
Medlem
Citat:
Ursprungligen postat av fnirp
Om man skulle göra en normaliserad lösning, så har du tre tabeller:

USER: user_id, user_name
CODE: code_id, code_string
USER_CODE: user_id, code_id

dvs du lägger till en rad i USER_CODE varje gång du tilldelar en användare en kod. Men ibland kan det vara bättre att förenkla tabellstrukturen och om man då gör som du gör är det bara nästan rätt. Använd NULL istället för -, så blir det tydligt att ingen användare har tilldelats den där koden.

CODE: code_id, user_id, code_string

SELECT *
FROM code
WHERE user_id IS NULL
ORDER BY ID
LIMIT 1

Som du ser använder jag mig av ett user_id-värde istället för namnet i klartext. En användares namn ska bara stå i klartext på ett ställe, i användartabellen. För vad händer annars om användaren byter namn? Byter du överallt i alla tabeller där namnet står i klartext? Det är risk för inkonsistens i databasen och sånt vill man undvika.


Tack så mycket för tipsen! Ska ta en titt på min struktur.

Det kommer inte vara möjligt att byta namn. Det som sidan används till är att ge ut cd-keys till ett spel. Sidan kommer att användas till att registrera alla nycklar vi har, för att sedan ge ut nycklarna. Man ska alltså inte riktigt göra någonting med informationen i databasen förutom att hålla koll på vilka nycklar som är använda och inte.
Citera
2013-09-23, 10:35
  #7
Medlem
Bongomans avatar
Citat:
Ursprungligen postat av fnirp
Misstänker att det handlar om en webbsida och så länge det är en webbserver och en databasmotor som har hand om alla anrop, så kommer databasen, precis som webbservern att jobba seriellt. Men vill man säkra upp det hela kan man köra med transaktioner i databasen, eller kanske ännu bättre att generera koder on-the-fly istället.

Men webbservern arbetar parallellt och två processer kan starta samtidigt och gå om varandra i databasfrågorna. Då läggs de på kö i oordning och det skiter sig på riktigt. Denna typen av uttag och insättning görs endast under lås och med en non-autocommit.
Citera

Stöd Flashback

Flashback finansieras genom donationer från våra medlemmar och besökare. Det är med hjälp av dig vi kan fortsätta erbjuda en fri samhällsdebatt. Tack för ditt stöd!

Stöd Flashback