Structurare DB pentru o căutare eficientă

Salut.
Trebuie sa introduc +500k iteme intr-o baza de date.
Fiecare item va avea mai multe categorii.

id | item_title | item_cat | item_slug
1 | bla bla | [cat1],[cat2],[cat5] | bla_bla
2 | abc abc | [cat2],[cat5],[cat3] | abc_abc

E mai ok sa fac cautarea item-elor dupa id sau slug ? ( vreau sa am linkurile de genu site/item/item_slug)
Categoriile sunt ok asa sau sa fac un tabel separat gen
id | item_id | cat

PS : exista vreo clasa care sa-mi scoata din titlul/numele itemului cateva cuvinte pe care sa le folosesc ca tag-uri ?

Crezi că e posibil ca item_cat să fie gândit greșit? Eu aș pune categoriile în alte două tabele:

Tabela items:

item_id | item_title | item_slug

Tabela relații categorii:

rel_id | cat_id | for_item

Tabela categorii:

cat_id | cat_name | cat_slug

Astfel vei normaliza DB și vei avea numele unei categorii scris într-un singur loc.

3 Likes

De ce preferati sa scrieti cat_id in loc de id? Am observat asta destul de des in SQL. Daca tabelul este categorii, nu este deajuns sa folosesti doar id, name, etc? Sau imi lipseste ceva?

6 Likes

În orice BD făcut de mine nu există coloană cu denumirea id, ci absolut toate au element_id (user_id, contact_id etc.). Și nu doar coloanele de ID, ci absolut toate dintr-un tabel. De ce? În ce fac zi de zi este mereu nevoie de exporturi și prelucrări din BD (nu mereu la fel, deci nu se pot face neapărat standardizate) și 1-2 join-uri îți vor arunca în aer orice idee despre ce ai prin coloanele alea în Excel.

Singurele coloane care nu au prefix sunt created_at, updated_at și mai nou deleted_at, dacă tot am trecut prin documentația Laravel :smiley:

PS: Da, știu că poți face select […] as, dar experiența îmi spune că e mai rapidă metoda mea.

2 Likes

@gabe, pe langa ce a zis @iamntz, mare atentie la indecsi, ei fac diferenta!

Eu am folosit așa în exemplu pentru a fi mai ușor de citit și pentru a face mai ușor legătura între coloane. Ultima dată când am făcut un tabel am folosit id. Privind în urmă, aș zice că select ... as este motivul nr. 1 pentru care JOIN-urile au generat mereu confuzie (pentru mine)

@andySF zice că ORM-ul folosit de el se descurcă mai bine cu coloanele prefixate.

Daca vorbim strict de o relatie Many to Many (fara date atasate la relatie, gen cate elemente sunt intr-o categorie, pentru ca un count e prea incet), tabela de relatie are o cheie primara compusa ( cat_id, item_id - combinatia lor e unica) si atat.

id | item_name | item_slug
id | cat_name | cat_slug
cat_id | item_id

Cat despre primary key, la mine toate se numesc id doar in coloanele de relationare folosesc _id. Iar ORM-ul nu are nici o problema cu asta (Doctrine 2). Ah, si mai sunt si niste foreign keys prin exemplul asta, dar o luam usor: intai normalizarea.

1 Like

plus că mi se pare mai natural să scrii comanda.clientId = client.clientId decât comanda.clientId=client.id. Oricum este doar o preferință personală.

1 Like

Because wordpress. Personal ma induc foarte mult in eroare coloanele prefixate cu numelele tabelelui.
Iar in join deja folosesti tabel.coloana, de ce sa repeti numele tabelelui de doua ori? (client.client_id)

1 Like

După cum ziceam mai sus: pentru că la un export pentru prelucrarea datelor în care o să ai 2 join-uri vei avea 3 coloane ID. Baftă să le găsești p-alea de care ai nevoie sau să nu le încurci la un moment dat :slight_smile:

De acord cu @redecs în ceea ce privește baza de date (structură & cheie primară).

În ceea ce privește căutarea, ai putea compune URL-urile în formatul /{:id}-{:slug} (sau /{:slug}-{:id}) și să faci căutarea după ID, știind că primele (sau ultimele) cifre din URL reprezintă ID-ul.
Avantajul la treaba asta este că, dacă cineva trimite altcuiva un link iar tu îți dai seama între timp că ai greșit slug-ul și-l modifici, link-ul vechi va funcționa în continuare. Ba mai mult, la accesarea paginii poți verifica dacă slug-ul din URL e identic cu cel din baza de date, iar dacă nu, să faci un redirect cu status 301 (mutat permanent) la noua adresă.

2 Likes