Pretraživanje baze podataka kada polje u tablici ima više vrijednosti

Zanima me kako biste vi “najelegantnije” riješili ovaj problem:

  • Pretražuje se baza podataka sa točno određenom ključnom riječi (kw*).
  • Određeni redak u tablici može imati sljedeće vrijednosti: “lorem”, “lorem,ipsum”, “lorem,ipsum, …”.

Upit: “SELECT * WHERE kw = ‘lorem’” neće vratiti retke u kojima stoji npr. “lorem,ipsum”, a meni trebaju i ti retci :slight_smile:

%LIKE% - ne dolazi u obzir.
Listanje rezultata (cijele tablice) unutar petlje i provjeravanje (petlja u petlji) isto bih htio izbjeći, jer je moguće da će tablica imati i preko 10000 zapisa.
Kreiranje dodatnih polja (za lorem, za ipsum, …) za svaki moguć rezultat također nije opcija.

Ako ne možeš koristiti LIKE, onda ne možeš vršiti pretraživanje bez remodeliranja baze.

Ako želiš mijenjati model, trebaš uvesti tablicu ključnih riječi - nazovimo je K - u kojoj će svaka ključna riječ - “lorem”, “ipsum”, itd. imati vlastiti zapis i nekakav ključ (autonumber se čini kao najlogičnije rješenje).

Neka se ova izvorna tablica koja je sadržava polje “kw” zove T, onda treba uvesti tablicu relacije T_K koja će povezivati preko ključa 1 zapis iz tablice T s N zapisa iz tablice K.

Onda kažeš nešto kao:

SELECT DISTINCT 
    K_T.T_KEY
FROM 
    K_T 
    INNER JOIN 
    K
    ON
        K_T.K_KEY = K.K_KEY
WHERE
    K.KW = 'lorem'

Slično tome možeš reći i nešto poput
WHERE
K.KW IN ( ‘lorem’, ‘ipsum’, ‘dolor’ )


P.S. Čestitke na 100-tom postu.

[quote=“tsereg”]Ako ne možeš koristiti LIKE, onda ne možeš vršiti pretraživanje bez remodeliranja baze.

Ako želiš mijenjati model, trebaš uvesti tablicu ključnih riječi - nazovimo je K - u kojoj će svaka ključna riječ - “lorem”, “ipsum”, itd. imati vlastiti zapis i nekakav ključ (autonumber se čini kao najlogičnije rješenje).[/quote]
LIKE izbjegavam jer nije uvijek jasno koje bi rezultate mogao dati. Da, to polje bih mogao iskoristiti pri FULLTEXT pretrazi, ali vrijednosti polja su specifične, pa nisam siguran i u takav način pretrage.

Konkretno u bazi se spremi rezolucija slike (npr. “1024x768”). Sada upitom treba vratiti sve retke koji sadržavaju tu rezoluciju. Ali kako slika može imati više rezolucija tako sam odlučio to spremiti na ovaj način “1024x600,1024x768”. Tu nastaje problem. Ako pretražim pomoću LIKE naredbe nisam siguran kako će se interpretirati pretraga za npr. “800x600”, u slučaju i kada redak sadrži “1024x600”…

Tablica:
±-------±------------+
| imgID | rezolucija |
±-------±------------+
| 1 …| 1024x600 |
| 2 …| 1024x600,1024x768,1280x800|
| n …| — |
±-------------+

Također ne želim se ograničiti definiranjem konačnog broja rezolucija u toj tablici (npr. ubacivanjem posebnih polja: rezolucija1, rezolucija2, rezolucija3). Iako hosting ima neograničene resurse :zub: ne volim takav pristup.

Ne poznam odlično SQL sintaksu, pa sam mislio da možda postoji nešto jednostavno tipa “… WHERE rezolucija CONTAINS(exactly) ‘keyword’”. Dakle, najpametnije je izmjenit cijelu tablicu tako da to polje ima FULLTEXT index?

Nisam siguran da razumijem ovaj dio. Ključna riječ nije nigdje definirana, može biti bilo što, odnosno bilo koja rezolucija…

[quote=“tsereg”]

P.S. Čestitke na 100-tom postu.[/quote]
Nisam ni primjetio, hvala :slight_smile:

