[ kukipei @ 07.03.2006. 16:55 ] @
Pozdrav.

Interesuju me vase ideje za cuvanje sahovskih pozicija u bazi.
Baza je relativno velika. Oko 750 000 partija.
Potrebno je da korisnik namesti poziciju na tabli i izvrsi pretragu u bazi.
Rezultat bi trebalo da budu sve partije koje sadrze datu poziciju.

ja sam nesto radio,

http://www.gensunasumus.com/explorer/explorer1.php

medjutim nisam zadovoljan brzinom.

Zelim da cujem vase ideje i iskustva,

Pozdrav i unapred hvala,
Predrag
[ NikolaVeber @ 07.03.2006. 17:08 ] @
Pa napisi kako si cuvao podatke (u kom obliku), kako si vrsio pretrazivanje, na kojim poljima imas indekse i tako to.
Moguce da ce onda neko imati predlog kako to poboljsati.

Sada mi pade na pamet da bi recimo mogao da cuvas broj figura na tabli u jednom polju i na njega stavis index i koristis kao prvi uslov, to bi moglo doneti neko poboljsanje (evenutualno broj crnih/belih odvojeno).

[Ovu poruku je menjao NikolaVeber dana 07.03.2006. u 18:09 GMT+1]
[ mulaz @ 07.03.2006. 17:10 ] @
http://www.xoops.org/modules/news/article.php?storyid=1596

pogledaj to.. amm.. nije nesto apmetno, ali isto on drzi podatke o poziciji figura u bazi, mozda nesto pomogne.. ali kako kaze onaj covek sa pinka.. ne moze da skodi :)
[ kukipei @ 07.03.2006. 18:36 ] @
Pozdrav,

Evo ovako. Svaka sahovska pozicija se moze predstaviti tzv. FEN notacijom.
npr FEN pocetne pozicije TSLDKLST/PPPPPPPP/8/8/8/8/pppppppp/tsldklst itd.
gde su velika slova crne figure a mala bele figure, brojevi oznacavaju prazna polja.

sada ja te pozicije pamtim u jednoj tabeli. Ona trenutno ima oko 21 000 000 slogova. Svaki od tih FEN-ova ima svoj ID. U drugoj tabeli imam zapamcenje partije u obliku niza ID fenova. Kolone te tabele su prvipotezbelog, prvipotezcrnog, drugipotezbelog itd...

Kada neko trazi poziciju najpre tu poziciju pretvorim u FEN pa trazim ID tog FEN-a, a zatim trazim gde se javlja taj ID i na taj nacin nalazim partije. Broj slogova druge tabele je oko 750 000.

Pretrazivanje FEN-a mi je po indeksima, a u drugoj tabeli nemam nigde indekse

[Ovu poruku je menjao kukipei dana 07.03.2006. u 19:38 GMT+1]
[ jablan @ 08.03.2006. 08:09 ] @
Dodaj u obe tabele ID partije, drugu indeksiraj po tom IDju.

Ako u drugoj za svaki potez imaš po kolonu, verovatno ti je bolje da sve poteze spakuješ u jednu kolonu, u neko tekst polje, ovako bacaš mnogo mesta.

Verovatno ti je prva tabela spora. Možeš probati sa savetom N. Vebera, da dodaš jedno indeksirano polje broj figura koje bi ubrzalo pretragu.
[ kukipei @ 08.03.2006. 09:46 ] @
Pozdrav,

Prva tabela je relativno brza, a njoj pristupam samo jednom, tako da to nije problem.
Citat:
jablan
Ako u drugoj za svaki potez imaš po kolonu, verovatno ti je bolje da sve poteze spakuješ u jednu kolonu, u neko tekst polje, ovako bacaš mnogo mesta.


Mislim da ce tada biti problema sa pretragom. Jer ja trazim ID fena u toj tabeli a ako u jednoj koloni imam tekst (vise ID fena), kako cu vrsiti pretragu.

Citat:
jablan:  Možeš probati sa savetom N. Vebera, da dodaš jedno indeksirano polje broj figura koje bi ubrzalo pretragu.


Ovako cu da probam.
Pozdrav i hvala
[ jablan @ 08.03.2006. 10:04 ] @
Citat:
kukipei: Mislim da ce tada biti problema sa pretragom. Jer ja trazim ID fena u toj tabeli a ako u jednoj koloni imam tekst (vise ID fena), kako cu vrsiti pretragu.

