ugrás a tartalomhoz

Véletlenszerű kép lekérése

drext0r · 2013. Jan. 11. (P), 05.19
Szeretnék egy oldalon véletlenszerűen képeket megjeleníteni de nem egészen tudom, hogy hogyan tegyem ezt a képeket a webszerveren tárolom a képek adatai pedig adatbázisban vannak.

Én elsőre úgy gondoltam, hogy minden feltöltött kép kap egy id-t és akkor lekérem az adatbázisból a képeknél a legkisebb és a legnagyobb id-t szóval az első és az utolsó képet majd ezt a két számot berakom egy mt_rand()-ba és a véletlen szám alapján jelenítem meg a képet.

De aztán gondolkodtam és olyan problémák lehetnek, hogy az oldalon lehet képet törölni szóval ha a generált képnek az id-jét már törölték akkor nem fog megjelenni semmi szóval nem tudom, hogy tudnám ezt megoldani.

Ha valaki tudna segíteni ebben azt nagyon megköszönném.
 
1

ORDER BY RAND()

T.G · 2013. Jan. 11. (P), 07.47
Rögtön az adatbázisból is lekérhetsz véletlenszerűen képeket:
SELECT * FROM tbl_name ORDER BY RAND() LIMIT 1;
(feltételezve, hogy MySql-ről van szó)
2

rand nem biztos, hogy jó

szabo.b.gabor · 2013. Jan. 11. (P), 08.39
RAND() nem biztos, hogy jó. sok rekordnál lassú lehet.

mt_rand() végülis nem is rossz

SELECT *
FROM kepek
WHERE id>$randid
ORDER BY id
LIMIT 1
3

Jogos!

T.G · 2013. Jan. 11. (P), 10.19
Jogos, nagy elemszám esetében a két lekérés is gyorsabb, mint az order by rand()!
4

Viszont nem feltétlenül lesz

tgr · 2013. Jan. 11. (P), 23.32
Viszont nem feltétlenül lesz egyenletes az eloszlás, ha törölni is lehet képeket. Lehet egy külön oszlopot fenntartani erre a célra, amibe 0..mt_getrandmax() közötti véletlenszámot írsz a rekord létrehozásakor, és akkor egy lekérdezéssel lehet keresni (csak arra kell vigyázni, hogy ha a legnagyobb számnál is nagyobbat húzol, akkor a legkisebbet add vissza). Ha jól tudom, pl. a Wikipédia lap találomra funkciója így működik.
5

Random OFFSET

pkadam · 2013. Jan. 14. (H), 02.51
És ha az id-k helyett az elemek számát kérnéd le, majd a nulla és e közötti véletlen számmal OFFSET-elnéd a lekérdezést? (A maximum érték persze eggyel kisebb legyen, mert azzal OFFSET-elve nem talál semmit a MySQL.)

mt_rand(0,mysqli_num_rows($query)-1)
6

szerintem eddig ez a

szabo.b.gabor · 2013. Jan. 14. (H), 10.46
szerintem eddig ez a legjobb..
12

visszavonom. nagy offset-et

szabo.b.gabor · 2013. Jan. 15. (K), 09.58
visszavonom. nagy offset-et tényleg lassú lekérni.
7

Nem triviális méretű táblára

tgr · 2013. Jan. 14. (H), 12.52
Nem triviális méretű táblára nagyon rossz módszer, egyrészt InnoDB-n az összes sor megszámolása egy full index scant jelent, másrészt offset+limit darab sort kell lekérdezni hozzá, vagyis átlagosan a fél táblát végig kell mászni minden véletlen kiválasztáshoz.
8

full index scan?

eddig bírtam szó nélkül · 2013. Jan. 14. (H), 14.37
Nem full table scan-re gondoltál?
(lehet, hogy csak én vagyok lemaradva, de indexekkel kapcsolatban még nem találkoztam a kifejezéssel)
10

Nem, vagy nem feltétlenül,

