Konsep Ketergantungan Fungsional, Ketergantungan Transitif, Normalisasi, dan Identifikasi Primary Key dalam Perancangan Sistem Database

Dalam posting tulisan tentang: “Tujuan dan Manfaat Normalisasi dalam Perancangan Database”, kita sudah mempelajari tentang: “Apa itu normalisasi” dan “Mengapa kita perlu melakukan normalisasi”. Kedua pertanyaan itu sudah terjawab dalam tulisan tersebut. Dalam posting tulisan ini, kita akan mempelajari bagaimana melakukan proses normalisasi dalam perancangan sistem basis data. Sebelum melakukan proses normalisasi kita perlu mempelajari dan memahami suatu konsep penting yang mendasari proses normalisasi, yaitu ketergantungan fungsional (functional dependecies) dan  ketergantungan transitif (transitive dependencies) antar atribut dalam suatu relasi. [Baca juga: Contoh proses normalisasi relasi dari UNF – 1NF – 2NF – dan 3NF]

Memahami Functional Dependency (Ketergantungan Fungsional) Antar Atribut dalam Suatu Relasi 

Konsep penting yang menjadi dasar melakukan normalisasi relasi-relasi dalam perancangan sistem database adalah functional dependency atau ketergantungan fungsional. Tanpa memahami konsep functional dependency atau ketergantungan fungsional kita tidak bisa melakukan proses normalisasi dengan baik dan benar. Functional dependency atau ketergantungan fungsional adalah suatu konsep yang menjelaskan tentang relationship/asosiasi/hubungan antara atribut-atribut dalam suatu relasi. 

Misalnya, jika A dan B adalah kumpulan atribut (bisa satu atau lebih atribut) dalam suatu relasi R, maka B disebut bergantung secara fungsional (functionally dependent) pada A (dituliskan dengan     A --> B), apabila setiap nilai A terasosiasi tepat dengan satu nilai dari B (ingat, A dan B adalah atribut-atribut di dalam relasi R). Representasi dalam bentuk diagramnya adalah seperti berikut:

Representasi dalam bentuk diagram, atribut-atribut B bergantung pada atribut-atribut A (A menentukan B)

Di dalam representasi functional dependency (atau kebergantungan fungsional A --> B), atribut-atribut yang disebelah kiri disebut dengan determinan. Jadi, representasi gambar di atas adalah: atribut-atribut B bergantung secara fungsional pada atribut-atribut A, dan atribut-atribut A disebut dengan determinan (atau A menentukan B).

Contoh functional dependency (kebergantungan fungsional) yang mengacu pada sampel data relasi ‘StaffBranch’ berikut:
Contoh relasi StaffBranch
Contoh ketergantungan fungsional antar atribut dalam relasi StaffBranch

Jika kita mengacu pada sampel data pada relasi di atas, maka kita bisa mengidentifikasi salah satu contoh functional dependency (kebergantungan fungsional) seperti berikut:

staffNo --> sName

sName --> staffNo

Namun identifikasi functional dependency seperti di atas adalah mengacu pada sampel data yang ada (data sementara saja) dalam relasi 'StaffBranch', sebaliknya apabila kita mempertimbangkan kemungkinan terhadap nilai data untuk semua nilai data pada masa-masa mendatang pada atribut 'staffNo' dan 'sName', maka identifikasi functional dependency yang benar seharusnya adalah

staffNo --> sName

Jadi cara terbaik untuk mengidentifikasi functional dependency adalah dengan memahami dengan baik tentang ‘arti/makna’ atau ‘semantik’ dari hubungan/relationship/asosiasi antar atribut (bukan hanya dengan mengalisa data sementara saja).

Functional dependency atau kebergantungan fungsional terdiri dari tiga jenis: 
  1. Full functional dependency (kebergantungan fungsional penuh)
  2. Partial dependency (kebergantungan sebagian)
  3. Transitive dependency (kebergantungan transitif)
Beberapa karakteristik dalam full functional dependency (kebergantungan penuh) adalah sebagai berikut:
  • Jumlah atribut yang menjadi determinan yang digunakan untuk menjaga ketergantungan atribut-atribut yang berada di sisi sebelah kanan, seharusnya seminimal mungkin. 
  • Bila A dan B adalah kumpulan atribut (bisa satu atau lebih atribut) di dalam suatu relasi, B disebut bergantung secara penuh (full functional dependency) pada A, apabila B bergantung secara penuh pada A, dan bukan bergantung pada subset/sebagian (salah satu atribut) A
  • Ada hubungan/relationship/asosiasi one-to-one antara atribut-atribut pada sisi sebelah kiri (determinan) dan yang di sisi sebelah kanan dari functional dependency
  • Harus benar/akurat sepanjang waktu (tidak hanya sementara waktu saja) untuk seluruh nilai data mendatang