Iz prve tabele na osnovu fena izvučeš ID partije. Nađeš partiju u drugoj tabeli.
U drugoj tabeli u tekstualnom polju ne čuvaš ID fenova (da ne bi morao da radiš lookupe na prvu), nego redosled poteza.
[ noviKorisnik @ 08.03.2006. 12:13 ] @
Mislim - pogledaj računicu - imaš 750 hiljada partija, a 21 milion jedinstvenih pozicija, ako podelim to sa bojem partija dobijam da po partiji prosečno 26 jedinstvene pozicije. E sad, nemam predstavu kolika je prosečna dužina partije ... recimo da je 50 poteza, znači 100 pozicija.

I sam kažeš da nemaš nekih posebnih problema s prvom tabelom.

Ako bi druga tabela bila jednostavno - IdPartije, IdPozicije, RedniBrojPotezaUPartiji - po mojoj pretpostavci o prosečnoj dužini partije bi trebalo da ova tabela ima svega 4 puta više slogova od prve. Odavde je lako izvući pojedinu partiju, ili sve partije gde se javlja neka pozicija.

... inače, totalno mi je nejasna predstavljena postavka druge tabele, s mnogo kolona ... koliko ima tih kolona? Šta s partijom koja popuni sve kolone a nije još gotova, kako je sačuvati? Šta s nepopunjenim poljima kraćih partija, mnogo ih je? I konačno, najvažnije, ne postoji način za efikasno pretraživanje pozicija jer su razbacane po različitim kolonama!

Naravno, može dodatno da se optimizuje kad se uvede u sistem još tabela, recimo teorija otvaranja, pa bi se u tabeli partija (tamo gde su podaci o igračima, ko je beli a ko crni, gde se i kada igralo i slično) pamti i koje se otvaranje koristilo, pa bi se u tabeli toka partije (ova "druga" o kojoj se priča) pamtile tek pozicije nakon otvaranja (što bi značajno smanjilo broj slogova u toj tabeli). itd
[ flighter_022 @ 08.03.2006. 20:54 ] @
Mozda nije najbolje optimizovano, ali ovako na brzinu, ja bih uradio sledece:

Tabela sahista

-IdSahiste
-Ime
-Ostali podaci po potrebi

Tabela partija

-IdPartije
-SahistaBeli (ID sahiste)
-SahistaCrni (ID sahiste)
-OstaliPodaci (po potrebi)

Tabela poteza

-IdPoteza
-Idpartije (iz tabele partija)
-64 polja tipa BYTE (gde su figure predstavljene vrednostima 1-16 za bele figure, i 17-32 za crne, a 0 za prazno polje)
-DatumPoteza
-VremePoteza
-IdSahiste (koji je izvrsio potez)

Ovo je prilicno pojednostavljeno. Mozda bi deo sa 64 polja mogao dodatno da se optimizuje (jer za jedno polje na tabli nije potrebno svih 8 bitova, vec 5, ali bi to nepotrebno komplikovalo ceo sistem a i opterecivalo server koji bi to sve dekodovao).

Na ovaj nacin, bilo bi moguce pregledati partije i poteze po bilo kojem kriterijumu, ukljucujuci pretragu po zadatom stanju na tabli.

E sad, koliko bi baza zauzimala? Pa recimo da zaglavlje partije zauzima 64 bajtova (ili manje), da podaci o svakom sahisti zauzimaju 128 bajtova, i da svaki potez zauzima dodatnih 128 bajtova. Ako imas 10.000 sahista, 750.000 partija, sa prosecno 100 poteza (50+50), onda bi to bilo:

1250 KB za podatke o sahistima
46875 KB za podatke o partijama
93750 KB za podatke o potezima
---------------------------------------
141875 KB (138 Mb)

Ova kolicina podataka ne ukljucuje indekse... Sa indeksima, mozda bi poraslo do 400 Mb
[ kukipei @ 16.03.2006. 20:55 ] @
Pozdrav.

Izvinjavam se sto se ranije nisam javio. Bio sam nesto zauzet.


Ovo je struktura baze koju trenutno koristim:

