Kuriant žiniatinklio programas, našumas yra vienas svarbiausių aspektų, į kurį reikia atsižvelgti. Duomenų gavimo iš duomenų bazės analizė yra geras atspirties taškas ieškant patobulinimų. Šiame straipsnyje rasite pavyzdžių, kaip pagerinti našumą naudojant suvestines funkcijas ir filtruojant duomenis duomenų bazės lygmeniu.
Pradžiai šiek tiek konteksto
Šį straipsnį įkvėpė reali problema, kurią man kartą teko spręsti. Jos sprendimas mane daug ko išmokė, ir aš vis dar turiu jį kaip nuorodą savo atmintyje. Manau, kad pavyzdžiai yra geras mokymosi šaltinis, jie gali daug ką paaiškinti. Šiame straipsnyje norėčiau pasidalyti keliais pavyzdžiais, kaip naudoti "Active Record" užklausų metodus.
Kad nepateikčiau su sritimi susijusių detalių, pavyzdžiams iliustruoti naudosiu bibliotekos pavyzdinę programą. Viskas gana paprasta, kaip parodyta toliau pateiktoje schemoje. Turime keturias lenteles: autorių, knygų, vartotojų ir nuomos. Vienas naudotojas gali pasiskolinti daug knygų, o vieną knygą gali pasiskolinti daug naudotojų, todėl mums reikia jungiamosios lentelės, kad galėtume modeliuoti santykius "daug-daug". Mūsų atveju tai lentelė Rentals. Joje taip pat saugome papildomą informaciją - skolinimosi ir grąžinimo datas. Autorius gali turėti daug knygų, priskirtų jo vardui. Knyga taip pat turi atributą, apibrėžiantį jos žanrą.
Naudotojo skaitymo statistika
Užduotis buvo parengti statistinius duomenis apie vieną vartotoją, kad galėtume pasakyti, kiek kiekvieno žanro knygų buvo pasiskolinta. Pirmoji mano mintis buvo paimti visas naudotojo pasiskolintas knygas, sugrupuoti jas pagal žanrą ir tada atlikti atvaizdavimą, kad kiekvienam žanrui būtų priskirtas knygų skaičius, o ne sąrašas. Štai ką sugalvojau:
Nors šis metodas veikia ir atrodo švarus, jis neišnaudoja visų "Active Record" užklausų metodų teikiamų galimybių. Jų dėka galime filtruoti ir agreguoti duomenys duomenų bazės lygmeniu, nenaudojant neapdoroto SQL tiesiogiai mūsų kodas. Darbas db lygmeniu taip pat didina mūsų efektyvumą.
Pirmiau pateiktame pavyzdyje vietoj "Ruby" metodo group galime naudoti metodą grouppagal metodą. Jis taikys GRUPĖSBY sąlyga prie tSQL užklausos. Be to, atvaizdavimo ir dydžio metodą galima pakeisti skaičiavimo agregavimo funkcija. Galiausiai gauname užklausą, kuri atrodo taip:
Book.joins(:rentals).where(rentals: { user: user }).group(:genre).count(:books)
Atrodo dar paprasčiau!
Kiti naudingi pavyzdžiai
Toliau rasite keletą kitų užklausos metodų naudojimo būdų, kuriuos, mano nuomone, verta žinoti.
Kvietimas neaktyviems naudotojams
UŽDUOTIS: Užduotis: Filtruoti naudotojus, kurie niekada nesiskolino knygos arba tai padarė daugiau nei prieš metus.
Galėtume gauti visus naudotojus, įtraukdami susijusius nuomotojus, ir tada juos filtruoti naudodami pasirinkimo metodą.
User.includes(:rentals).select do |user|
user.rentals.empty? ||| user.rentals.none? { ||nuoma| nuoma.start_date >= Date.today - 1.year }
end
Tačiau, žinoma, nebūtina parsinešti visko. Naudodami užklausos metodus galime filtruoti db lygmeniu. Pirmiausia atrinkime vartotojus, kurie per pastaruosius metus pasiskolino keletą knygų, ir tada pašalinkime juos iš galutinės atrankos.
UŽDAVINYS: Gaukite autorių, turinčių vieną arba nulį pasiskolintų knygų
Tai padaryti naudojant select metodą yra labai paprasta, tačiau vėlgi - nėra reikalo dirbti su tokiu dideliu duomenų rinkiniu, nes db gali jį filtruoti. mus:
Naudojant left_joins (ir apskritai išorines jungtis) svarbu prisiminti vieną dalyką. Jei kairėje lentelėje (čia: autoriai) yra įrašų, neturinčių atitinkamų įrašų dešinėje lentelėje (čia: knygos), dešinės lentelės stulpeliai bus užpildyti nulinėmis reikšmėmis.
Kadangi mums taip pat reikia autorių, kuriems sistemoje priskirta viena knyga, reikia atlikti dar kelias operacijas. Turėsime atlikti grupavimą, skaičiavimą ir pridėti sąlygą. Štai kaip visa tai sudėti:
Sąlyga pateikiama po apibendrinimo funkcijos, todėl jai nurodyti turime naudoti ne WHERE, o HAVING sąlygą.
Galvojant apie programos našumą verta patikrinti "Active Record" užklausų metodus. Jie gali supaprastinti jūsų kodą ir pagreitinti jo veikimą. Tikiuosi, kad pasidalyti pavyzdžiai padės jums ištirti užklausų metodų teikiamas galimybes.