SQL: Queries II, Constraints & Triggers (Chap. 5 – Ramakrishnan)
Pokok Bahasan Apa yang termasuk dalam bahasa SQL? Bagaimana queries disajikan dalam SQL? Bagaimana makna suatu query dinyatakan dalam standar SQL? Bagaimana SQL menjadikan aljabar dan kalkulus relasional sebagai dasar dan memperluas keduanya? Apa yang dimaksud dengan “grouping”? Dan bagaimana ia dapat digunakan dalam operasi-operasi aggregasi? Apa yang dimaksud dengan “nested queries”? Apa yang dimaksud dengan null values ? Bagaimana queries dapat digunakan utk menuliskan integrity constraints yang komplek? Apa yang dimaksud triggers, dan mengapa triggers menjadi berguna? Dan bagaimana kaitan triggers dan integrity constarints?
Dapatkan age dari sailor termuda dengan usia 18 untuk setiap rating yang minimal mempunyai 2 sailors (dari sembarang usia) SELECT S.rating, MIN (S.age) FROM Sailors S WHERE S.age >= 18 GROUP BY S.rating HAVING 1 < (SELECT COUNT (*) FROM Sailors S2 WHERE S.rating=S2.rating)
Menunjukkan bahwa HAVING clause juga dapat berisikan sebuah subquery. Apa yang terjadi jika HAVING clause deganti dengan: HAVING COUNT(*) > 1 Dapatkan ratings yang mempunyai rata-rata age paling rendah dibandingkan semua ratings yang ada Solusi yang SALAH: operasi-operasi aggregasi tidak boleh digunakan dalam nested query!
Solusi yang benar: SELECT S.rating FROM Sailors S WHERE S.age = (SELECT MIN (AVG (S2.age)) FROM Sailors S2 GROUP BY S2.rating) Solusi yang benar: SELECT Temp.rating, Temp.avgage FROM (SELECT S.rating, AVG (S.age) AS avgage FROM Sailors S GROUP BY S.rating) AS Temp WHERE Temp.avgage = (SELECT MIN (Temp.avgage) FROM Temp)
Null Values Nilai-nilai fields dalam sebuah tuple kadang-kadang tidak diketahui (unknown) (Misal, sebuah nilai rating tidak diberikan) atau tidak dapat digunakan (inapplicable) (Misal, tidak mempunyai nama isteri/suami). SQL menyediakan nilai spesial null utk keadaan-keadaan tersebut. Adanya nilai null dapat menimbulkan beberapa komplikasi. Sebagai contoh:
Null Values Operators spesial diperlukan utk melakukan pengecekan apakah nilai null atau not null. Diperlukan 3-valued logic (true, false dan unknown). Bagaimana dengan penggunaan penghubung AND, OR dan NOT? Makna dari bentukan-bentukan query harus didefinisikan dengan cermat. (misal, WHERE clause akan mengeliminasi baris-baris yang tidak dievaluasi dengan nilai true)
Null Values dan Operator Perbandingan serta Konjungsi AND, OR dan NOT Perbandingan dua nilai null menggunakan operator perbandingan , , , , , selalu menghasilkan nilai unknown SQL menyediakan sebuah operator perbandingan khusus IS NULL atau IS NOT NULL untuk melakukan pengujian apakah nilai dari suatu kolom adalah NULL atau NOT NULL NOT unknown dievaluasi unknown
Null Values dan Operator Perbandingan serta Konjungsi AND, OR dan NOT OR dari dua buah argumen akan dievaluasi: true jika salah satu argumen bernilai true false jika kedua argumen bernilai false unknown jika satu argumen dievaluasi false dan argumen lainnya dievaluasi unkwon AND dari dua buah argumen akan dievaluasi: false jika salah satu argumen bernilai false true jika kedua argumen bernilai true unknown jika satu argumen dievaluasi true dan argumen lainnya dievaluasi unknown
Dampak Null Values pada Bentukan SQL Untuk kualifikasi dalam WHERE clause, keberadaan null values mengakibatkan sembarang baris yang menghasilkan evaluasi false atau unknown harus dieliminasi Eliminasi baris-baris yang menghasilkan evaluasi unknown, walaupun tidak kentara tetapi dapat mempunyai dampak yang signifikan pada SQL querires, terutama nested queries yang melibatkan EXISTS atau UNIQUE
Dampak Null Values pada Bentukan SQL Persoalan lain dalam kaitan dengan keberadaan null values adalah definisi kapan dua baris dalam sebuah nilai relasi dianggap duplikasi Definisi SQL menyatakan bhw dua baris dinyatakan duplikasi bilamana nilai kolom-kolom yang bersesuaian adalah sama atau berisi nilai null Dalam kenyataan, perbandingan dua buah nilai null menggunakan operator “=“ akan menghasilkan nilai unknown; dimana untuk kontek duplikasi, perbandingan ini secara implisit akan diperlakukan sebagai nilai true (yang merupakan anomali !!)
Dampak Null Values pada Konsepsi SQL (Lanjutan) Operasi-operasi aritmatika +, -, *, dan /, semuanya menghasilkan nilai null jika salah satu argumennya bernilai null Null values dapat menimbulkan kelakukan yang tidak diharapkan untuk operasi-operasi aggregasi COUNT (*) memperlakukan null values seperti halnya nilai-nilai lainnya (ikut diperlhitungkan) Operasi-operasi aggregasi lainnya (COUNT, SUM, AVG, MIN, MAX, dan variasi penggunaan DISTINCT) mengabaikan null values
Null Values dan Outer Joins SQL menyediakan operasi yang disebut outer joins yang merupakan varian dari operasi join yang bergantung pada null values Dalam operasi [inner] join, tuples yang tidak memenuhi kondisi join tidak muncul dalam hasil Dalam outer join, baris-baris yang tidak memenuhi kondisi join muncul dalam hasil dengan kolom-kolom yang tidak memenuhi kondisi diberikan null values Terdapat tiga variasi outer join: Left outer join, baris-baris dari relasi pertama yang tidak mempunyai matching dengan baris dalam relasi kedua muncul dalam hasil Right outer join, baris-baris dari relasi kedua yang tidak mempunyai matching dengan baris dalam relasi pertama muncul dalam hasil Full outer join, baris-baris yang tidak mempunyai matching dalam relasi kedua muncul dalam hasil Dalam SQL, jenis join yang diinginkan dispesifikasikan dalam FROM clause: SELECT S.Sid, R.bid FROM Sailors S NATURAL LEFT OUTER JOIN Reserves R
Tidak Membolehkan Null Values Null values dapat tidak dibolehkan untuk muncul dengan menspesifikasikan NOT NULL sebagai bagian dari definisi field- field yang diinginkan. Contoh: sname CHAR(20)NOT NULL Selain itu, fields dalam primary key tidak diperbolehkan bernilai null Untuk ini terdapat constraint implisit NOT NULL untuk setiap field yang dinyatakan dalam PRIMARY KEY constraint Pembahasan null values dalam bab ini jauh dari lengkap. Bagi yang ingin mengetahuinya secara lebih rinci dapat mengacu ke beberapa buku yang secara khusus membahas tentang SQL
Integrity Constraints (Review) Sebuah IC menjelaskasn kondisi yang harus dipenuhi oleh setiap legal instance dari suatu relasi. Inserts/deletes/updates yang melanggar IC tidak diperbolehkan. Dapat digunakan utk menjamin semantik dari aplikasi (misal, sid adalah sebuah key), atau mencegah terjadinya inkonsistensi (misal, sname hrs berupa string, age harus < 200) Jenis IC: Domain constraints, primary key constraints, foreign key constraints, general constraints. Domain constraints: Nilai-nilai field harus dari tipe data yang benar. Harus selalu dipaksakan . 5
Domain Constraints & Distinct Types Sebuah domain baru dapat didefinisikan menggunakan statement CREATE DOMAIN dan CHECK constranits CREATE DOMAIN ratingval INTEGER DEAFULT 1 CHECK (VALUE >= 1 AND VALUE <= 10) Begitu sebuah domain telah didefinisikan, nama domain dpt digunakan dalam deklarasi sebuah skema Sebuah distinct type dapat didefiniskan dalam SQL/99: CREATE TYPE ratingtype is INTEGER Nilai-nilai dengan tipe ratingtype dapat dibandingkan satu dengan lainnya Namun, nilai-nilai dengan tipe ratingtype akan diperlakukan berbeda dengan nilai tipe-tipe lainnya yang sejenis (termasuk nilai-nilai dari tipe sumbernya, INTEGER)
General Constraints pada Satu Tabel Tunggal CREATE TABLE Sailors ( sid INTEGER, sname CHAR(10), rating INTEGER, age REAL, PRIMARY KEY (sid), CHECK ( rating >= 1 AND rating <= 10 ) General Constraints pada Satu Tabel Tunggal Bermanfaat bilamana melibatkan lebih banyak general IC Dapat menggunakan quries untuk mengekspresika n constraints Constraints dapat diberi nama. CREATE TABLE Reserves ( sname CHAR(10), bid INTEGER, day DATE, PRIMARY KEY (bid,day), CONSTRAINT noInterlakeRes CHECK (`Interlake’ <> ( SELECT B.bname FROM Boats B WHERE B.bid=bid))) 8
Constraints utk Multiple Relations Nampak aneh dan salah. Berkaitan dg Sailors, tapi melibatkan Boats! Jika Sailors kosong, jumlah Boats tuples dapat berupa sesuatu dan > 100 ! CREATE TABLE Sailors ( sid INTEGER, sname CHAR(10), rating INTEGER, age REAL, PRIMARY KEY (sid), CHECK ((SELECT COUNT (S.sid) FROM Sailors S) + (SELECT COUNT (B.bid) FROM Boats B)) < 100 ) Constraint: Jumlah boats plus jumlah Sailors hrs < 100 ASSERTION adalah solusi yang benar; tidak diasosiasikan dengan sutau tabel tertentu CREATE ASSERTION smallClub CHECK( ((SELECT COUNT (S.sid) FROM Sailors S) + (SELECT COUNT (B.bid) FROM Boats B)) < 100) 9
Triggers Trigger: procedure yang dipanggil secara otomatis oleh DBMS sebagai respon terhadap perubahan-perubahan dalam database, khusunya yang dispesifikasikan oleh DBA Deskripsi trigger terdiri dari 3 bagian: Event: Perubahan pada database yang mengaktifkan trigger Condition: Query atau pengujian yang dijalankan bilamana trigger diaktifkan Action: Prosedur yang dijalankan bilamana trigger diaktifkan dan kondisinya bernilai true Database yang memiliki satu set triggers disebut active database
Triggers dalam SQL/99 Basic events yang dapat dispesifikasikan untuk mentrigger sejumlah aturan (rules) adalah perintah-perintah SQL UPDATE standar: INSERT, DELETE, dan UPDATE. Untuk kasus UPDATE, attributes yang akan di-update dapat dinyatakan secara eksplisit Menyediakan row-level trigger dan statement-level trigger. Menggunakan clause FOR EACH ROW utk row-level, dan cluase FOR EACH STATEMENT utk statement-level Dapat menggunakan tuple/table variable name untuk mengacu ke tuples yang lama (old) dan baru (new) Dalam row-level trigger, clause REFERENCING digunakan untuk mengacu ke sebuah baris baru (yang baru disisipkan atau baru di-update) yang dinyatakan sbg new row variable name, sedang old row variable name digunakan utk mengacu ke sebuah baris lama (baris yang telah dihapus atau tuple lama sebelum dilakukan update) Dalam statement-level trigger, clause REFERENCING digunakan untuk mengacu ke tabel dari semua tuples baru (yang baru disisipkan atau baru di-update) sbg new table variable name, sedang old table variable name digunakan utk mengacu ke tabel dari semua tuples lama (tuples yang telah dihapus atau tuples lama sebelum dilakukan update)
Row-Level Trigger: Contoh-1 Tables: Employee (Name, SSN, Salary, Dno, Supervisor_SSN) Department (Dname, DNO, Total_Sal, Manager_SSN) CREATE TRIGGER TotalSal_1 AFTER INSERT ON Employee REFERENCING OLD ROW AS O, NEW ROW AS N FOR EACH ROW WHEN (N.DNO IS NOT NULL) UPDATE Department SET Total_Sal = Total_Sal + N.Salary WHERE DNO = N.DNO;
Row-Level Trigger: Contoh-2 Tables: Employee (Name, SSN, Salary, Dno, Supervisor_SSN) Department (Dname, DNO, Total_Sal, Manager_SSN) CREATE TRIGGER TotalSal_2 AFTER UPDATE OF DNO ON Employee REFERENCING OLD ROW AS O, NEW ROW AS N FOR EACH ROW BEGIN UPDATE Department SET Total_sal = Total_Sal + N.Salary WHERE DNO = N.DNO; UPDATE Department SET Total_sal = Total_Sal - O.Salary WHERE DNO = O.DNO END;
Row-Level Trigger: Contoh-3 Tables: Employee (Name, SSN, Salary, Dno, Supervisor_SSN) Department (Dname, DNO, Total_Sal, Manager_SSN) CREATE TRIGGER TotalSal_3 AFTER DELETE ON Employee REFERENCING OLD ROW AS O FOR EACH ROW WHEN (O.DNO IS NOT NULL) UPDATE Department SET Total_sal = Total_Sal - O.Salary WHERE DNO = O.DNO END;
Row-Level Trigger: Contoh-4 Tables: Employee (Name, SSN, Salary, Dno, Supervisor_SSN) Department (Dname, DNO, Total_Sal, Manager_SSN) CREATE TRIGGER Inform_Supervisor_1 BEFORE INSERT OR UPDATE OF Salary, Supervisor_SSN ON EMPLOYEE REFERENCING OLD ROW AS O, NEW ROW AS N FOR EACH ROW WHEN (N.Salary > ( SELECT Salary FROM Employee WHERE SSN = N.Supervisor_SSN ) ) inform_supervisor (N.Supervisor_SNN, N.SSN); //Diasumsikan “inform_supervisor” sebagai sebuah external procedure untuk memberikan notifikasi kepada supervisor
Statement-Level Trigger: Contoh-1 Tables: Employee (Name, SSN, Salary, Dno, Supervisor_SSN) Department (Dname, DNO, Total_Sal, Manager_SSN) CREATE TRIGGER TotalSal_4 AFTER UPDATE OF Salary ON EMPLOYEE REFERENCING OLD TABLE AS O, NEW TABLE AS N FOR EACH STATEMENT WHEN EXISTS ( SELECT * FROM N WHERE N.DNO IS NOT NULL ) OR EXISTS ( SELECT * FROM O WHERE O.DNO IS NOT NULL ) UPDATE Department AS D SET D.Total_Sal =D.Total_Sal + ( SELECT SUM (N.Salary) FROM N WHERE D.DNO = N.DNO ) - ( SELECT SUM (O.Salary) FROM O WHERE D.DNO = O.DNO ) WHERE DNO IN ( (SELECT DNO FROM N) UNION (SELECT DNO FROM O) );
Statement-Level Trigger: Contoh-2 Table: Sailors (sid, name, age, rating) CREATE TRIGGER youngSailorUpdate AFTER INSERT ON Sailors REFERENCING NEW TABLE NewSailors FOR EACH STATEMENT INSERT INTO YoungSailors(sid, name, age, rating) SELECT sid, name, age, rating FROM NewSailors N WHERE N.age <= 18
Statement-Level Trigger: Contoh-3 Table: Students (sid, name, age, gpa) CREATE TRIGGER setCount AFTER INSERT ON Students REFERENCING NEW TABLE AS InsertedTuples FOR EACH STATEMENT INSERT INTO StatisticsTable(ModifiedTable, ModificationType, Count) SELECT ‘Students’, ‘Insert’, COUNT * FROM InsertedTuples I WHERE I.age < 18
Active Databases: Mengapa Triggers Dpt Menjadi Sulit Dipahami? Dlm sebuah active database system, pada saat DBMS akan mengeksekusi suatu statement yang memodifikasi database, DBMS akan memeriksa apakah beberapa trigger diaktifkan oleh statement tsb. Jika ya, maka DBMS memproses trigger dengan cara mengevaluasi bagian kondisinya, dan (jika evalusai kondisi bernilai true) maka DBM akan mengeksekusi bagian action dari trigger Jika sebuah statement mengaktifkan lebih dari satu trigger, secara tipikal DBMS akan memproses semuanya dengan urutan sembarang. Sebuah trigger dpt mengaktifkan trigger lainnya, yang pada gilirannya trigger yang diaktifkan dpt mengaktifkan trigger yang sama yang disebut “recursive triggers”. Aktivasi triggers yang membentuk “rantai” dapat menimbulkan kesulitan untuk memahami efek yang dapat ditimbulkannya
Active Databases: Constraints v.s. Triggers Penggunaan triggers yang umum adalah untuk memelihara konsistensi database. Untuk ini kita harus selalu mempertimbangkan bahwa penggunaan sebuah IC (misal, FK constraint) dapat memenuhi tujuan yang sama Makna dari sebuah constraint tidak didefinisikan secara operasional (tidak seperti pengaruh sebuah trigger) Sifat ini menjadikan constraint lebih mudah untuk dipahami, dan memberi peluang bagi DBMS untuk mengoptimasi eksekusinya Constraint juga mencegah terjadinya inkonsistensi data oleh suatu statement. Beda dengan trigger yang diaktivasi oleh suatu statement yang spesifik (INSERT, DELETE, atau UPDATE). Hal ini menjadikan constraint lebih mudah dipahami Sebaliknya, triggers memungkinkan kita untuk memelihara database integrity dalam cara yang lebih fleksibel.
Rangkuman SQL menjadi faktor yang penting pada saat awal penerimaan model relasional, karena lebih natural dibandingkan bahasa-bahasa database sebelumnya yang bersifat prosedural (procedural query languages), seperti aljabar relasional. SQL lengkap secara rasional; bahkan dalam kenyataannya memiliki daya ekspresi yang signifikan dibandingkan aljabar relasional Bahkan, queries yang dapat dinyatakan dalam aljabar relasional seringkali dpt dinyatakan dengan lebih natural dalam SQL.
Rangkuman (Lanjutan) Terdapat banyak alternatif utk menulsikan sebuah query. Optimizer harus mencari rencana evaluasi yang paling efisien Dalam praktek, pengguna perlu memikirkan bagaimana queries dioptimalkan dan dievaluasi untuk memberikan hasil terbaik Nilai NULL untuk nilai-nilai field yang tidak diketahui (unknown) dapat menimbulkan banyak komplikasi SQL memungkinkan untuk menspesifikasikan berbagai jenis integrity constraints Triggers memberikan respon otomatis terhadap terjadinya perubahan-perubahan dalam database