mboost-dp1

Array lignende struktur i DB?


Gå til bund
Gravatar #1 - KC
2. feb. 2010 22:16
Jeg skal i en DB gemme en gamestate. Denne state skal indeholde information om en række faktorer, problemet er at disse faktorer er variable. F.eks. skal den indeholde spillerens kort på hånden som kan være fra 0 til ca. 60.

Vil det være bedst at reservere 60 kolonner eller skal jeg indsætte kortene som rækker i en ny table og så have et ID i hver række som identificerer dem som samlet i den pågældende hånd? Med den ene mulighed vil jeg få en række pr. spiller, denne række vil blive stor, med den anden vil jeg få en masse rækker for hver spiller. Hvad vurderer i at være bedst rent praktisk og rent effektivit?
Gravatar #2 - myplacedk
2. feb. 2010 22:19
En "array-lignende struktur" hedder en "tabel" i en relationsdatabase.

Så: Lav en ny tabel, hvor du indsætter mellem 0 og ca. 60 rækker pr. spiller.
Gravatar #3 - røvskæg
2. feb. 2010 22:33
Alternativt hvad så med en række pr. spiller. Og så bare komma(el. lign.)- separere kortene. og så splitte/explode/andet det når du henter opslaget.

Du kunne også vende den rundt, nu hvor det gælder et spil kort, og så lave en row for hvert kort, og så hold styr på hvilken bruger der har det pågældende kort. Det vil udelukke fejl med dupletter af kort. Men det kommer vel an på hvilket slags spil det er du skal lave.
Gravatar #4 - arne_v
2. feb. 2010 23:00
#3

NEJJJJJJJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

http://en.wikipedia.org/wiki/1NF
Gravatar #5 - KC
2. feb. 2010 23:11
arne_v (4) skrev:
#3

NEJJJJJJJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

http://en.wikipedia.org/wiki/1NF


Tak!

Ud fra det ser det ud til at løsningen er en masse rækker pr. spiller, med et ID og et kort i hver.
Gravatar #6 - røvskæg
2. feb. 2010 23:13
arne_v (4) skrev:
#3

NEJJJJJJJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

http://en.wikipedia.org/wiki/1NF


lol.

Det første foslag giver anledning til mange fejl, og gør det besværligt hvis man vil søge. Det udnytter ikke databasens funktioner, og man kunne lige så godt bruge en fil.

Synes da det andet forslag er meget fornuftigt. Det er simpelt og giver ikke anledning til fejl.
Gravatar #7 - arne_v
2. feb. 2010 23:29
#6

Hvad er "det andet forslag" ?
Gravatar #8 - røvskæg
2. feb. 2010 23:32
røvskæg (3) skrev:
Du kunne også vende den rundt, nu hvor det gælder et spil kort, og så lave en row for hvert kort, og så hold styr på hvilken bruger der har det pågældende kort. Det vil udelukke fejl med dupletter af kort. Men det kommer vel an på hvilket slags spil det er du skal lave.
Gravatar #9 - arne_v
2. feb. 2010 23:51
#8

Det kunne måske godt bruges.

Det var de komma separerede værdier der fik mig op af lænestolen.
Gravatar #10 - røvskæg
2. feb. 2010 23:56
arne_v (9) skrev:
Det var de komma separerede værdier der fik mig op af lænestolen.


Ja det kan jeg forstå.
Jeg har da aldrig før set dig reagere så følesesmæssigt.
Gravatar #11 - arne_v
3. feb. 2010 00:33
#10

Der er visse ting jeg opfatter som "blasfemiske" indenfor databaser.

Felter med kommaseparerede værdier.

Brug af SELECT MAX til enten at finde sidst indsatte id eller næste id.
Gravatar #12 - zin
3. feb. 2010 09:11
Hihi, we found one of arne's buttons. >=)
Gravatar #13 - themuss
3. feb. 2010 09:36
Lær dog noget normalisering, tåber!

Jeg har præcis samme knapper som arne_v åbenbart.
Gravatar #14 - Mort
3. feb. 2010 11:59
Om det bedst kan betale sig at indsætte 60 rækker, per spiller, i en tabel, eller om det bedst kan betale sig at indsætte en række som indeholder de 60 kort som et felt med binære data, kommer an på flere ting.

Ved at indsætte en række per spiller:
Så kan du ikke filtrere på indholdet af hver værdi. Du kan ikke søge på enkelte af værdierne, men kan kun få allesammen på en gang. Hvis du altid har brug for alle rækkerne på en gang, så giver dette god mening.