CREATE TABLE `fenovi` (
`ID_fena` int(20) NOT NULL auto_increment,
`fen` varchar(100) binary NOT NULL default '',
`pob` mediumint(11) NOT NULL default '0',
`por` mediumint(11) NOT NULL default '0',
`ner` mediumint(11) NOT NULL default '0',
PRIMARY KEY (`ID_fena`),
UNIQUE KEY `fen` (`fen`)
) ENGINE=MyISAM;
CREATE TABLE `igrac` (
`ID_igraca` int(11) NOT NULL auto_increment,
`ime` varchar(35) NOT NULL default '',
`broj` smallint(4) NOT NULL default '0',
PRIMARY KEY (`ID_igraca`),
KEY `ime` (`ime`(10))
) ENGINE=MyISAM;
CREATE TABLE `otvaranja` (
`eco_kod` char(3) NOT NULL default '',
`naziv` varchar(60) NOT NULL default '',
`potezi` varchar(150) NOT NULL default '',
PRIMARY KEY (`eco_kod`)
) ENGINE=MyISAM;
CREATE TABLE `partija` (
`ID_beli` mediumint(11) NOT NULL default '0',
`ID_crni` mediumint(11) NOT NULL default '0',
`turnir` varchar(50) NOT NULL default '/',
`site` varchar(50) NOT NULL default '/',
`datum` varchar(10) NOT NULL default '0000.00.00',
`rezultat` char(3) NOT NULL default 'nul',
`round` tinyint(3) NOT NULL default '0',
`ECO` char(3) NOT NULL default '/',
`belirejting` smallint(4) NOT NULL default '0',
`crnirejting` smallint(4) NOT NULL default '0',
`ID_partije` int(11) NOT NULL auto_increment,
`potezi` text NOT NULL,
`god` smallint(4) NOT NULL default '0',
PRIMARY KEY (`ID_partije`),
KEY `ECO` (`ECO`),
KEY `ID_beli` (`ID_beli`),
KEY `ID_crni` (`ID_crni`),
KEY `god` (`god`)
) ENGINE=MyISAM;
CREATE TABLE `s_fen` (
`ID_partije` int(11) NOT NULL default '0',
`w1` int(11) NOT NULL default '0',
`b1` int(11) NOT NULL default '0',
`w2` int(11) NOT NULL default '0',
`b2` int(11) NOT NULL default '0',
`w3` int(11) NOT NULL default '0',
`b3` int(11) NOT NULL default '0',
`w4` int(11) NOT NULL default '0',
`b4` int(11) NOT NULL default '0',
`w5` int(11) NOT NULL default '0',
`b5` int(11) NOT NULL default '0',
`w6` int(11) NOT NULL default '0',
`b6` int(11) NOT NULL default '0',
`w7` int(11) NOT NULL default '0',
`b7` int(11) NOT NULL default '0',
`w8` int(11) NOT NULL default '0',
`b8` int(11) NOT NULL default '0',
`w9` int(11) NOT NULL default '0',
`b9` int(11) NOT NULL default '0',
`w10` int(11) NOT NULL default '0',
`b10` int(11) NOT NULL default '0',
`w11` int(11) NOT NULL default '0',
`b11` int(11) NOT NULL default '0',
`w12` int(11) NOT NULL default '0',
`b12` int(11) NOT NULL default '0',
`w13` int(11) NOT NULL default '0',
`b13` int(11) NOT NULL default '0',
`w14` int(11) NOT NULL default '0',
`b14` int(11) NOT NULL default '0',
`w15` int(11) NOT NULL default '0',
`b15` int(11) NOT NULL default '0',
`w16` int(11) NOT NULL default '0',
`b16` int(11) NOT NULL default '0',
`w17` int(11) NOT NULL default '0',
`b17` int(11) NOT NULL default '0',
`w18` int(11) NOT NULL default '0',
`b18` int(11) NOT NULL default '0',
`w19` int(11) NOT NULL default '0',
`b19` int(11) NOT NULL default '0',
`w20` int(11) NOT NULL default '0',
`b20` int(11) NOT NULL default '0',
`w21` int(11) NOT NULL default '0',
`b21` int(11) NOT NULL default '0',
`w22` int(11) NOT NULL default '0',
`b22` int(11) NOT NULL default '0',
`w23` int(11) NOT NULL default '0',
`b23` int(11) NOT NULL default '0',
`w24` int(11) NOT NULL default '0',
`b24` int(11) NOT NULL default '0',
`w25` int(11) NOT NULL default '0',
`b25` int(11) NOT NULL default '0',
`rez` tinyint(1) unsigned NOT NULL default '3',
`eco` char(3) NOT NULL default '0',
`god` smallint(4) unsigned NOT NULL default '0',
PRIMARY KEY (`ID_partije`)
) ENGINE=MyISAM;