Mari kita lihat contoh berikut ini dan masih mengacu pada relasi StaffBranch di atas:

staffNo, sName --> branchNo

contoh identifikasi functional dependency (kebergantungan fungsional) di atas adalah benar, karena setiap nilai dari (staffNo, sName) ter-asosiasi dengan tepat hanya satu nilai dari ‘branchNo’. Tetapi, ‘brachNo’ secara fungsional juga bergantung pada sebagian/subset dari (staffNo, sName), yaitu ‘staffNo’. Jadi contoh di atas ini adalah apa yang disebut sebagai partial depedency atau kebergantungan parsial/sebagian.

Selain full functional dependency (kebergantungan penuh) dan partial dependency (kebergantungan sebagian), satu lagi jenis kebergantungan yang perlu untuk didentifikasi adalah transitive dependency atau kebergantungan transitif.

Transitive dependency atau kebergantungan transitif adalah suatu kondisi dimana A, B, dan C masing-masing adalah kumpulan atribut (bisa satu atau lebih atribut) dalam suatu relasi sedemikian rupa sehingga apabila A --> B dan B --> C, maka C disebut bergantung secara transitif (transitively dependent) pada A melalui B, asalkan A tidak bergantung secara fungsional pada B atau C.

Mari kita lihat contoh functional dependency yang mengacu pada relasi ‘StaffBranch’ di atas:

staffNo --> sName, position, salary, branchNo, bAddress

branchNo --> bAddress

dalam contoh di atas, ‘bAddress’ bergantung pada ‘branchNo’, tetapi ‘branchNo’ juga bergantung pada ‘staffNo’. Maka bisa dikatakan bahwa ‘bAddress’ bergantung secara transitif pada ‘staffNo’ melalui 'branchNo'. Jadi transitive dependency (kebergantungan transitif) teridentifikasi pada contoh di atas.

Proses Normalisasi 

Setelah memahami konsep functional dependency atau ketergantungan fungsional, barulah kita bisa melakukan proses normalisasi. Jadi secara definisi, proses normaliasi adalah penerapan teknik formal yang digunakan dalam menganalisa suatu relasi berdasarkan primary key (kunci primer) dan functional dependency (ketergantungan fungsional) antara atribut-atribut dalam relasi tersebut.

Secara teori, bentuk normal suatu relasi bisa sampai ke tingkat lima 5NF, yaitu 1NF – 2NF – 3NF/BCNF – 4NF – 5NF. Tetapi secara praktik dalam dunia nyata, relasi dalam suatu database sudah dibilang baik kalau sudah mencapai 3NF (bentuk normal ketiga).
Tingkatan normalisasi
Proses normalisasi kita mulai dengan mengidentifikasi semua jenis functional dependency dalam suatu relasi. Pada umumnya kita memiliki relasi yang pada awalnya berada pada kondisi 1NF (bentuk normal pertama). Namun terkadang bisa juga kita menemui atau mulai dari keadaan UNF (unnormalized form). [Untuk contoh lebih detil tentang proses normalisasi bisa dipelajari dan dipahami dalam posting tulisan tentang: "Contoh proses normalisasi relasi dari UNF – 1NF – 2NF – dan 3NF"].

Bila relasi dalam kondisi 1NF (atau bentuk normal pertama), maka kita perlu mengidentifikasi keberadaan ‘partial dependency’. Bila ditemukan ‘partial dependency’ maka kita harus menghilangkan ‘partial dependency’ ini. Cara menghilangkan ‘partial dependency' adalah dengan memindahkan atribut yang bergantung secara parsial tersebut menjadi relasi yang baru beserta copy dari atribut atau determinant yang menjadi bagian dari primary key pada relasi asalnya. Bila semua relasi sudah tidak mengandung ‘partial dependency’ maka semua relasi sudah berada dalam kondisi 2NF (atau bentuk normal kedua). Untuk menuju ke 3NF, kita perlu mengidentifikai keberadaan ‘transitive dependency’ atau ketergantungan transitif. Apabila ditemukan adanya ‘transitive dependency’ atau ketergantungan transitif dalam suatu relasi, maka kita harus menghilangkan keberadaan ‘transitive dependency’ itu. Cara menghilangkan ‘transitive dependency’ adalah dengan memindahkan atribut-atribut yang bergantung secara transitif tersebut beserta ‘copy’ dari ‘determinant’ dari relasi orisinalnya ke suatu relasi yang baru. Bila semua relasi sudah tidak mengandung baik ‘partial dependency’ maupun ‘transitive dependency’, maka semua relasi itu sudah berada dalam 3NF.