Du får ikke nogen former for validering på indholdet af dine binære data, så hvis du putter junk i dine binære data så får du lov til det.

Du skal selv definere et format til de 60 kort. Det kan feks være et XML dokument eller lignende.

Ved at indsætte 60 rækker per spiller:
Så får du flere entries i din database, hvilket giver langsommere søgetider. Hvis du ikke har tusindvis af spillere, så er det ikke sikkert det giver et problem.

Du kan søge i dine værdier og feks hente alle dine esser ud.

Du kan læse værdierne ved at bruge dit almindelige database værktøj.
Gravatar #15 - myplacedk
3. feb. 2010 12:26
Mort (14) skrev:
Ved at indsætte 60 rækker per spiller:
Så får du flere entries i din database, hvilket giver langsommere søgetider.

At lave dårligere design for at få bedre performance, kan sjældent betale sig. Den slags kræver generelt en meget god indsigt i hvad man laver, for ikke at ende med at gøre performance værre i stedet for bedre. Dette spørgsmål viser, at spørgeren ikke har denne indsigt.

Den performance-forbedringen der potentielt kan være at hente, kan meget nemt gå tabt igen. Fx. foreslår du et XML-dokument. At skrive til XML og læse fra XML kan rigtigt nemt tage meget længere tid, end den tid du sparer i databasen.

Derfor er mit råd næsten altid: Lav et godt teknisk design. Glem performance-problemer til du har dem.
Et godt teknisk design plejer i øvrigt at give en acceptabel performance. Et dårligt teknisk design plejer at give dårligere performance, flere fejl, og udvikling bliver sværere og sværere jo længere man kommer med projektet.
Gravatar #16 - mazing
3. feb. 2010 12:41
Hvis du bruger MySQL kunne du måske overveje at bruge SET datatypen..
http://dev.mysql.com/tech-resources/articles/mysql...

Det bryder selvfølgelig normaliseringen, men hvis det kan forsimple løsningen, er det måske værd at undersøge?

Er selv fan af normalisering, men kun til en vis grænse - du kan nemt ende med et design der er langt mere kompliceret hvis du hovedløst normaliserer til højre og venstre.
Gravatar #17 - illishar
3. feb. 2010 12:41
Det kommer an på brugen af de omtalte data. Den korrekte måde er med "en række per kort". Men i situationer hvor databasen primært bruges som lager, kan den ovenstående løsning gøre tingene ubrugeligt, hvis der er mange kort (flere end 60) og mange spillere.
Prøv at lav en database med grafiske (GIS) objekter. Hvert objekt har i snit 100-5000 vertices og der er omkring 5000-15000 objekter i hvert lag. (Et gennemsnitlig vektor-lag.) Og der er ca. 10-50 lag. Hvis hver vertex skal placeres i en række, så skal der hentes ca. 750M rækker ud, som forøvrigt er joinet med en objekttabel. Brugeren er faldet i søvn, lang tid før I rent faktisk kommer til renderingen. Hvis hvert objekt derimod kun består af en række (dvs. ikke nogen joins e.l.), så skal der kun hentes 10k rækker per lag. (Det er ingenting i forhold.)

Man behøver jo ikke gøre "normalisering" til det primære argument for at kaste penge efter Oracle. ;)
Gravatar #18 - myplacedk
3. feb. 2010 12:49
illishar (17) skrev:
Men i situationer hvor databasen primært bruges som lager

...skal man typisk ikke bruge en database. Filsystemet er rigtigt godt til at lagre data i.

Hvis man bruger en relationsdatabase til at lagre blobs i, i stedet for de relationelle data den er beregnet til, så gælder reglerne for godt design af relationsdatabaser ikke.

Igen: Man bruger teknologien til noget andet, end den er designet til. Det bør man overlade til de erfarne. Når begyndere gør sådan noget, er det typisk fordi de har taget en forkert beslutning, og bør gå lidt tilbage inden de kommer for langt ud af et sidespor.
Gravatar #19 - arne_v
3. feb. 2010 16:00
Mort (14) skrev:
Så får du flere entries i din database, hvilket giver langsommere søgetider.


Mjo.

table scan er O(n)
index som tree er O(logn)
index som hashtable er O(1)

Som udgangspunkt vil jeg betragte færre rækker som vejen til hurtigere søgninger.

Mort (14) skrev:
Hvis du ikke har tusindvis af spillere, så er det ikke sikkert det giver et problem.


Hvis det kun er tusinder så er der næppe problemer uanset hvad.