najbitnije tabele su (tabele koje najvise koristim prilikom pretrage)
s_fen i fenovi

s_fen ima oko 750000 slogova
a fenovi vise od 20 miliona

pa ako nekog interesuje neka pogleda.


Citat:
flighter_022: E sad, koliko bi baza zauzimala? Pa recimo da zaglavlje partije zauzima 64 bajtova (ili manje), da podaci o svakom sahisti zauzimaju 128 bajtova, i da svaki potez zauzima dodatnih 128 bajtova. Ako imas 10.000 sahista, 750.000 partija, sa prosecno 100 poteza (50+50), onda bi to bilo:

1250 KB za podatke o sahistima
46875 KB za podatke o partijama
93750 KB za podatke o potezima
---------------------------------------
141875 KB (138 Mb)

Ova kolicina podataka ne ukljucuje indekse... Sa indeksima, mozda bi poraslo do 400 Mb


Jesi li siguran da je racunica tacna. Po meni ispada oko 9 GB.
128 B * 750000 = 96 000 000B (93750 KB) * 100 = 8.9 GB

Pozdrav
[ noviKorisnik @ 16.03.2006. 21:35 ] @
Nijedna partija nema više od 25 poteza?
[ kukipei @ 16.03.2006. 21:50 ] @
Naravno da ima,

Ali zbog velicine baze moguce je pretrazivati samo prvih 25 poteza.
Nisam uspeo da smislim bolji nacin
[ noviKorisnik @ 16.03.2006. 22:59 ] @
Pogledaj moj prethodni post onda. Evo malo da probam da pretočim u strukturu prema ovome što si priložio:

Tabela 'fenovi' : ID_fena i fen (ovo ostalo su ti statistike, nije mi baš jasno da je to potrebno držati, bar ne tu, možda u posebnoj tabeli

Tabela 'igrač' : ok, čuvaj šta hoćeš, treba ti ID_igrača za partije samo, ostalo po volji

Tabela 'otvaranja' - preskočiću u ovoj analizi

Tabela 'partija' : osnovno da ima svoj ID i da definiše ko je beli a ko crni

Tabela 's_fen' : ID_partije, ID_fena i redni broj poteza u partiji (složeni ključ od sve 3 kolone)

Ti sad hoćeš da nađeš sve partije u kojima je odigran neki potez ... vidiš da je trivijalno. Pored toga, partija može da ima i više od 25 poteza, a nema praznih polja u tabeli ukoliko je partija kraća.
[ noviKorisnik @ 17.03.2006. 08:26 ] @
uf pardon, u 's_fen' je ključ ID_partije i redni broj poteza ...
[ kukipei @ 17.03.2006. 15:09 ] @
Cini mi se kao dobra ideja

Pozdrav
[ NikolaVeber @ 10.04.2006. 20:19 ] @
Verovatno je kasno, mozda i pomenuto u predhodnim postovima: kako bi bilo cuvati poteze kao pocetno i krajnje polje?

Tako bi za svaki potez umesto matrice 8x8 imao 2 vrednosti. Znaci imas id partije, broj poteza i pocetno i krajnje polje. Tako mozes jednoznacno rekonstruisati partiju, a velicina baze se znatno smanjuje.

Da, i sa partijom se mora cuvati i podatak ko je poceo partiju - crni ili beli.
[ Kalasnjikov @ 24.08.2006. 10:10 ] @
crni krajnje retko pocinje partiju! :D

Informacije o poziciji bi trebalo drzati na nivou bitova: svaka figura moze zauzimati jedno od 64 polja (6 bitova), imas max 32 figure, (6 razlicitih), pa puta 2 jer mogu biti i crne i bele, znaci 12 (4 bita), u proseku 16, znaci 16x(6+4) = 160 bitova, plus po bit za ko je na potezu i da li su vrsili rokadu, sto ce reci u proseku oko 163 bita po poziciji.