IMAGE := ( IMG_ID, IMG_CAPTION )
RESOLUTION := ( RES_ID, RES_VER, RES_HOR, RES_CAPTION )
IMG_RES := ( IMG_ID, RES_ID )

IMAGE
IMG_ID | IMG_CAPTION
-------+-------------------
1      | Planine u Arizoni
2      | Pogled iz aviona
3      | Lijepi desktop

RESOLUTION
RES_ID | RES_VER | RES_HOR | RES_CAPTION
-------+---------+---------+---------------------------------
1      | 640     | 480     | Standardna VGA
2      | 1280    | 1024    | Za 19" monitor
3      | 1024    | 768     | Za 17" monitor
5      | 1980    | 1080    | HDTV rezolucija
6      | 832     | 578     | Za mobitel KONČAR model "Jura"

IMG_RES
IMG_ID | RES_ID
-------+-------
1      | 2
1      | 5
2      | 1
2      | 2
2      | 3
3      | 2
3      | 6

SELECT
    IMG_ID
  , IMG_CAPTION
FROM
    (
        SELECT DISTINCT
            IMG_ID
        FROM
            IMG_RES
            INNER JOIN
            RESOLUTION
            ON
                IMG_RES.RES_ID = RESOLUTION.RES_ID
        WHERE
                RESOLUTION.RES_VER = 1024
            AND RESOLUTION.RES_HOR = 768
    ) T
    INNER JOIN
    IMAGE
    ON
        T.IMG_ID = IMAGE.IMG_ID

Alternative:

        WHERE
                RESOLUTION.RES_VER >= 1024
            AND RESOLUTION.RES_HOR >= 768
      
        WHERE
                RESOLUTION.RES_VER/RESOLUTION.RES_HOR = 4/3

        WHERE
                RESOLUTION.RES_VER IN ( 800, 1024 )

[quote=“TomislavS”]…Tu nastaje problem. Ako pretražim pomoću LIKE naredbe nisam siguran kako će se interpretirati pretraga za npr. “800x600”, u slučaju i kada redak sadrži “1024x600”…
[/quote]

Ako je MySQL, mozda ovako:http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_find-in-set

Već sam implementirao tsereg-ov prijedlog, ali ću definitivno prijeći na “FIND_IN_SET” :slight_smile:

Prednost tsereg-ovog pristupa je bolja kontrola i veća mogućnost manipulacije podacima (pretrage po x,y osima), ali kako meni to ne treba ova MySQL naredba je idealna.

Ako nekome bude trebalo:

Funkcija je stvarno kao da su je pisali za tebe. :slight_smile:

Međutim, provjeri je li ti po perfomansama brža od LIKE operatera.

[quote=“tsereg”]Funkcija je stvarno kao da su je pisali za tebe. :slight_smile:

Međutim, provjeri je li ti po perfomansama brža od LIKE operatera.[/quote]
:slight_smile:

Test - LIKE vs. FIND_IN_SET:

TEST
ID    | TITLE   | RESOLUTION
------+---------+------------
1     | naslov1 | random
...   | ...     | ...
5     | naslov5 | 800x600 ili *
...   | ...     | ...
n

U tablicu sam unio 5000 nasumičnih zapisa, s time da je svaka peta rezelocija 800x600, te otprilike u 10% slučajeva je umjesto 800x600 vrijednost zapravo *“1024x768,800x600,1280x800”. p.s. rezultat je bio gotovo isti i kada su vrijednosti bile samo “800x600” (bez *)…

Konačan rezultat (sa *):

LIKE         :: 1,000 rezultata, vrijeme 0.00078 sek
FIND_IN_SET  :: 1,000 rezultata, vrijeme 0.00072 sek
---

Rezultati predstavljaju prosjek 5 zasebnih mjerenja.
Upiti su slani preko phpmyadmin sučelja.

Koliko ja vidim, iako su brzine slične, zapravo radi dostatno brzo. Ili?

Da, neočekivano brzo… Za ono što meni treba je sasvim dovoljno.


Copyright © 2020 WM Forum - AboutContact - Sponsored by: Mydataknox & Webmaster.Ninja