Version 2 (modified by 3 days ago) ( diff ) | ,
---|
Напреден апликативен развој
Имплементирани се сите случаи на употреба дефинирани во фаза 3.
Примери на индекси
Индексите се користат за да се забрза извршувањето на често користени SELECT, JOIN и WHERE. Со оглед на тоа што во Travel Sage често пребаруваме активности според датум и корисник, се додаваат индекси врз тие колони.
- За побрзо пребарување на активности во одреден период
CREATE INDEX idx_aktivnost_datum ON aktivnosti(datum_od, datum_do);
- За побрз join и филтрирање по корисник при резервации
CREATE INDEX idx_rezervacii_korisnik ON rezervacii(idkorisnik);
- За побрзо пребарување на дестинации по име на локација
CREATE INDEX idx_destinacii_lokacija ON destinacii(imelokacija);
Примери за тригери
Тригерите се користат за автоматска реакција на промена во базата. Во TravelSage, тие се применети за: контрола на интегритет (нема дупли препораки) и автоматска реакција на негативна рецензија.
- Спречување дупли препораки
CREATE OR REPLACE FUNCTION prevent_duplicate_recommendation() RETURNS TRIGGER AS $$ BEGIN IF EXISTS ( SELECT 1 FROM preporaki WHERE idkorisnik = NEW.idkorisnik AND iddestinacija = NEW.iddestinacija ) THEN RAISE EXCEPTION 'User already has this destination in recommendations!'; END IF; RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE TRIGGER trg_check_duplicate_recommendation BEFORE INSERT ON preporaki FOR EACH ROW EXECUTE FUNCTION prevent_duplicate_recommendation();
- Деактивирање дестинација со негативни рецензии
CREATE OR REPLACE FUNCTION check_negative_review() RETURNS TRIGGER AS $$ BEGIN IF NEW.ocenka < 3 THEN UPDATE destinacii SET aktivna = FALSE WHERE iddest = NEW.iddest; END IF; RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE TRIGGER trg_negative_review AFTER INSERT ON recenzii FOR EACH ROW EXECUTE FUNCTION check_negative_review();
Примери за прегледи
View се користи за да се поедностават комплексни пребарувања.
- Во TravelSage, прикажани се активности што се „најдобра вредност за пари“, базирано на цена и просечна оцена од рецензии.
CREATE VIEW best_value_activities AS SELECT a.idaktivnost, a.ime, a.iznos, d.imelokacija, AVG(r.ocenka) AS avg_rating FROM aktivnosti a JOIN destinacii d ON a.iddest = d.iddest JOIN recenzii r ON a.idaktivnost = r.idaktivnost GROUP BY a.idaktivnost, a.ime, a.iznos, d.imelokacija HAVING AVG(r.ocenka) > 4 AND a.iznos < 1000;
- Активности со најниски цени
DB::statement(" CREATE VIEW view_procent_cheap_destinations AS SELECT d.imelokacija, COUNT(CASE WHEN a.iznos < 500 THEN 1 END) * 100.0 / COUNT(*) AS procent_cheap FROM travel_sage.destinacii d JOIN travel_sage.aktivnosti a ON d.iddest = a.iddest GROUP BY d.iddest, d.imelokacija ORDER BY procent_cheap DESC ");
Трансакции
- Пример при резервација на активност
DB::transaction(function () use ($request) { DB::table('rezervacii')->insert([ 'idkorisnik' => auth()->id(), 'idaktivnost' => $request->aktivnost_id, 'datum' => now() ]); DB::table('aktivnosti') ->where('idaktivnost', $request->aktivnost_id) ->decrement('kvota', 1); });
Ако не успее било кој дел (резервација или ажурирање на квота), не се зачувува ништо – атомичност.
-
DB::transaction(function () use ($request) { $validatedData = $request->validate([ 'imepaket' => 'required|string|max:255', 'cena' => 'required|numeric', 'pochetok' => 'required|date_format:Y-m-d\TH:i', 'kraj' => 'required|date_format:Y-m-d\TH:i|after_or_equal:pochetok', ]); TravelPackage::create($validatedData); });
-
DB::transaction(function () use ($request) { $validatedData = $request->validate([ 'naziv' => 'required|string|max:255', 'vidovi' => 'required|string|max:255', 'detali' => 'nullable|string', 'pochetendatum' => 'required|date', 'kraendatum' => 'required|date', ]); TravelEvent::create($validatedData); });
-
DB::transaction(function () use ($request) { $validatedData = $request->validate([ 'imeaktivnost' => 'required|string|max:255', 'informacii' => 'nullable|string|max:255', 'kategorija' => 'required|string|max:255', 'iznos' => 'nullable|numeric', ]); TravelActivity::create($validatedData); });
Складирани функции и процедури
- Просечна оцена за локација (функција)
CREATE OR REPLACE FUNCTION avg_rating_for_location(dest_id INT) RETURNS FLOAT AS $$ DECLARE result FLOAT; BEGIN SELECT AVG(ocenka) INTO result FROM recenzii WHERE iddest = dest_id; RETURN result; END; $$ LANGUAGE plpgsql;
- Додади препорака (процедура)
CREATE OR REPLACE PROCEDURE dodadi_preporaka(p_korisnik INT, p_dest INT) LANGUAGE plpgsql AS $$ BEGIN INSERT INTO preporaki(idkorisnik, iddestinacija, datum) VALUES (p_korisnik, p_dest, NOW()); END; $$;
Овие складирани елементи се користат за централизирана логика и можат да се повикаат од Laravel или други процедури.