09. februar 2004 - 10:05
Der er
8 kommentarer og
1 løsning
Opbygning af simpel database
Hej
Jeg er rimelig grøn udi MySQL-databaser, men skal have lavet en der kan holde styr på, om en bruger har downloadet bestemte filer. Grunden til dette, er at der skal vises en bestemt side inden downloadningen begynder hvis filen ikke er blevet downloadet før.
Relationen er: 1 bruger kan downloade mange filer.
Hvordan skal strukuren se ud?
Skal der være 2 tabeller, 1 med bruger og 1 med filnavne? Hvordan forbindes de så?
Kan man nøjes med en tabel, der så indeholder et brugerfelt og en "multivalue" filnavnsfelt? Jeg er ikke sikker på at der er noget der hedder multivalue i MySQL - det er noget jeg har fra Lotus Notes, som er en anden måde at lave databaser på...
Jeg har adgang til phpMyAdmin!
Er der en eller anden der kan mig opskriften på hvordan jeg klarer den opgave??? Ved ikke om der mangler nogle oplysninger ellers må I sige til.
På forhånd tak!
Mvh
Pede
09. februar 2004 - 11:44
#1
Du burde næsten oprette det i kategorien MySQL fremfor Microsoft SQL Server (MS SQL).
Men en løsning - Verbalt: En bruger kan downloade MANGE filer. EN fil kan downloades af MANGE brugere. Relationen mellem filer og brugere er derfor en MANGE til MANGE relation - og det kræver en tabel.
Struktur ser så således ud
brugertabel (
id,
brugernavn )
filtabel (
id,
filnavn )
brugerogfiler (
bruger_id,
fil_id
)
Nu kan du så i tabellen brugerogfiler registere når bruger_id 1 har downloadet fil_id 1 etc.
Løsningen er i øvrigt 3 tabeller. En med brugere, en med fil navne og en der viser hvilke brugere der har downloadet hvilke filer.
09. februar 2004 - 13:25
#4
I så tilfælde kan du godt undlade id-felterne - men brugerogfiler skal så være baseret på brugernavn og filnavne - og det fylder jo mere.
En anden ting er, om fx dine brugernavne er unikke eller blot meta-unikke. Hvis en bruger sletter sig sin konto - kan en anden bruger så senere oprette en konto med samme brugernavn?
Hvis ja - så er de ikke rigtig unikke - og det samme gør sig gældende med filnavnene.
09. februar 2004 - 16:00
#5
Både brugernavne og filnavne er ikke længere end 8 characterer, så det kan vel godt betale sig at droppe ID'erne. Men nu hvor vi er ved det, er det så overhovedet nødvendigt med brugerhotel- og filhoteltabellerne? De indeholder jo ikke mere, end hvad der i forvejen kommer til at ligge i brugerogfilertabellen...
09. februar 2004 - 23:12
#6
Jeg vil foreslå at du lige checker op på relationelle databaser og normalisering - men kort:
Kun at gemme brugernavn og filnavn giver ikke rigtig mening - jeg forudsætter at du for brugere gemmer brugernavn og adgangskode samt dato/tid for oprettelse af brugerkontoen og for filer gemmer filnavn, størrelsen, brugeren der har uploaded den og datoen det skete.
Vi sætter så at du lader definitionerne for hver felt være:
Brugernavn, 8 tegn, typisk 9 bytes (17 hvis Unicode)
Adgangskode, 8 tegn, typisk 9 bytes (17 hvis Unicode)
Brugeroprettet, datotidsfelt, typisk 8 bytes
Filnavn, 8 tegn, typisk 9 bytes (17 hvis Unicode)
Størrelse, heltal, typisk 4 bytes
UploadedAf, 8 tegn, typisk 9 bytes (17 hvis Unicode)
UploadedDen, datotidsfelt, typisk 8 bytes
Ok, det lyder jo ganske rimeligt, men lad os kigge videre.
Hvis der ikke anvendes unicode, så fylder en bruger altså maximalt 26 bytes og hver fil fylder maksimalt 30 bytes.
Hvis du så har f.eks. 1.000 filer og 1.000 brugere og du ønsker i én tabel at registere alle brugeres download af de enkelte filer - så vil den ene tabel altså komme til at indeholde 1000 x 1000 = 1.000.000 rækker.
Dvs at tabellen så kommer til at fylde (26+30)*1.000.000 = 56.000.000 bytes = ca. 52 MBytes!
Problemet er, at du får gentagne oplysninger - alle brugeroplysninger og filoplysninger skal stå i hver enkelt række. Det er ikke særlig smart, bl.a. på grund af pladsforbruget og fordi du skal opdatere samtlige rækker hvori en fil indgår hvis du ønsker at opdatere filens informationer. Tilsvarende med brugere. Det er hvad man kalder en denormaliseret database.
Hvis du normaliserer databasen ved at splitte de redundante oplysninger ud i separate tabeller som vis herunder, så bliver pladsforbruget med de samme oplysninger ret anderledes.
brugerid, heltal, 4 bytes
Brugernavn, 8 tegn, typisk 9 bytes (17 hvis Unicode)
Adgangskode, 8 tegn, typisk 9 bytes (17 hvis Unicode)
Brugeroprettet, datotidsfelt, typisk 8 bytes
filid, heltal, 4 bytes
Filnavn, 8 tegn, typisk 9 bytes (17 hvis Unicode)
Størrelse, heltal, typisk 4 bytes
UploadedAf, 8 tegn, typisk 9 bytes (17 hvis Unicode)
UploadedDen, datotidsfelt, typisk 8 bytes
mange-til-mange relation (tabel brugerogfiler)
filid, heltal, 4 bytes
brugerid, heltal, 4 bytes
Brugerinfo fylder nu 30 bytes og filinfo 34 bytes. Med 1.000 af hver fylder det så hhv ca. 30 KBytes og 34 Kbytes. Mange-til-mange relationen fylder så 8*1.000.000 bytes (plus det løse) ca. 8 MBytes. Totalt fylder den normaliserede database 8.1 MBytes.
Altså en pladsbesparelse på 44 MBytes og den fordel at informationer nu kun skal rettes et sted. Du kan endda vælge at tilføje informationen om hvornår hver enkelt download har fundet sted (datotidsfelt, 8bytes pr række) og stadig kun bruge lidt over 16 Mbytes.
Okay, der bruges så plads til indeks i den normaliserede database - det giver bl.a. væsenligt højere hastighed til når data læses og skrives, men ovenstående burde egentlig besvare dit spørgsmål.
09. februar 2004 - 23:29
#7
hmm - i øvrigt, i den normaliserede database vil man typisk ikke lade brugernavnet på personen der uploadede en fil stå i tekst. Det kan nemlig rettes til en heltals-henvisning til brugerkontoen (en En-til-Mange relation) og så fylder filtabellen kun 29 Kb når der spares 5 bytes pr række.