10000 spillere af 60 et eller andet af f.eks. 5 x 4 bytes er kun 12 MB. Hvilket kan ligge i RAM. Ja faktisk kan det ligge i L3 cache på en ordentlig database server.

100 millioner spillere kunne begynde at stresse lidt.
Gravatar #20 - arne_v
3. feb. 2010 16:09
#17

Jeg synes ikke at det er så umiddelbart indlysende at det er mange hurtigere at hente 10000 rækker af lad os sige 7.5 MB end 750 milioner rækker af 100 byte. Begge dele tager tid.

Det er muligvis lidt hurtigere, fordi man sparer noget per række overhead. Men at hente 75 GB data op fra en database tager lidt tid.
Gravatar #21 - Mort
3. feb. 2010 16:17
#20

Problemet med at gemme 60 rækker er ikke at det tager tid at hente datamængden ud. Problemet er at der skal slåes op 60 forskellige steder i tabellen og de 60 steder først skal findes.

Hvis du bruger et indeks er det naturligvis hurtigere at slå 60 poster op i indekset end i tabellen, men det er stadig markant hurtigere at slå 1 post op i enten en tabel eller et indeks end det er at slå 60 af dem op.

Skal man lave et godt design er det vigtigt at se på hvilket behov man har. Er der ikke et behov for at søge i eller relatere til data, så er der ikke nogen fordel ved at splitte de 60 kort op i 60 poster i databasen.

Eksemplet med GIS kortet er ganske udemærket. En binær datamængde som altid læses samlet, men som splittes ud over flere poster end nødvendigt, kan give et markant større overhead end nødvendigt, uden nødvendigvis at være til gavn.
Gravatar #22 - arne_v
3. feb. 2010 16:24
#21

Hvis databasen finder de rækker enkeltvist, således at det tager N gange så lang tid at finde N rækker end 1 række, så ja.

Men jeg tvivler på at der er nogen database relevant for problem stillingen der er så ringe. Både index og data pages caches.

Gravatar #23 - arne_v
3. feb. 2010 16:27
#20 & 22

Jeg skal måske lige understrege at jeg heller ikke kan se nogen grund til at splitte de GIS data ud i mange rækker.

Men jeg er lidt skeptisk overfor den store performance forbedring der blev antydet.

Jeg forventer mere en faktor 2 end en faktor 200.
Gravatar #24 - arne_v
3. feb. 2010 16:28
myplacedk (18) skrev:
...skal man typisk ikke bruge en database. Filsystemet er rigtigt godt til at lagre data i.


Ved store datamængder har databaser nogle administrative fordele fremfor filsystemer.
Gravatar #25 - illishar
3. feb. 2010 16:37
#23 Vi lavede faktisk en række tests på det givne felt, for et par år siden. Godt nok på en MS SQL server. Forskellen på de 2 scenarier var noget i retning af faktor 15. Så helt vildt var det heller ikke. (Men det var en afgørende forskel, på det pågældende projekts brugbarhed.)


... men en faktor 2 ville da også være et ganske godt boost, til et vilkårligt program ^^
Gravatar #26 - arne_v
3. feb. 2010 16:42
#25

En måling trumfer naturligvis mine forventninger.
Gravatar #27 - illishar
3. feb. 2010 16:44
Man kunne da håbe/forvente at en tilsvarende test på en Oracle ville give en bedre score til den normaliserede version.
Gravatar #28 - Saxov
3. feb. 2010 17:53
arne_v (9) skrev:
Det var de komma separerede værdier der fik mig op af lænestolen


arne_v (11) skrev:
#10

Der er visse ting jeg opfatter som "blasfemiske" indenfor databaser.

Felter med kommaseparerede værdier.

Brug af SELECT MAX til enten at finde sidst indsatte id eller næste id.

Jeg kan godt forstå dig, der er jo en grund til man har opfundet XML og BLOB's, kommaseperation holder jo ikke... :D
Gravatar #29 - arne_v
3. feb. 2010 18:29
#28

CLOB's og BLOB's er opfundet til atomiske data. Bare nogle store "atomer".

XML er noget problematisk i forhold til traditionel relationel tankegang.

Det hjælper dog lidt hvis databasen validerer mod schema og understøtter XPath.
Gravatar #30 - arntc
7. feb. 2010 01:47
#27 de-normalisering blev ikke "opfundet" for ingenting :P
Gå til top

Opret dig som bruger i dag

Det er gratis, og du binder dig ikke til noget.

Når du er oprettet som bruger, får du adgang til en lang række af sidens andre muligheder, såsom at udforme siden efter eget ønske og deltage i diskussionerne.

Opret Bruger Login