BlaZe · 2013. Jan. 14. (H), 15.57
Nem, vagy nem feltétlenül, van full index scan. De ha pl a db postgresql < 9.2 (ha jól emlékszem 9.2) az MVCC miatt még csak nem is full index scan lesz, hanem full table scan, mert az index a közelmúltig nem tárolt tranzakció infót. Pl egy tizenmilliós táblán egy countnál már azért előfordulhat, hogy gondolkodási időt kér a db :)

Amúgy a kérdésfelvetésből én nem gondolnám, hogy performancia gondjai vannak a kérdezőnek. Ha meg mégis, akkor én inkább azt javasolnám, hogy a háttérben töltsön valami (daemon, cron, akármilyen process) egy queue-t, és abból rángassák ki a képeket a requestek, mintsem hogy minden requestkor akármivel is nekiessen egy monster táblának.
11

De ha pl a db postgresql <

BlaZe · 2013. Jan. 14. (H), 16.22
De ha pl a db postgresql < 9.2 (ha jól emlékszem 9.2) az MVCC miatt még csak nem is full index scan lesz, hanem full table scan, mert az index a közelmúltig nem tárolt tranzakció infót.

Az utókor kedvéért javítom magam :) A pg most sem tárol visibility infót az indexben, hanem egy visibility mapet használ, és az alapján képes index-only scant futtatni, ahol lehet. Viszont a 9.2-re jól emlékeztem :) Bővebben:
http://wiki.postgresql.org/wiki/What's_new_in_PostgreSQL_9.2#Index-only_scans
9

Hogy tárolod a képeket?Mit

eddig bírtam szó nélkül · 2013. Jan. 14. (H), 14.41
Hogy tárolod a képeket? (milyen struktúrában?)
Mit csinálsz a töröltekkel? (valóban törlöd őket vagy csak az adatbázisban jelölöd meg töröltként?)
Milyen mennyiségről van szó? (néhány száz, ezres, esetleg milliós nagyságrend?)

Azon törtem a fejem a válaszokat olvasva, hogy nem lenne-e gyorsabb, kisebb erőforrás igényű a fájlrendszerből válogatni véletlenszerűen, és az így megtalált kép adatait lekérni az adatbázisból...
13

Query szinte mindig gyorsabb

Pepita · 2013. Jan. 17. (Cs), 17.43
...nem lenne-e gyorsabb, kisebb erőforrás igényű a fájlrendszerből válogatni véletlenszerűen...
Szinte biztosan lassabb lenne.

Nagy rekordszám esetén én adnék pl. egy 'number' mezőt a rekordokhoz, ami egy unsigned int és unique. Egyébként random. A kép insert-kor kell ügyesen belőni (tranzakció), hogy véletlen legyen, de próbáljon újat, ha már beletrafált egy létezőbe. Lekéréskor pedig amelyik pl. nagyobb, mint egy pillanatnyi random, és LIMIT 1. Persze ehhez is tudni kell a maximumot, de nincs "esélytöbbszörözés", mint id esetén. (Illetve van, de az is véletlenszerű.)

Ez (sem) igazán tuti, de mindenképp MySql-oldalon érdemes megoldani, mert az a leggyorsabb.
14

Azt ne felejtsd el, hogy a

eddig bírtam szó nélkül · 2013. Jan. 17. (Cs), 18.02
Azt ne felejtsd el, hogy a fájlrendszerhez mindenképp hozzá kell nyúlni, ebből következően, minimum a könyvtárbejegyzések cache-ben lesznek.
Ha jól szervezi a könyvtárstruktúráját, előfordulhat, hogy gyorsabb lesz.
~30 éve a használt állományok valahogy úgy voltak felosztva, hogy soros, indexelt és ... már nem emlékszem a pontos elnevezésre, valami direct access v. hasonló.
Ez utóbbi úgy működött, hogy az azonosítóból ki lehetett számolni a rekord pontos helyét, emiatt nagyon gyors volt benne az azonosító alapú keresés. Na itt is valami hasonló megoldásra gondolnék. Nem lennék ennyire lusta, tán még össze is dobhatnék valami performancia tesztet. Persze mindehhez még ott van a fájlrendszer típusa is, ami szintén nem mindegy...

De a kérdező eltűnt, így merőben felesleges energiapazarlásnak tűnik a dolog.