29. juni 2004 - 13:25Der er
54 kommentarer og 1 løsning
Normaliserings spørgsmål
Jeg har en database, der rent meta-data mæssigt er ret så lille og overskuelig, men rent data-mæssigt er meget stor. Databasen består som den er nu af kun 1 tabel med 8 attributter og ikke andet. Databasen har kørt som testbase i en periode i en afdeling nu. Der ligger i øjeblikket over 1 million tupler i databasen, og når applikationen bliver rullet ud for alvor bliver dette mange-doblet. Så jeg satte mig ned og tænkte, selvom det måske er en meget lille tabel kan det nok godt betale sig at normalisere den ud for at spare data. Men jeg er ikke helt sikker på om det kan betale sig. Selve systemet er et filscannings system der gemmer filnavne på samtlige filer i hele virksomheden. (der er omkring 2000 ansatte) Så det bliver en pænt stor database rent datamæssigt som sagt. Informationerne jeg gemmer i databasen for hver fil er følgende: Ip|Computernavn|Dato|Sti|Filnavn|Extension|Size|type|
(Type indikerer om det er en klient eller en server vi har med at gøre. Gir bedre overblik for en bruger) Som sagt ligger det nu i én tabel, med en del redundante data. Fx. computernavn og ip står skrevet masser af gange. Så mit spørgsmål er om det ville kunne betale sig at dele tabellen op i flere vha normalisering. Jeg er kommet frem til følgende forslag selv:
Autonummerering|Ip|Computernavn|Type|
compId|Dato|Sti|Filnavn|Extension|Size|
Autonummerring er en primærnøgler compId svarer til disse numre, og agerer dermed fremmednøglen i filtabellen. Ville det kunne betale sig at lave det således, eller er der en smartere måde at gribe problematikken an på? Mvh. Bumle90
Teknologi, AI og forretning er i centrum på Computerworlds Cloud og AI Festival i København d. 18. og 19. september. Se hele programmet for den store konference om strategisk brug af Cloud og AI på: www.cloud-festival.dk
Det kan jo også ske, at samme filnavn ligger på flere af maskinerne. Det kunne f.eks. være filerne i C:\Windows. Der kan så eventuelt være forskellige datoer. Men med en måske lidt uortodoks link-tabel, kunne dette også laves i databasen. Så ville det komme til at se sådan ud:
compId i linktabellen er stadig fremmednøgle til computertabellen. filId i linktabellen er fremmednøgle til filtabellen, hvor filId er også er en autogenereret primærnøgle. Dato er flyttet over i linktabellen, for at man stadig kan angive en dato til hver enkel fil på hver enkel computer.
Rasmus' forslag er godt - hvis du kan styre ens filer. På den vis slipper du også billere i backup (der bør måske være en checksum - bare så du ikke får taget backup af den éne virus fil der er og så distribuere den til alle de andre.)
Jeg kan ikke lave en computertabel som er "statisk" da det vil forekomme at samme computer kan have forskellig ip... Men stadig er det jo relativt sjældent at en IP skifter
Hmm det blir jo så bare lidt svært eftersom filerne bliver slettet og skrevet ned i databasen igen ved hvert scan. Dvs. filerne får et nyt autonummer hver gang? Holder det?
Det mest smarte ved scanninger ville være kun at skrive ændringerne i databasen i stedet for at starte forfra hver gang. Men jeg kan godt se, at der er et problem der, hvis en fil er blevet slettet på en af maskinerne mellem to scanninger. Der må jeg sige, at jeg ikke lige har noget forslag...
Mit problem bliver jo også at vedligeholde den tabel der identificerer de enkelte computere da vi ikke har faste IPer...Så skal jeg lave noget med hvis ip/compnavn kombination findes skal der kun opdateres i filtabellen, ellers skal der opdateres i begge tabeller og compId i filtabellen skal nu knyttes til det nye autonummer der bliver tildelt når den nye ip/compnavn bliver lagt i i computertabellen. Bliver det ikke noget værre roderi mon? Spørgsmålet er om det overhovedet kan betale sig...Jeg kan simpelthen ikke gennemskue det
Der kommer jo alligevel til at være en trilliard tupler i den database, og feltet "sti" er defineret som en lang tekst. Altså en blob. Alene det felt kommer jo til at tage ufatteligt meget performance...Så måske så¨meget at det er ligemedet at ip/compnavn som er to almindelige tekstfelter og type som er en int, bliver gentaget en masse gange. Hvad siger I?
jamen det har de, men alligevel synes jeg bare det er sådan liiiidt du ved at lave ID på blot et computernavn. Så kunne man måske lave det på MAC adressen...men folk skifter jo konstant computere og dermed netkort....og så er man jo ligevidt
Hvorfor er stien en blob? Så vidt jeg husker (ret mig hvis jeg tager fejl) tillader hverken windows, dos, linux eller macos mere end allerhøjest 255 tegn (tror det ofte er det halve). Så en varchar skulle vel være alt rigeligt.
Og jeg tror stadig der er en del at spare ved at normalisere. Både i plads og i performance.
Performancemæssigt er spørgsmålet dog også - hvad gør du mest? Indsætter eller søger?
Endeligt kan man selvfølgelig blive helt praktisk og sige "if it works don't fix it". Lad lortet køre inditl det bliver en nødvendighed at ændre noget.
Du er en klog mand dadane :) Principperne er da i orden :P Der vil køre langt flest indsættelser eftersom der kun bliver administratortne dvs. 5-10 mennesker der kommer til at søge i den, og over 2000 computere hvis filer vil blive indsat. Hmmm ja..ser ud til du har ret i det med sti-længden. Jeg troede at det kun var mappenavnene der max måtte være 255 karakterer, og der måtte være vilkårligt mange mapper...Men kunne man ikke forestille sig at det snart bliver ændret?
Tjoeh, det er altid svært at forudsige hvilke ændringer andre laver, - men mon dog?
Bare af nysgerrighed, - hvad skal det bruges til?
Licenstjek? (Hvor mange har installeret program X version Y) Seriøsitetstjek (et enkelt billede er o.k. - men 537 billeder som alle starter med XXX er ikke)?
Ja, det må nok være det nederste. Det skal give administratorerne et overblik over hvilke filer der flourerer rundt i virksomheden...Om filerne ligger korrekt og om folk ikke sidder med et hav af piratkopier og ting og sager på deres computer...
Hele systemet har jeg faktisk lavet..og testen har kørt i et stykke tid i en afdeling på 30 ansatte....Der er så også nogle servere med osv. Men der ligger nu knap 1 million tupler i tabellen
så det er ret store mængder data at arbejde med...og også derfor jeg begyndte at spekulere lidt. Ikke fordi jeg havde da også tænkt de tanker inden jeg gik igang...men ville gerne have et produkt hurtigt på bordet Nu tænkte jeg bare at jeg for min egen skyld måske burde lave databasen stabil også, så jeg ikke får allemulige irriterende vedligeholdelsesproblemer sidenhen
Begrundelse: * jeg tror ikke at du kan detecte hvis en computer skifter navn og så er computerid overflødigt * sidsteIP giver også mening med DHCP * sidstescan på computer tillader at scanne computere på forskelligt tidspunkt men uden at gemme en tid per fil * de 4 felter i fil kunne faktisk godt være en sammensat PK men det synes jeg er for bøvlet derfor en autogenrated id
Jeg tænkte på om det evt. ville være smart at lave en form for checksum på sti+filnavn+extension. Så kunne man på en eller anden måde udnytte det for ikke at skrive de samme stier 1000 gange. Ville det være smart?
hmmm ja...hvordan ville man skulle lave det? Findes der algoritmer til at lave checksumme? Og hvad skulle jeg så sætte ind i databasen? Og hvad skulle jeg evt. lave checksum over?
Ville du så lægge fx. checksummen for stien som "filsti" inde i sti tabellen? Kunne man ikke med fordel også lave noget checksum på filnavn/ext/size tilsammen? og lægge de informationer ud i en tabel for sig, med en autogenereret ID som PK og i filtabellen skulle der så være en filID som FK der forbandt til den nye filtabel. Så man fik noget ala:
computer -------- navn,PK type sidsteIP sidstescan
sti --- id,PK checksum på(filsti)
fil --- id,PK Checksum på(filnavn,filext,size)
samling --- id,PK,autogenerate computer,FK->computer stiid,FK->sti filid,FK->filnavn,type og størrelse
okay, det har du jo nok ret i. Mht. at indsætte nye logs eller hvad man nu skal kalde dem i samlingstabellen. Så er jeg vel nødt til først at hive alle stier ud af sti tabellen, og derefter checke hvilken en jeg skal referere til vha. sammenligning af stier. eller kan man på en eller anden måde lave en join i en insert eller noget andet smart ?
Men der skal jo kun være en sti der hedder fx. C:\winnt På den måde kan alle der har en sådan sti referere til den...og der kan derved spares kolossale mængder data...Det er da skide smart
Kan du se hvad jeg gør galt her? Jeg vil bare hive en int ud af databasen
string sql3; printf("debug1"); sqlstr="SELECT ID FROM Files"; printf("debug2"); stat = SQLExecDirect(stmt,(SQLCHAR *)sqlstr,strlen(sqlstr)); if((stat!=SQL_SUCCESS)&&(stat!=SQL_SUCCESS_WITH_INFO)) { printf("Error in ExecDirect %i og %i\n",stat,SQL_ERROR); } printf("%i",linectr);
Okay, nu ser det ud til at køre... Endnu et tvivlspg. (Håber ikke jeg presser citronen for meget :) ) Mht. felterne filnavn,ext,size Lige nu ligger de som du forslog i den samlede tabel. Men her vil der givet vis også kunne spares en del da ufattelig mange filnavne vil være de samme. Samme filnavn,størrelse og extension. Ville det være smart at lægge hver ud i sin egen tabel, på samme måde som med stien og så have en reference i samlingstabellen, eller hvad? Sagen er jo nemlig den at man skal kunne søge på alle attributterne, så hvis man havde dem i hver sin tabel, måske med undtagelse af filstørrelse ville dette godt kunne lade sig gøre. Hvad siger du til denne ide? Det er jo sådan set bare en viderebygning til det du skrev
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.