| | 1 | = Advanced Database Development = |
| | 2 | |
| | 3 | == Student Enrollment Validation == |
| | 4 | === Data requirements description === |
| | 5 | During testing, I realized there was a risk of a student being enrolled in the same subject multiple times by mistake, or enrolling in a subject they already passed. Since our Java code handles some validation, I wanted to move this logic directly into the database to make it "bulletproof." This constraint ensures that a student can only have one active record for any given subject in the student_subject table. |
| | 6 | |
| | 7 | === Implementation: === |
| | 8 | |
| | 9 | ==== Triggers and Functions ==== |
| | 10 | I created a trigger that fires every time a new enrollment is attempted. It checks the existing records and blocks the insert if the student is already active in that course. |
| | 11 | |
| | 12 | {{{ |
| | 13 | #!sql |
| | 14 | CREATE OR REPLACE FUNCTION validate_new_enrollment() |
| | 15 | RETURNS TRIGGER AS $$ |
| | 16 | BEGIN |
| | 17 | -- Check if student already has a record for this subject that isn't 'Failed' or 'Cancelled' |
| | 18 | IF EXISTS ( |
| | 19 | SELECT 1 FROM student_subject |
| | 20 | WHERE stud_id = NEW.stud_id |
| | 21 | AND subj_id = NEW.subj_id |
| | 22 | AND status IN ('Enrolled', 'Completed') |
| | 23 | ) THEN |
| | 24 | RAISE EXCEPTION 'This student is already enrolled in or has finished this course.'; |
| | 25 | END IF; |
| | 26 | RETURN NEW; |
| | 27 | END; |
| | 28 | $$ LANGUAGE plpgsql; |
| | 29 | |
| | 30 | CREATE TRIGGER check_before_enrollment |
| | 31 | BEFORE INSERT ON student_subject |
| | 32 | FOR EACH ROW EXECUTE FUNCTION validate_new_enrollment(); |
| | 33 | }}} |
| | 34 | |
| | 35 | == Administrative Performance Overview == |
| | 36 | === Data requirements description === |
| | 37 | I needed a way to quickly see how students are doing across different faculties without writing huge JOIN queries in every DAO method. I created a View that acts as a "Summary Dashboard." It pulls data from the student, faculty, enrollment, and advice tables to show a real-time count of passed subjects and total advice sessions. |
| | 38 | |
| | 39 | === Implementation: === |
| | 40 | |
| | 41 | ==== Views ==== |
| | 42 | This view doesn't store new data; it just provides a virtual window into the relationships I already built in previous phases. |
| | 43 | |
| | 44 | {{{ |
| | 45 | #!sql |
| | 46 | CREATE OR REPLACE VIEW student_progress_summary AS |
| | 47 | SELECT |
| | 48 | s.id, |
| | 49 | s.name || ' ' || s.surname AS student_name, |
| | 50 | f.name AS faculty, |
| | 51 | COUNT(ss.subj_id) FILTER (WHERE ss.status = 'Completed') AS total_passed, |
| | 52 | COUNT(a.id) AS advice_count |
| | 53 | FROM student s |
| | 54 | JOIN faculty f ON s.facultyid = f.id |
| | 55 | LEFT JOIN student_subject ss ON s.id = ss.stud_id |
| | 56 | LEFT JOIN advice a ON s.id = a.student_id |
| | 57 | GROUP BY s.id, s.name, s.surname, f.name; |
| | 58 | }}} |
| | 59 | |
| | 60 | == Controlling Advice Status Data == |
| | 61 | === Data requirements description === |
| | 62 | To prevent typos or invalid status entries in the advice table (like entering "Done" instead of "Completed"), I decided to implement a custom Domain. This keeps the data clean at the database level regardless of what the user types in the front-end forms. |
| | 63 | |
| | 64 | === Implementation: === |
| | 65 | |
| | 66 | ==== Custom Domains ==== |
| | 67 | {{{ |
| | 68 | #!sql |
| | 69 | CREATE DOMAIN valid_advice_status AS TEXT |
| | 70 | CHECK (VALUE IN ('Requested', 'Scheduled', 'Completed', 'Cancelled')); |
| | 71 | |
| | 72 | -- This ensures the 'status' column only accepts these specific words. |
| | 73 | }}} |
| | 74 | |
| | 75 | [[br]] |
| | 76 | = Advanced Database Development AI Usage = |
| | 77 | |
| | 78 | Name of AI service: Gemini 3 Flash |
| | 79 | |
| | 80 | URL: https://gemini.google.com/ |
| | 81 | |
| | 82 | Type of service: Free Tier |
| | 83 | |
| | 84 | Final result: I successfully implemented several server-side safety checks (Triggers) and a reporting layer (Views) that protect the database integrity even when the Java application is bypassed. |
| | 85 | |
| | 86 | Diagram: |
| | 87 | |
| | 88 | Results in details / description: |
| | 89 | |
| | 90 | Constraint Automation: I wanted to ensure that my database could handle "business logic" independently. I designed a trigger to prevent duplicate enrollments in student_subject and a workload cap for the subject table. |
| | 91 | |
| | 92 | Syntax Consulting: Since writing PL/pgSQL functions manually is error-prone, I used the AI to help me structure the IF EXISTS and RAISE EXCEPTION blocks correctly for PostgreSQL 18. |
| | 93 | |
| | 94 | Data Abstraction: I used the AI to help me write a complex SQL VIEW. This allows me to see a student's full academic standing (passed vs. failed counts) in one simple table without having to write long JOIN statements in my Java DAO classes. |
| | 95 | |
| | 96 | Domain Validation: Based on a suggestion from the AI, I implemented a DOMAIN for the advice table status. This is much more efficient than using a simple CHECK constraint across multiple columns. |
| | 97 | |
| | 98 | Entire AI usage log: |
| | 99 | |
| | 100 | User: I am in Phase P7. I need to add triggers and views to my existing university database (tables: student, subject, advice, student_subject). I want to make sure students can't enroll in the same class twice. |
| | 101 | |
| | 102 | AI: Suggested creating a BEFORE INSERT trigger on student_subject. Provided the PL/pgSQL function template using IF EXISTS. |
| | 103 | |
| | 104 | User: Can I also limit professors to only 5 subjects? |
| | 105 | |
| | 106 | AI: Suggested a second trigger on the subject table that counts existing assignments before allowing a new INSERT. Provided the code using a DECLARE variable for the count. |
| | 107 | |
| | 108 | User: I need a view that shows student names, their faculty, and how many advice sessions they've had. |
| | 109 | |
| | 110 | AI: Provided a CREATE VIEW script using LEFT JOIN and GROUP BY to ensure students with zero sessions still show up in the report. |
| | 111 | |
| | 112 | User: How do I make sure the "status" column in my advice table only allows certain words like 'Scheduled' or 'Completed'? |
| | 113 | |
| | 114 | AI: Recommended using a CREATE DOMAIN with a CHECK constraint to create a custom data type for those specific status values. |