Duomenų giminystės ryšiai PHP

Tarkime, kad prieš mus yra užduotis saugoti tėvus ir sūnus. Tarkime, kad kiekvienas tėvas gali turėti tik vieną sūnų, o sūnus savo ruožtu taip pat gali turėti vieną sūnų.

Reikia sugalvoti, kaip saugosime duomenis. Pirmoji mintis, kuri gali ateiti į galvą - sukurti dvi lenteles: parents tėvams ir sons sūnums. Tada susieti šias lenteles kokiu nors lauku: son_id arba parent_id.

Tačiau, ši idėja nėra labai gera - juk tas pats žmogus gali būti vienu metu ir tėvu, ir sūnumi - ir teks jį saugoti abiejose lentelėse, o tai nepatogu, užima daugiau vietos ir lengvai sukelia klaidų.

Geresnis variantas - susieti lentelę pačią su savimi: sukurkime lentelę users, joje saugokime visus vartotojus ir kiekvienam sukurkime lauką son_id, kuriame bus saugomas id sūnaus iš tos pačios lentelės:

users
id name son_id
1 user1 2
2 user2 3
3 user3 null

Užklausos

Dabar parašykime užklausą, kuri ištrauks vartotoją kartu su jo sūnumi.

Pirmiausia tiesiog ištraukime vartotojus:

sqlSELECT
  *
FROM
  users

Dabar prijunkime prie vartotojų jų sūnus. Jungti reikės lentelę pačią prie savęs, todėl mums reikia atlikti jos pervadinimą:

sqlLEFT JOIN users as sons

Dabar galime nurodyti pagrindinės lentelės ir pervadintos lentelės ryšį:

sqlLEFT JOIN users as sons ON sons.id=users.son_id

Dabar nurodykime laukus:

sqlSELECT
  users.name as user_name, sons.name as son_name

Sujunkime viską kartu ir gausime tokią užklausą:

sqlSELECT
  users.name as user_name, sons.name as son_name
FROM
  users
LEFT JOIN users as sons ON sons.id=users.son_id

Praktinės užduotys

Задание 1

Tarkime, kad turime kategorijas. Kiekviena kategorija gali priklausyti tėvinei kategorijai, ta savo ruožtu savo tėvinei kategorijai ir taip toliau. Aprašykite saugojimo struktūrą.

Задание 2

Parašykite užklausą, kuri ištrauks kategoriją kartu su jos tėvine kategorija.

Задание 3

Parašykite užklausą, kuri ištrauks kategoriją kartu su jos tėvu ir seneliu.

Задание 4

Parašykite užklausą, kuri ištrauks kategoriją kartu su jos tėvu, seneliu ir proseneliu.