Proses mengidentifikasi semua functional dependencies diantara semua atribut-atribut dalam suatu relasi akan menjadi mudah apabila kita memahami dengan baik semantik/arti/maksud dari setiap atribut dan relationship/asosiasi antara atribut-atribut itu. Keterangan atau informasi seperti ini seharusnya didapatkan dari perusahaan/organisasi dalam bentuk diskusi dengan para pengguna dan/atau dokumentasi, misalnya spesifikasi requirements dari para pengguna. Namun apabila informasi/keterangan seperti itu tidak ada maka si database desainer harus menggunakan logikanya dan/atau pengalamannya untuk mengidentifikasi semantik/arti/maksud dari atribut-atribut beserta relationship/asosiasi antar atribut tersebut.

Contoh proses identifikasi functional dependencies (ketergantungan fungsional) dalam relasi ‘StaffBranch’ di atas adalah seperti berikut:

staffNo --> sName, position, salary, branchNo, bAddress

branchNo --> bAddress

bAddress --> branchNo

branchNo, position --> salary

bAddress, position --> salary

catatan: dengan mencoba memahami semantik hubungan/asosiasi/relationship antar atribut dari relasi di atas kita berasumsi bahwa  posisi dan ‘branch’ atau cabang menentukan gaji atau ‘salary’ dari staff. 

Contoh lain – yaitu dengan menggunakan sampel data untuk mengidentifikasi functional dependencies:
contoh identifikasi ketergantungan fungsional dengan menggunakan sampel data dalam sampel relasi
Dari identifikasi di atas bisa kita dapatkan:

A --> C                                    (fd1)

C --> A                                     (fd2)

B--> D                                     (fd3)

A, B --> E                               (fd4)


Mengidentifikasi primary key dengan menggunakan functional dependency.

Selain untuk melakukan proses normalisasi, identifikasi functional dependencies juga digunakan untuk mengidentifikasi primary key. Jadi salah satu tujuan utama dalam mengidentifikasi berbagai functional dependency adalah juga untuk menetapkan integrity constraints (atau konstrain integritas) yang harus berlaku pada suatu relasi. Salah satu integrity constraint atau konstrain integritas penting yang perlu untuk dipikirkan pertama kali adalah identifikasi terhadap candidate keys, dimana salah satunya (kalau lebih dari satu) akan dipilih menjadi primary key dari relasi tersebut.

Jadi, apabila ada atribut yang menjadi determinan dan atribut ini menjadi determinan terhadap semua atribut yang lain dalam suatu relasi maka atribut ini akan dipilih sebagai ‘candidate key’. Dan apa bila ada beberapa ‘candidate key’ kita akan pilih salah satunya untuk menjadi ‘primary key’. 

Kembali pada contoh relasi ‘StaffBranch’, identifikasi terhadap relasi ini menghasilkan lima ketergantungan fungsional (functional dependency). Daftar determinan dari identifikasi tersebut adalah sebagai berikut:

staffNo, branchNo, bAdress, (branchNo, position), dan (bAddress,position)

kemudian, untuk mengidentifikasi candidate keys, kita perlu mencari dan menemukan atribut (atau kelompok atribut) yang secara unik bisa mengidentifikasi setiap baris dalam relasi tersebut. Dan semua atribut yang bukan bagian dari candidate key seharusnya bergantung secara fungsional pada candidate key ini. Jadi, untuk menemukan candidate key, kita perlu menemukan determinan dimana semua atribut lainnya bergantung pada determinan tersebut. Dalam relasi ‘StaffBranch’, satu-satunya candidate key dan karena itu berarti pasti menjadi primary key adalah ‘staffNo’, karena semua atribut yang lain dalam relasi itu bergantung pada ‘staffNo’. 

Dalam contoh lain yang mengacu ke sampel relasi di atas, daftar determinan dalam sampel relasi setelah identifikasi functional dependency seperti di atas adalah: 

A, B, C, dan (A,B)

Namun demikian, satu-satunya determinan yang menentukan semua atribut dalam sampel relasi tersebut adalah atribut (A,B). Maka atribut (A,B) dipilih sebagai primary key.

Kalau ingin bertanya silahkan posting di komentar. Terima kasih.

2 comments:

  1. kalau normalisasi pada kebutuhan dan kasus penggunaan bagaimana?
    sehingga bisa kita menegtahui kebergantungan antara kebetuhan dan kasus penggunaan..thanks..

    ReplyDelete
    Replies
    1. saya belum menangkap secara utuh maksud dari pertanyaan ini. Tetapi kalau maksudnya tujuan dan manfaat diterapkannya normalisasi bisa di baca di link ini: https://beritati.blogspot.com/2015/11/tujuan-dan-manfaat-normalisasi-dalam.html

      Delete