Anda di halaman 1dari 63

Diterjemahkan dari bahasa Inggris ke bahasa Indonesia - www.onlinedoctranslator.

com

BAB 14
Pengindeksan

Banyak kueri merujuk hanya sebagian kecil dari catatan dalam file. Misalnya, kueri seperti
"Temukan semua instruktur di departemen Fisika" atau "Temukan jumlah total kredit yang
diperoleh siswa denganIndo 22201” hanya merujuk sebagian kecil dari pengajar
atau murid catatan. Tidak efisien bagi sistem untuk membaca setiap tupel dalampengajar
kaitannya untuk memeriksa apakah nama departemen nilainya adalah "Fisika". Demikian juga, tidak efisien
untuk membaca keseluruhanmurid relasi hanya untuk menemukan satu tupel untuk Indo “22201”. Idealnya,
sistem harus dapat menemukan catatan ini secara langsung. Untuk mengizinkan bentuk akses ini, kami
merancang struktur tambahan yang kami kaitkan dengan file.

14.1 Konsep dasar

Indeks untuk file dalam sistem database bekerja dengan cara yang hampir sama seperti indeks
dalam buku teks ini. Jika kita ingin belajar tentang topik tertentu (ditentukan oleh kata atau frase)
dalam buku teks ini, kita dapat mencari topik dalam indeks di bagian belakang buku, menemukan
halaman di mana itu terjadi, dan kemudian membaca halaman. untuk menemukan informasi yang
kita cari. Kata-kata dalam indeks diurutkan, sehingga mudah untuk menemukan kata yang kita
inginkan. Selain itu, indeks jauh lebih kecil dari buku, semakin mengurangi upaya yang diperlukan.

Indeks sistem database memainkan peran yang sama seperti indeks buku di perpustakaan.
Misalnya, untuk mengambilmurid catatan yang diberikan Indo, sistem basis data akan mencari indeks
untuk menemukan blok disk mana1 catatan yang sesuai berada, dan kemudian mengambil blok disk,
untuk mendapatkan yang sesuai murid catatan.
Indeks sangat penting untuk pemrosesan kueri yang efisien dalam database. Tanpa indeks,
setiap kueri pada akhirnya akan membaca seluruh konten dari setiap relasi yang digunakannya;
melakukannya akan menjadi sangat mahal untuk kueri yang hanya mengambil beberapa catatan,
misalnya, satumurid catatan, atau catatan di mengambil hubungan yang sesuai dengan satu
siswa.

1Seperti pada bab sebelumnya, kami menggunakan istilah piringan untuk merujuk ke perangkat penyimpanan persisten, seperti disk magnetik dan solid-
state drive.

623
624 Bab 14 Pengindeksan

Menerapkan indeks pada murid hubungan dengan menyimpan daftar siswa yang diurutkan
Indo tidak akan bekerja dengan baik pada database yang sangat besar, karena (i) indeks itu sendiri
akan sangat besar, (ii) meskipun menjaga indeks diurutkan mengurangi waktu pencarian,
menemukan siswa masih bisa memakan waktu, dan (iii) memperbarui daftar yang diurutkan saat
siswa ditambahkan atau dihapus dari database bisa sangat mahal. Sebaliknya, teknik
pengindeksan yang lebih canggih digunakan dalam sistem database. Kita akan membahas
beberapa teknik ini dalam bab ini.
Ada dua jenis indeks dasar:

• Indeks yang dipesan. Berdasarkan urutan nilai yang diurutkan.

• Indeks hash. Berdasarkan distribusi nilai yang seragam di berbagai bucket. Bucket
tempat nilai ditetapkan ditentukan oleh suatu fungsi, yang disebut afungsi hash.

Kami akan mempertimbangkan beberapa teknik untuk pengindeksan berurutan. Tidak ada
satu teknik yang terbaik. Sebaliknya, setiap teknik paling cocok untuk aplikasi database tertentu.
Setiap teknik harus dievaluasi berdasarkan faktor-faktor ini:

• Jenis akses: Jenis akses yang didukung secara efisien. Jenis akses dapat mencakup
pencarian catatan dengan nilai atribut tertentu dan menemukan catatan yang nilai
atributnya termasuk dalam rentang tertentu.

• Waktu akses: Waktu yang diperlukan untuk menemukan item data tertentu, atau kumpulan item, dengan
menggunakan teknik yang dimaksud.

• Waktu penyisipan: Waktu yang diperlukan untuk memasukkan item data baru. Nilai ini mencakup waktu
yang diperlukan untuk menemukan tempat yang tepat untuk menyisipkan item data baru, serta waktu
yang diperlukan untuk memperbarui struktur indeks.

• Waktu penghapusan: Waktu yang diperlukan untuk menghapus item data. Nilai ini mencakup waktu yang
diperlukan untuk menemukan item yang akan dihapus, serta waktu yang diperlukan untuk memperbarui
struktur indeks.

• Ruang di atas kepala: Ruang tambahan yang ditempati oleh struktur indeks. Asalkan
jumlah ruang tambahan moderat, biasanya bermanfaat untuk mengorbankan ruang
untuk mencapai peningkatan kinerja.

Kita sering ingin memiliki lebih dari satu indeks untuk sebuah file. Misalnya, kita mungkin
ingin mencari buku berdasarkan penulis, subjek, atau judul.
Atribut atau kumpulan atribut yang digunakan untuk mencari record dalam file disebut a kunci
pencarian. Perhatikan bahwa definisi darikunci berbeda dari yang digunakan dalam kunci utama, kunci
kandidat, dan kunci super. Arti duplikat ini untukkunci (sayangnya) sudah mapan dalam praktiknya.
Menggunakan gagasan kami tentang kunci pencarian, kami melihat bahwa jika ada beberapa indeks
pada file, ada beberapa kunci pencarian.
14.2 Indeks yang dipesan 625

10101 Srinivasan Komp. Sci. 65000


12121 Wu Keuangan 90000
15151 Mozart Musik 40000
22222 Einstein Fisika 95000
32343 El Said Sejarah 60000
33456 Emas Fisika 87000
45565 Katz Komp. Sci. 75000
58583 Kaligrafi Sejarah 62000
76543 Singh Keuangan 80000
76766 krik Biologi 72000
83821 Brandt Komp. Sci. 92000
98345 Kim Elec. Ind. 80000

Gambar 14.1 File berurutan untuk pengajar catatan.

14.2 Indeks yang dipesan

Untuk mendapatkan akses acak cepat ke catatan dalam file, kita dapat menggunakan struktur indeks.
Setiap struktur indeks dikaitkan dengan kunci pencarian tertentu. Sama seperti indeks buku atau katalog
perpustakaan, danindeks yang dipesan menyimpan nilai kunci pencarian dalam urutan yang diurutkan
dan mengaitkan dengan setiap kunci pencarian catatan yang berisi itu.
Catatan dalam file yang diindeks mungkin sendiri disimpan dalam beberapa urutan yang diurutkan,
seperti halnya buku di perpustakaan disimpan menurut beberapa atribut seperti angka desimal Dewey.
Sebuah file mungkin memiliki beberapa indeks, pada kunci pencarian yang berbeda. Jika file yang berisi
record diurutkan secara berurutan, aindeks pengelompokan adalah indeks yang kunci pencariannya
juga mendefinisikan urutan file secara berurutan. Indeks pengelompokan juga disebutindeks utama;
syaratindeks utama mungkin muncul untuk menunjukkan indeks pada kunci utama, tetapi indeks
tersebut sebenarnya dapat dibangun pada kunci pencarian apa pun. Kunci pencarian indeks
pengelompokan sering kali merupakan kunci utama, meskipun tidak selalu demikian. Indeks yang kunci
pencariannya menentukan urutan yang berbeda dari urutan file disebutindeks nonclustering, atau
indeks sekunder. Istilah "clustered" dan "nonclustered" sering digunakan sebagai pengganti "clustering"
dan "nonclustering."
Dalam Bagian 14.2.1 hingga Bagian 14.2.3, kami berasumsi bahwa semua file diurutkan
secara berurutan pada beberapa kunci pencarian. File seperti itu, dengan indeks pengelompokan
pada kunci pencarian, disebutfile indeks-urutan. Mereka mewakili salah satu skema indeks tertua
yang digunakan dalam sistem database. Mereka dirancang untuk aplikasi yang memerlukan
pemrosesan berurutan dari seluruh file dan akses acak ke catatan individu. Dalam Bagian 14.2.4
kita membahas indeks sekunder.
Gambar 14.1 menunjukkan file berurutan dari pengajar catatan diambil dari contoh
universitas kami. Dalam contoh Gambar 14.1, catatan disimpan dalam urutan instruktur yang
diurutkanIndo, yang digunakan sebagai kunci pencarian.
626 Bab 14 Pengindeksan

14.2.1 Indeks Padat dan Jarang


NS entri indeks, atau catatan indeks, terdiri dari nilai kunci pencarian dan penunjuk ke satu atau
beberapa record dengan nilai tersebut sebagai nilai kunci pencariannya. Pointer ke record terdiri
dari pengidentifikasi blok disk dan offset di dalam blok disk untuk mengidentifikasi record di
dalam blok.
Ada dua jenis indeks pesanan yang dapat kita gunakan:

• indeks padat: Dalam indeks padat, entri indeks muncul untuk setiap nilai kunci pencarian
dalam file. Dalam indeks pengelompokan padat, catatan indeks berisi nilai kunci pencarian
dan penunjuk ke catatan data pertama dengan nilai kunci pencarian tersebut. Sisa catatan
dengan nilai kunci pencarian yang sama akan disimpan secara berurutan setelah catatan
pertama, karena, karena indeks adalah satu pengelompokan, catatan diurutkan pada kunci
pencarian yang sama.
Dalam indeks nonclustering padat, indeks harus menyimpan daftar pointer ke semua catatan
dengan nilai kunci pencarian yang sama.

• Indeks jarang: Dalam indeks yang jarang, entri indeks hanya muncul untuk beberapa nilai kunci
pencarian. Indeks jarang dapat digunakan hanya jika relasi disimpan dalam urutan kunci pencarian
yang diurutkan; yaitu, jika indeks adalah indeks pengelompokan. Seperti halnya dalam indeks
padat, setiap entri indeks berisi nilai kunci pencarian dan penunjuk ke catatan data pertama
dengan nilai kunci pencarian tersebut. Untuk menemukan catatan, kami menemukan entri indeks
dengan nilai kunci pencarian terbesar yang kurang dari atau sama dengan nilai kunci pencarian
yang kami cari. Kita mulai dari catatan yang ditunjuk oleh entri indeks itu dan ikuti petunjuk dalam
file sampai kita menemukan catatan yang diinginkan.

Gambar 14.2 dan Gambar 14.3 masing-masing menunjukkan indeks padat dan jarang, untuk
pengajar file. Misalkan kita mencari catatan instruktur denganIndo “22222”. Menggunakan indeks
padat Gambar 14.2, kami mengikuti penunjuk langsung ke catatan yang diinginkan. SejakIndo
adalah kunci utama, hanya ada satu catatan seperti itu dan pencarian selesai. Jika kita
menggunakan indeks sparse (Gambar 14.3), kita tidak menemukan entri indeks untuk “22222”.
Karena entri terakhir (dalam urutan numerik) sebelum "22222" adalah "10101", kami mengikuti
penunjuk itu. Kami kemudian membacapengajar file secara berurutan sampai kami menemukan
catatan yang diinginkan.
Pertimbangkan kamus (cetak). Header setiap halaman mencantumkan kata pertama
menurut abjad pada halaman itu. Kata-kata di bagian atas setiap halaman indeks buku
bersama-sama membentuk indeks tipis pada isi halaman kamus.
Sebagai contoh lain, anggaplah nilai kunci pencarian bukan kunci utama. Angka
14.4 menunjukkan indeks pengelompokan padat untuk pengajar file dengan kunci pencarian adalah
nama departemen. Perhatikan bahwa dalam hal inipengajar file diurutkan pada kunci pencarian nama
departemen, dari pada Indo, jika tidak, indeks pada nama departemen akan menjadi indeks
nonclustering. Misalkan kita sedang mencari catatan untuk departemen Sejarah. Menggunakan indeks
padat Gambar 14.4, kami mengikuti penunjuk langsung ke catatan Sejarah pertama. Kami memproses
catatan ini dan mengikuti penunjuk dalam catatan itu untuk menemukan catatan berikutnya di
14.2 Indeks yang dipesan 627

10101 10101 Srinivasan Komp. Sci. 65000


12121 12121 Wu Keuangan 90000
15151 15151 Mozart Musik 40000
22222 22222 Einstein Fisika 95000
32343 32343 El Said Sejarah 60000
33456 33456 Emas Fisika 87000
45565 45565 Katz Komp. Sci. 75000
58583 58583 Kaligrafi Sejarah 62000
76543 76543 Singh Keuangan 80000
76766 76766 krik Biologi 72000
83821 83821 Brandt Komp. Sci. 92000
98345 98345 Kim Elec. Ind. 80000

Gambar 14.2 Indeks padat.

kunci pencarian (nama departemen) memesan. Kami terus memproses catatan sampai kami
menemukan catatan untuk departemen selain Sejarah.
Seperti yang telah kita lihat, umumnya lebih cepat untuk menemukan catatan jika kita memiliki indeks padat
daripada indeks jarang. Namun, indeks sparse memiliki keunggulan dibandingkan indeks padat dalam hal mereka
membutuhkan lebih sedikit ruang dan mereka memaksakan lebih sedikit biaya pemeliharaan untuk penyisipan dan
penghapusan.
Ada trade-off yang harus dibuat oleh perancang sistem antara waktu akses dan overhead
ruang. Meskipun keputusan mengenai pertukaran ini tergantung pada aplikasi spesifik, kompromi
yang baik adalah memiliki indeks yang jarang dengan satu entri indeks per

10101 10101 Srinivasan Komp. Sci. 65000


32343 12121 Wu Keuangan 90000
76766 15151 Mozart Musik 40000
22222 Einstein Fisika 95000
32343 El Said Sejarah 60000
33456 Emas Fisika 87000
45565 Katz Komp. Sci. 75000
58583 Kaligrafi Sejarah 62000
76543 Singh Keuangan 80000
76766 krik Biologi 72000
83821 Brandt Komp. Sci. 92000
98345 Kim Elec. Ind. 80000

Gambar 14.3 Indeks jarang.


628 Bab 14 Pengindeksan

Biologi 76766 krik Biologi 72000


Komp. Sci. 10101 Srinivasan Komp. Sci. 65000
Elec. Ind. 45565 Katz Komp. Sci. 75000
Keuangan 83821 Brandt Komp. Sci. 92000
Sejarah 98345 Kim Elec. Ind. 80000
Musik 12121 Wu Keuangan 90000
Fisika 76543 Singh Keuangan 80000
32343 El Said Sejarah 60000
58583 Kaligrafi Sejarah 62000
15151 Mozart Musik 40000
22222 Einstein Fisika 95000
33465 Emas Fisika 87000

Gambar 14.4 Indeks padat dengan kunci pencarian nama departemen.

memblokir. Alasan desain ini merupakan trade-off yang baik adalah karena biaya yang dominan dalam
memproses permintaan basis data adalah waktu yang diperlukan untuk membawa blok dari disk ke
memori utama. Setelah kami memasukkan blok, waktu untuk memindai seluruh blok dapat diabaikan.
Dengan menggunakan indeks jarang ini, kami menemukan blok yang berisi catatan yang kami cari. Jadi,
kecuali record berada di blok overflow (lihat Bagian 13.3.2), kami meminimalkan akses blok sambil
menjaga ukuran indeks (dan dengan demikian ruang overhead kami) sekecil mungkin.

Untuk teknik sebelumnya menjadi sepenuhnya umum, kita harus mempertimbangkan kasus di mana
catatan untuk satu nilai kunci pencarian menempati beberapa blok. Sangat mudah untuk mengubah skema
kami untuk menangani situasi ini.

14.2.2 Indeks Multilevel


Misalkan kita membangun indeks padat pada relasi dengan 1.000.000 tupel. Entri indeks lebih
kecil dari catatan data, jadi mari kita asumsikan bahwa 100 entri indeks muat pada blok 4-kilobyte.
Dengan demikian, indeks kami menempati 10.000 blok. Jika relasi tersebut memiliki 100.000.000
tupel, indeks akan menempati 1.000.000 blok, atau 4 gigabyte ruang. Indeks besar tersebut
disimpan sebagai file berurutan pada disk.
Jika indeks cukup kecil untuk disimpan seluruhnya di memori utama, waktu pencarian untuk
menemukan entri rendah. Namun, jika indeks sangat besar sehingga tidak semuanya dapat
disimpan dalam memori, blok indeks harus diambil dari disk bila diperlukan. (Bahkan jika indeks
lebih kecil dari memori utama komputer, memori utama juga diperlukan untuk sejumlah tugas
lain, sehingga tidak mungkin untuk menyimpan seluruh indeks dalam memori.) Pencarian entri
dalam indeks kemudian memerlukan beberapa pembacaan blok-disk.
Pencarian biner dapat digunakan pada file indeks untuk menemukan entri, tetapi pencarian masih
memiliki biaya yang besar. Jika indeks akan menempatiB blok, pencarian biner membutuhkan sebanyak
kancatatan2(B)⌉ blok untuk dibaca. (kanxkan menunjukkan bilangan bulat terkecil yang lebih besar dari atau
sama dengan x; yaitu, kita membulatkan ke atas.) Perhatikan bahwa blok yang dibaca tidak berdekatan
14.2 Indeks yang dipesan 629

satu sama lain, sehingga setiap pembacaan memerlukan operasi I/O acak (yaitu, non-sekuensial). Untuk indeks
10.000 blok, pencarian biner membutuhkan 14 pembacaan blok acak. Pada sistem disk magnetik di mana
pembacaan blok acak membutuhkan waktu rata-rata 10 milidetik, pencarian indeks akan memakan waktu 140
milidetik. Ini mungkin tampak tidak banyak, tetapi kita hanya dapat melakukan tujuh pencarian indeks per detik
pada satu disk, sedangkan mekanisme pencarian yang lebih efisien akan memungkinkan kita melakukan
pencarian yang jauh lebih banyak per detik, seperti yang akan kita lihat segera. Perhatikan bahwa, jika blok
overflow telah digunakan, pencarian biner hanya dimungkinkan pada blok non-overflow, dan biaya sebenarnya
mungkin lebih tinggi daripada ikatan logaritmik di atas. Pencarian berurutan membutuhkanB pembacaan blok
sekuensial, yang mungkin memakan waktu lebih lama (walaupun dalam beberapa kasus biaya yang lebih
rendah dari pembacaan blok sekuensial dapat mengakibatkan pencarian sekuensial menjadi lebih cepat
daripada pencarian biner). Dengan demikian, proses pencarian indeks besar mungkin mahal.

Untuk mengatasi masalah ini, kami memperlakukan indeks sama seperti kami memperlakukan file sekuensial
lainnya, dan kami membuat indeks luar yang jarang pada indeks asli, yang sekarang kami sebut indeks dalam, seperti
yang ditunjukkan pada Gambar 14.5. Perhatikan bahwa entri indeks selalu dalam urutan yang diurutkan, memungkinkan
indeks luar menjadi jarang. Untuk menemukan catatan, pertama-tama kita menggunakan pencarian biner pada indeks
luar untuk menemukan catatan dengan nilai kunci pencarian terbesar kurang

indeks data
blok 0 blok 0

indeks data
blok 1 blok 1
indeks luar

indeks bagian dalam

Gambar 14.5 Indeks jarang dua tingkat.


630 Bab 14 Pengindeksan

dari atau sama dengan yang kita inginkan. Pointer menunjuk ke blok indeks bagian dalam.
Kami memindai blok ini sampai kami menemukan catatan yang memiliki nilai kunci
pencarian terbesar kurang dari atau sama dengan yang kami inginkan. Pointer dalam record
ini menunjuk ke blok file yang berisi record yang kita cari.
Dalam contoh kita, indeks dalam dengan 10.000 blok akan membutuhkan 10.000 entri di
indeks luar, yang hanya akan menempati 100 blok. Jika kita berasumsi bahwa indeks luar sudah
ada di memori utama, kita hanya akan membaca satu blok indeks untuk pencarian menggunakan
indeks bertingkat, daripada 14 blok yang kita baca dengan pencarian biner. Hasilnya, kami dapat
melakukan pencarian indeks 14 kali lebih banyak per detik.
Jika file kita sangat besar, bahkan indeks luar mungkin tumbuh terlalu besar untuk muat di
memori utama. Dengan relasi 100.000.000-tupel, indeks bagian dalam akan menempati 1.000.000
blok, dan indeks luar akan menempati 10.000 blok, atau 40 megabita. Karena ada banyak tuntutan
pada memori utama, mungkin tidak mungkin untuk mencadangkan memori utama sebanyak itu
hanya untuk indeks luar khusus ini. Dalam kasus seperti itu, kita dapat membuat level index yang
lain. Memang, kita dapat mengulangi proses ini sebanyak yang diperlukan. Indeks dengan dua
atau lebih level disebutindeks bertingkat. Pencarian record dengan indeks bertingkat
membutuhkan operasi I/O yang jauh lebih sedikit daripada pencarian record dengan pencarian
biner.2
Indeks multilevel terkait erat dengan struktur pohon, seperti pohon biner yang digunakan
untuk pengindeksan dalam memori. Kami akan memeriksa hubungan nanti, di Bagian 14.3.

14.2.3 Pembaruan Indeks

Terlepas dari bentuk indeks apa yang digunakan, setiap indeks harus diperbarui setiap kali
catatan dimasukkan atau dihapus dari file. Selanjutnya, jika catatan dalam file diperbarui,
indeks apa pun yang atribut kunci pencariannya terpengaruh oleh pembaruan juga harus
diperbarui; misalnya, jika departemen instruktur diubah, indeks padanama departemen
atribut dari pengajar harus diperbarui sesuai. Pembaruan catatan semacam itu dapat
dimodelkan sebagai penghapusan catatan lama, diikuti dengan penyisipan nilai catatan
baru, yang menghasilkan penghapusan indeks diikuti oleh penyisipan indeks. Akibatnya kita
hanya perlu mempertimbangkan penyisipan dan penghapusan pada indeks, dan kita tidak
perlu mempertimbangkan pembaruan secara eksplisit.
Kami pertama-tama menjelaskan algoritme untuk memperbarui indeks tingkat tunggal.

14.2.3.1 Penyisipan

Pertama, sistem melakukan pencarian menggunakan nilai kunci pencarian yang muncul dalam catatan yang
akan dimasukkan. Tindakan yang diambil sistem selanjutnya bergantung pada apakah indeks padat atau jarang:

2Pada hari-hari awal indeks berbasis disk, setiap tingkat indeks berhubungan dengan unit penyimpanan fisik. Jadi, kita mungkin
memiliki indeks pada level track, silinder, dan disk. Hirarki seperti itu tidak masuk akal saat ini karena subsistem disk
menyembunyikan detail fisik penyimpanan disk, dan jumlah disk dan platter per disk sangat kecil dibandingkan dengan jumlah
silinder atau byte per track.
14.2 Indeks yang dipesan 631

• Indeks padat:

1. Jika nilai kunci pencarian tidak muncul dalam indeks, sistem memasukkan entri
indeks dengan nilai kunci pencarian dalam indeks pada posisi yang sesuai.

2. Jika tidak, tindakan berikut diambil:


A. Jika entri indeks menyimpan pointer ke semua record dengan nilai kunci pencarian yang
sama, sistem akan menambahkan pointer ke record baru dalam entri indeks.

B. Jika tidak, entri indeks menyimpan penunjuk hanya ke rekaman pertama dengan
nilai kunci pencarian. Sistem kemudian menempatkan catatan yang dimasukkan
setelah catatan lain dengan nilai kunci pencarian yang sama.

• Indeks jarang: Kami berasumsi bahwa indeks menyimpan entri untuk setiap blok. Jika sistem
membuat blok baru, sistem akan memasukkan nilai kunci pencarian pertama (dalam urutan kunci
pencarian) yang muncul di blok baru ke dalam indeks. Di sisi lain, jika catatan baru memiliki nilai
kunci pencarian paling sedikit di bloknya, sistem memperbarui entri indeks yang menunjuk ke blok;
jika tidak, sistem tidak akan mengubah file index.

14.2.3.2 Penghapusan

Untuk menghapus record, sistem terlebih dahulu mencari record yang akan dihapus. Tindakan yang
diambil sistem selanjutnya bergantung pada apakah indeks padat atau jarang:

• Indeks padat:

1. Jika catatan yang dihapus adalah satu-satunya catatan dengan nilai kunci pencarian
tertentu, maka sistem akan menghapus entri indeks yang sesuai dari indeks.

2. Jika tidak, tindakan berikut diambil:


A. Jika entri indeks menyimpan pointer ke semua record dengan nilai kunci pencarian yang
sama, sistem akan menghapus pointer ke record yang dihapus dari entri indeks.

B. Jika tidak, entri indeks menyimpan penunjuk hanya ke rekaman pertama dengan nilai
kunci pencarian. Dalam hal ini, jika catatan yang dihapus adalah catatan pertama
dengan nilai kunci pencarian, sistem memperbarui entri indeks untuk menunjuk ke
catatan berikutnya.

• Indeks jarang:

1. Jika indeks tidak berisi entri indeks dengan nilai kunci pencarian dari catatan yang
dihapus, tidak ada yang perlu dilakukan pada indeks.

2. Jika tidak, sistem akan mengambil tindakan berikut:


A. Jika catatan yang dihapus adalah satu-satunya catatan dengan kunci pencariannya,
sistem akan mengganti catatan indeks yang sesuai dengan catatan indeks untuk nilai
kunci pencarian berikutnya (dalam urutan kunci pencarian). Jika nilai kunci pencarian
berikutnya sudah memiliki entri indeks, entri tersebut akan dihapus alih-alih diganti.
632 Bab 14 Pengindeksan

B. Jika tidak, jika entri indeks untuk nilai kunci pencarian menunjuk ke catatan yang
dihapus, sistem memperbarui entri indeks untuk menunjuk ke catatan berikutnya
dengan nilai kunci pencarian yang sama.

Algoritma penyisipan dan penghapusan untuk indeks bertingkat adalah perpanjangan


sederhana dari skema yang baru saja dijelaskan. Pada penghapusan atau penyisipan, sistem
memperbarui indeks tingkat terendah seperti yang dijelaskan. Sejauh menyangkut level kedua,
indeks level terendah hanyalah file yang berisi catatan—jadi, jika ada perubahan pada indeks level
terendah, sistem memperbarui indeks level kedua seperti yang dijelaskan. Teknik yang sama
berlaku untuk level indeks selanjutnya, jika ada.

14.2.4 Indeks Sekunder


Indeks sekunder harus padat, dengan entri indeks untuk setiap nilai kunci pencarian, dan penunjuk ke
setiap catatan dalam file. Indeks pengelompokan mungkin jarang, hanya menyimpan beberapa nilai
kunci pencarian, karena selalu mungkin untuk menemukan catatan dengan nilai kunci pencarian
menengah dengan akses berurutan ke bagian file, seperti yang dijelaskan sebelumnya. Jika indeks
sekunder hanya menyimpan beberapa nilai kunci pencarian, catatan dengan nilai kunci pencarian
menengah dapat berada di mana saja dalam file dan, secara umum, kami tidak dapat menemukannya
tanpa mencari seluruh file.
Indeks sekunder pada kunci kandidat terlihat seperti indeks pengelompokan padat, kecuali
bahwa catatan yang ditunjukkan oleh nilai berurutan dalam indeks tidak disimpan secara
berurutan. Namun, secara umum, indeks sekunder mungkin memiliki struktur yang berbeda dari
indeks pengelompokan. Jika kunci pencarian indeks pengelompokan bukan kunci kandidat, cukup
jika indeks menunjuk ke catatan pertama dengan nilai tertentu untuk kunci pencarian, karena
catatan lain dapat diambil dengan pemindaian berurutan dari file.
Sebaliknya, jika kunci pencarian dari indeks sekunder bukan kunci kandidat, tidak cukup
hanya menunjuk ke record pertama dengan setiap nilai kunci pencarian. Catatan yang tersisa
dengan nilai kunci pencarian yang sama dapat berada di mana saja dalam file, karena catatan
diurutkan oleh kunci pencarian dari indeks pengelompokan, bukan oleh kunci pencarian dari
indeks sekunder. Oleh karena itu, indeks sekunder harus berisi pointer ke semua catatan.

Jika suatu relasi dapat memiliki lebih dari satu record yang berisi nilai kunci pencarian yang sama
(yaitu, dua atau lebih record dapat memiliki nilai yang sama untuk atribut yang diindeks), kunci
pencarian dikatakan sebagai kunci pencarian yang tidak unik.
Salah satu cara untuk menerapkan indeks sekunder pada kunci pencarian yang tidak unik adalah
sebagai berikut: Berbeda dengan kasus indeks primer, penunjuk dalam indeks sekunder tersebut tidak
menunjuk langsung ke catatan. Sebagai gantinya, setiap penunjuk dalam indeks menunjuk ke ember
yang pada gilirannya berisi penunjuk ke file. Gambar 14.6 menunjukkan struktur indeks sekunder yang
menggunakan tingkat tipuan ekstra padapengajar file, pada tombol pencarian nama departemen.

Namun, pendekatan ini memiliki beberapa kelemahan. Pertama, akses indeks membutuhkan waktu
lebih lama, karena tingkat tipuan ekstra, yang mungkin memerlukan operasi I/O acak. Kedua,
14.2 Indeks yang dipesan 633

10101 Srinivasan Komp. Sci. 65000


12121 Wu Keuangan 90000
Biologi 15151 Mozart Musik 40000
Komp. Sci. 22222 Einstein Fisika 95000
Elec. Ind. 32343 El Said Sejarah 60000
33456 Emas Fisika 87000
Keuangan
45565 Katz Komp. Sci. 75000
Sejarah
58583 Kaligrafi Sejarah 62000
Musik
76543 Singh Keuangan 80000
Fisika
76766 krik Biologi 72000
83821 Brandt Komp. Sci. 92000
98345 Kim Elec. Ind. 80000

Gambar 14.6 Indeks sekunder aktif pengajar file, pada kunci bukan kandidat nama departemen.

jika kunci memiliki sangat sedikit atau tidak ada duplikat, jika seluruh blok dialokasikan ke bucket yang
terkait, banyak ruang yang akan terbuang. Kemudian dalam bab ini, kami mempelajari alternatif yang
lebih efisien untuk menerapkan indeks sekunder, yang menghindari kelemahan ini.
Pemindaian sekuensial dalam urutan indeks pengelompokan efisien karena catatan dalam file
disimpan secara fisik dalam urutan yang sama dengan urutan indeks. Namun, kami tidak dapat (kecuali
dalam kasus khusus yang jarang terjadi) menyimpan file yang diurutkan secara fisik oleh kunci pencarian
indeks pengelompokan dan kunci pencarian indeks sekunder. Karena urutan kunci sekunder dan urutan
kunci fisik berbeda, jika kita mencoba untuk memindai file secara berurutan dalam urutan kunci
sekunder, pembacaan setiap record kemungkinan memerlukan pembacaan blok baru dari disk, yang
sangat lambat.
Prosedur yang dijelaskan sebelumnya untuk penghapusan dan penyisipan juga dapat diterapkan
pada indeks sekunder; tindakan yang diambil adalah yang dijelaskan untuk indeks padat yang
menyimpan pointer ke setiap catatan dalam file. Jika sebuah file memiliki beberapa indeks, setiap kali file
tersebut dimodifikasi,setiap indeks harus diperbarui.
Indeks sekunder meningkatkan kinerja kueri yang menggunakan kunci selain kunci
pencarian indeks pengelompokan. Namun, mereka memaksakan overhead yang
signifikan pada modifikasi database. Perancang database memutuskan indeks
sekunder mana yang diinginkan berdasarkan perkiraan frekuensi relatif kueri dan
modifikasi.

14.2.5 Indeks pada Beberapa Tombol

Meskipun contoh yang telah kita lihat sejauh ini memiliki satu atribut dalam kunci pencarian,
secara umum kunci pencarian dapat memiliki lebih dari satu atribut. Kunci pencarian yang berisi
lebih dari satu atribut disebut sebagaikunci pencarian gabungan. Struktur indeks sama dengan
indeks lainnya, satu-satunya perbedaan adalah bahwa kunci pencarian bukanlah atribut tunggal,
melainkan daftar atribut. Kunci pencarian dapat direpresentasikan sebagai
sebuah tuple nilai, dari bentuk (A1,…, An), di mana atribut yang diindeks adalah A1,…, An.
634 Bab 14 Pengindeksan

Urutan nilai kunci pencarian adalah urutan leksikografis. Misalnya untuk


kasus dua kunci pencarian atribut, (A1, A2) < (B1, B2) jika keduanya A1 < B1 atau A1 = B1 dan
A2 < B2. Urutan leksikografis pada dasarnya sama dengan urutan abjad kata. Sebagai
contoh, perhatikan indeks padamengambil relasi, pada pencarian gabungan
kunci (ID kursus, semester, tahun). Indeks tersebut akan berguna untuk menemukan semua mahasiswa yang
telah mendaftar untuk mata kuliah tertentu pada semester/tahun tertentu. Indeks berurutan pada kunci
komposit juga dapat digunakan untuk menjawab beberapa jenis pertanyaan lain secara efisien, seperti yang
akan kita lihat di Bagian 14.6.2.

14.3 B+-File Indeks Pohon

Kerugian utama dari organisasi file urutan indeks adalah bahwa kinerja menurun saat
file tumbuh, baik untuk pencarian indeks dan untuk pemindaian berurutan melalui
data. Meskipun degradasi ini dapat diatasi dengan reorganisasi file, reorganisasi sering
tidak diinginkan.
NS B+-indeks pohon struktur adalah yang paling banyak digunakan dari beberapa struktur
indeks yang mempertahankan efisiensinya meskipun ada penyisipan dan penghapusan data. AB+
-indeks pohon berbentuk a pohon seimbang di mana setiap jalan dari akar pohon ke daun pohon
adalah sama panjang. Setiap node nonleaf di pohon (selain root) memiliki antarakann/2kan dan n
anak-anak, dimana n ditetapkan untuk pohon tertentu; akar memiliki antara 2 dann anak-anak.

Kita akan melihat bahwa B+-struktur pohon membebankan overhead kinerja pada penyisipan
dan penghapusan dan menambahkan ruang di atas kepala. Overhead dapat diterima bahkan
untuk file yang sering dimodifikasi, karena biaya reorganisasi file dapat dihindari. Selain itu,
karena node mungkin sebanyak setengah kosong (jika mereka memiliki jumlah minimum anak),
ada beberapa ruang yang terbuang. Overhead ruang ini juga dapat diterima mengingat manfaat
kinerja B+-struktur pohon

14.3.1 Struktur B+-Pohon


AB+-tree index adalah indeks bertingkat, tetapi memiliki struktur yang berbeda dari file urutan indeks
bertingkat. Kami berasumsi untuk saat ini bahwa tidak ada nilai kunci pencarian duplikat, yaitu, setiap
kunci pencarian adalah unik dan terjadi paling banyak pada satu record; kami mempertimbangkan
masalah kunci pencarian yang tidak unik nanti.
Gambar 14.7 menunjukkan simpul tipikal dari B+-pohon. Ini berisi hinggan - 1 kunci pencarian
nilai-nilai K1, K2,…, Kn1, dan n petunjuk P1, P2,…, Pn. Nilai kunci pencarian dalam sebuah node disimpan dalam
urutan yang diurutkan; dengan demikian, jikasaya < j, kemudian KSaya < KJ .

P1 K1 P2 … Pn 1 Kn 1 Pn

Gambar 14.7 Simpul tipikal dari B+-pohon.


14.3 B+-File Indeks Pohon 635

simpul daun

Brandt Kaligrafi krik Pointer ke simpul daun berikutnya

10101 Srinivasan Komp. Sci. 65000


12121 Wu Keuangan 90000
15151 Mozart Musik 40000
22222 Einstein Fisika 95000
32343 El Said Sejarah 80000
33456 Emas Fisika 87000
45565 Katz Komp. Sci. 75000
58583 Kaligrafi Sejarah 60000
76543 Singh Keuangan 80000
76766 krik Biologi 72000
83821 Brandt Komp. Sci. 92000
98345 Kim Elec. Ind. 80000

pengajar file

Gambar 14.8 Sebuah simpul daun untuk pengajar B+-indeks pohon (n = 4).

Kami mempertimbangkan terlebih dahulu struktur simpul daun. UntukSaya = 1, 2,…, n - 1, penunjuk PSaya
menunjuk ke catatan file dengan nilai kunci pencarian KSaya. penunjukPn memiliki tujuan khusus yang
akan kita bahas segera.
Gambar 14.8 menunjukkan satu simpul daun dari B+-pohon untuk pengajar file, di mana kami telah
memilih n menjadi 4, dan kunci pencariannya adalah nama.
Sekarang setelah kita melihat struktur simpul daun, mari kita pertimbangkan bagaimana nilai kunci
pencarian ditetapkan ke simpul tertentu. Setiap daun dapat menampung hinggan - 1 nilai. Kami
mengizinkan simpul daun berisi sesedikit(n - 1)/2kan nilai-nilai. Dengann = 4 dalam contoh kita B+-pohon,
setiap daun harus mengandung paling sedikit dua nilai, dan paling banyak tiga nilai.
Jika LSaya dan LJ adalah simpul daun dan saya < j (itu adalah, LSaya ada di sebelah kiri LJ di pohon), maka
setiap nilai kunci pencarian vSaya di dalam LSaya kurang dari setiap nilai kunci pencarian vJ di dalam LJ .
Jika B+-tree index digunakan sebagai indeks padat (seperti biasanya), setiap search-key
nilai harus muncul di beberapa simpul daun.
Sekarang kita bisa menjelaskan penggunaan pointer Pn. Karena ada orde linier pada
daun berdasarkan nilai kunci pencarian yang dikandungnya, kami menggunakan Pn untuk menyatukan simpul
daun dalam urutan kunci pencarian. Pemesanan ini memungkinkan pemrosesan berurutan yang efisien
dari file.
NS simpul tak berdaun dari B+-pohon membentuk indeks bertingkat (jarang) pada simpul daun.
Struktur node nonleaf sama dengan node leaf, kecuali bahwa semua pointer adalah pointer
ke node pohon. Node nonleaf dapat menampung hinggan petunjuk dan harus tahan
setidaknya kann/2kan petunjuk. Jumlah pointer dalam sebuah node disebutfanout dari
simpul. Node nonleaf juga disebut sebagaisimpul internal.
636 Bab 14 Pengindeksan

Mozart simpul akar

Einstein Emas Srinivasan Node internal

Nodus daun

Brandt Crick Kalifiri Einstein El Said Emas Katz Kim Mozart Singh Srinivasan Wu

10101 Srinivasan Komp. Sci. 65000


12121 Wu Keuangan 90000
15151 Mozart Musik 40000
22222 Einstein Fisika 95000
32343 El Said Sejarah 80000
33456 Emas Fisika 87000
45565 Katz Komp. Sci. 75000
58583 Kaligrafi Sejarah 60000
76543 Singh Keuangan 80000
76766 krik Biologi 72000
83821 Brandt Komp. Sci. 92000
98345 Kim Elec. Ind. 80000

Gambar 14.9 B+-pohon untuk pengajar berkas (n = 4).

Mari kita pertimbangkan sebuah simpul yang mengandung M petunjuk (M ≤ n). UntukSaya = 2, 3,…, M - 1,
penunjuk PSaya menunjuk ke subpohon yang berisi nilai kunci pencarian kurang dari KSaya dan lebih besar dari
atau sama dengan KSaya -1. penunjukPM menunjuk ke bagian dari subpohon yang berisi nilai-nilai kunci yang
lebih besar dari atau sama dengan KM1, dan penunjuk P1 menunjuk ke bagian dari subpohon
yang berisi nilai kunci pencarian kurang dari K1.
Tidak seperti node nonleaf lainnya, node root dapat menampung kurang dari kann/2kan petunjuk;
namun, itu harus menampung setidaknya dua pointer, kecuali pohon hanya terdiri dari satu node. Itu
selalu mungkin untuk membangun B+-pohon, untuk apa saja n, yang memenuhi persyaratan
sebelumnya.
Gambar 14.9 menunjukkan B lengkap+-pohon untuk pengajar file (dengan n = 4). Kita punya
dihilangkan pointer nol untuk kesederhanaan; setiap bidang penunjuk pada gambar yang tidak
memiliki panah dianggap memiliki nilai nol.
Gambar 14.10 menunjukkan B lain+-pohon untuk pengajar file, kali ini dengan n = 6.
Perhatikan bahwa tinggi pohon ini lebih kecil dari pohon sebelumnya, yang memiliki
n = 4.

El Said Mozart

Brandt Kaligrafi krik Einstein El Said Emas Katz Kim Mozart Singh Srinivasan Wu

Gambar 14.10 B+-pohon untuk pengajar mengajukan dengan n = 6.


14.3 B+-File Indeks Pohon 637

Contoh-contoh B . ini+-pohon semuanya seimbang. Artinya, panjang setiap jalan dari


akar ke simpul daun adalah sama. Properti ini merupakan persyaratan untuk B+-pohon. Memang, "B" di B
+-tree singkatan dari "seimbang." Ini adalah properti keseimbangan B+-pohon yang memastikan kinerja
yang baik untuk pencarian, penyisipan, dan penghapusan.
Secara umum, kunci pencarian dapat memiliki duplikat. Salah satu cara untuk menangani kasus kunci pencarian
yang tidak unik adalah dengan memodifikasi struktur pohon untuk menyimpan setiap kunci pencarian pada simpul daun
sebanyak yang muncul dalam catatan, dengan setiap salinan menunjuk ke satu catatan.
Syarat itu KSaya < KJ jika saya < j perlu diubah menjadi KSaya ≤ KJ . Namun, pendekatan ini dapat
menghasilkan duplikat nilai kunci pencarian di node internal, membuat penyisipan
prosedur penghapusan dan penghapusan lebih rumit dan mahal. Alternatif lain adalah
menyimpan satu set (atau ember) penunjuk catatan dengan setiap nilai kunci pencarian, seperti
yang kita lihat sebelumnya. Pendekatan ini lebih rumit dan dapat mengakibatkan akses yang tidak
efisien, terutama jika jumlah pointer record untuk kunci tertentu sangat besar.
Kebanyakan implementasi database malah membuat kunci pencarian unik sebagai berikut: Sup-
ajukan atribut kunci pencarian yang diinginkan ASaya hubungan R tidak unik. MembiarkanAP menjadi kunci
utama dari R. Kemudian kunci pencarian komposit unik (ASaya , AP) digunakan sebagai pengganti ASaya saat
membangun indeks. (Setiap set atribut yang bersama-sama denganASaya jamin keunikan juga bisa
digunakan sebagai pengganti AP.) Misalnya, jika kita ingin membuat indeks pada pengajar
hubungan pada atribut nama, kami malah membuat indeks pada kunci pencarian gabungan
(nama, ID), karena ID adalah kunci utama untuk pengajar. Pencarian indeks hanya padanama dapat ditangani
secara efisien menggunakan indeks ini, seperti yang akan kita lihat segera. Bagian 14.3.5 mencakup masalah
dalam menangani kunci pencarian yang tidak unik secara lebih rinci.
Dalam contoh kami, kami menunjukkan indeks pada beberapa kunci pencarian yang tidak unik, seperti: pengajar.
nama, dengan asumsi sederhana bahwa tidak ada duplikat; pada kenyataannya sebagian besar basis data akan secara
otomatis menambahkan atribut tambahan secara internal, untuk memastikan tidak adanya duplikat.

14.3.2 Query pada B+-Pohon

Mari kita pertimbangkan bagaimana kita memproses kueri pada B+-pohon. Misalkan kita ingin
menemukan catatan dengan nilai yang diberikanv untuk kunci pencarian. Gambar 14.11 menyajikan
pseudocode untuk suatu fungsifidan(v) untuk melakukan tugas ini, dengan asumsi tidak ada duplikat,
yaitu, paling banyak ada satu record dengan kunci pencarian tertentu. Kami membahas masalah kunci
pencarian yang tidak unik nanti di bagian ini.
Secara intuitif, fungsi dimulai dari akar pohon dan melintasi pohon ke bawah hingga
mencapai simpul daun yang akan berisi nilai yang ditentukan jika ada di pohon. Secara
khusus, dimulai dengan root sebagai simpul saat ini, fungsi mengulangi langkah-langkah
berikut sampai simpul daun tercapai. Pertama, node saat ini diperiksa, mencari
untuk yang terkecil Saya sedemikian rupa sehingga nilai kunci pencarian KSaya lebih besar atau sama dengan v.
Misalkan nilai seperti itu ditemukan; lalu jikaKSaya adalah sama dengan v, simpul saat ini diatur ke simpul yang
ditunjuk oleh PSaya+1, sebaliknya KSaya > v, dan simpul saat ini diatur ke simpul yang ditunjuk oleh PSaya. Jika tidak
ada nilai seperti ituKSaya ditemukan, maka v > KM1, di mana PM adalah penunjuk nonnull terakhir di
simpul. Dalam hal ini simpul saat ini diatur ke yang ditunjuk olehPM. Prosedur di
atas diulang, melintasi pohon sampai simpul daun tercapai.
638 Bab 14 Pengindeksan

fungsi fidan(v)
/* Diasumsikan tidak ada kunci duplikat, dan mengembalikan pointer ke record dengan
* nilai kunci pencarian v jika record seperti itu ada, dan null sebaliknya */ Set C
= simpul akar
ketika (C bukan simpul daun) mulai
Membiarkan Saya = bilangan terkecil sehingga v ≤ CKSaya
jika tidak ada nomor seperti itu Saya lalu mulai
Membiarkan PM = pointer non-null terakhir di node
Set C = CPM
akhir

lain jika (v = CKSaya) kemudian Mengatur C = CPSaya+1

lain Mengatur C = CPSaya /* v < CKSaya */


akhir

/* C adalah simpul daun */


jika untuk beberapa Saya, KSaya = v

kemudian kembali PSaya

lain kembali nol; /* Tidak ada catatan dengan nilai kunciv ada*/

Gambar 14.11 Menanyakan B+-pohon.

Di simpul daun, jika ada nilai kunci pencarian KSaya = v, penunjuk PSaya mengarahkan kita ke
catatan dengan nilai kunci pencarian KSaya. Fungsi kemudian mengembalikan pointer ke record,
PSaya. Jika tidak ada kunci pencarian dengan nilaiv ditemukan di simpul daun, tidak ada catatan dengan nilai kunci v
ada dalam relasi, dan fungsi fidan mengembalikan null, untuk menunjukkan kegagalan.
B+-pohon juga dapat digunakan untuk menemukan semua catatan dengan nilai kunci pencarian dalam tertentu
jangkauan [lb, ub]. Misalnya, dengan B+-pohon pada atribut gaji dari pengajar, kita dapat menemukan
semua pengajar catatan dengan gaji dalam kisaran tertentu seperti [50000, 100000] (dengan kata lain,
semua gaji antara 50000 dan 100000). Pertanyaan seperti itu disebutjangkauan kueri. Untuk
mengeksekusi kueri seperti itu, kita dapat membuat prosedurfindRange (lb, ub), ditunjukkan dalam
Gambar 14.12. Prosedurnya melakukan hal berikut: pertama melintasi daun dengan cara yang mirip denganfi
dan(lb); daun mungkin atau mungkin tidak benar-benar mengandung nilailb. Kemudian langkah-langkah
melalui catatan di itu dan node daun berikutnya mengumpulkan pointer ke semua catatan
dengan nilai kunci CKSaya NS lb ≤ CKSaya ≤ ub menjadi set resultSet. Fungsi berhenti ketika
CKSaya > ub, atau tidak ada lagi kunci di pohon.
Implementasi nyata akan memberikan versi findRange mendukung iterator
antarmuka yang mirip dengan yang disediakan oleh JDBC HasilSet, yang kita lihat di Bagian 5.1.1. Antarmuka
iterator seperti itu akan menyediakan metodelanjut(), yang dapat dipanggil berulang kali untuk mengambil
record yang berurutan. NSlanjut() metode akan melangkah melalui entri di tingkat daun, dengan cara yang
mirip dengan findRange, tetapi setiap panggilan hanya membutuhkan satu langkah dan mencatat di mana
panggilan terakhir, sehingga panggilan berturut-turut ke lanjut() langkah melalui en-
14.3 B+-File Indeks Pohon 639

fungsi findRange(lb, ub)


/* Mengembalikan semua record dengan nilai kunci pencarian V seperti yang lb ≤ V ≤ ub. */
Setel resultSet = {};
Mengatur C = simpul akar

ketika (C bukan simpul daun) mulai


Membiarkan Saya = bilangan terkecil sehingga lb ≤ CKSaya
jika tidak ada nomor seperti itu Saya lalu mulai
Membiarkan PM = pointer non-null terakhir di node
Set C = CPM
akhir

lain jika (lb = CKSaya) kemudian Mengatur C = CPSaya+1


lain Mengatur C = CPSaya /* lb < CKSaya */
akhir

/* C adalah simpul daun */


Membiarkan Saya jadilah nilai terkecil sehingga KSaya ≥ lb

jika tidak ada seperti itu Saya

kemudian Mengatur Saya = 1 + jumlah kunci di C; /* Untuk memaksa pindah ke daun berikutnya
*/ Set done = false;
ketika (belum selesai) mulai
Membiarkan n = jumlah kunci dalam C.
jika ( Saya ≤ n dan CKSaya ≤ ub) lalu mulai
Menambahkan CPSaya untuk

hasilSet Set Saya = Saya + 1

akhir

lain jika (Saya ≤ n dan CKSaya > ub)


kemudian Set selesai = benar;

lain jika (saya > tidak dan CPn+1 bukan nol)


kemudian Mengatur C = CPn+1, dan Saya = 1 /* Pindah ke daun berikutnya */
lain Set selesai = benar; /* Tidak ada lagi daun ke kanan */
akhir

kembali hasilSet;

Gambar 14.12 Kueri rentang pada B+-pohon.

mencoba. Kami menghilangkan detail untuk kesederhanaan, dan membiarkan kodesemu untuk antarmuka iterator
sebagai latihan untuk pembaca yang tertarik.
Kami sekarang mempertimbangkan biaya kueri pada B+-indeks pohon Dalam memproses kueri,
kami melintasi jalan di pohon dari akar ke beberapa simpul daun. Jika adan catatan di
file, jalurnya tidak lebih dari kancatatankann/2kan(n)⌉.
Biasanya, ukuran node dipilih sama dengan ukuran blok disk, yang:
biasanya 4 kilobyte. Dengan ukuran kunci pencarian 12 byte, dan ukuran penunjuk disk sebesar
640 Bab 14 Pengindeksan

8 byte, n sekitar 200. Bahkan dengan perkiraan yang lebih konservatif sebesar 32 byte untuk ukuran
kunci penelusuran, n sekitar 100. Dengan n = 100, jika kita memiliki 1 juta nilai kunci pencarian di
file, pencarian hanya membutuhkan kancatatan50(1.000.000)= 4 node untuk diakses. Jadi,
paling banyak empat blok perlu dibaca dari disk untuk melintasi jalur dari root ke daun.
Node akar pohon biasanya banyak diakses dan kemungkinan besar berada di buffer, jadi biasanya
hanya tiga atau lebih sedikit blok yang perlu dibaca dari disk.
Perbedaan penting antara B+-struktur pohon dan struktur pohon dalam memori,
seperti pohon biner, adalah ukuran simpul, dan sebagai hasilnya, tinggi pohon. Dalam pohon biner,
setiap node kecil dan memiliki paling banyak dua pointer. dalam B+-tree, setiap node berukuran besar—
biasanya sebuah blok disk—dan sebuah node dapat memiliki sejumlah besar pointer. Jadi, B+-pohon
cenderung gemuk dan pendek, tidak seperti pohon biner yang kurus dan tinggi. Dalam biner seimbang
pohon, jalur untuk pencarian bisa panjang kancatatan2(n)⌉, di mana n adalah jumlah record
dalam file yang diindeks. Dengann = 1.000.000 seperti pada contoh sebelumnya, a
pohon biner seimbang membutuhkan sekitar 20 akses node. Jika setiap node berada di blok disk yang
berbeda, 20 pembacaan blok akan diperlukan untuk memproses pencarian, berbeda dengan empat
pembacaan blok untuk B+-pohon. Perbedaannya signifikan dengan disk magnetik, karena setiap
pembacaan blok dapat memerlukan pencarian lengan disk yang, bersama dengan pembacaan blok,
membutuhkan waktu sekitar 10 milidetik pada disk magnetik. Perbedaannya tidak terlalu drastis dengan
penyimpanan flash, di mana pembacaan halaman 4 kilobyte membutuhkan waktu sekitar 10 hingga 100
mikrodetik, tetapi masih signifikan.
Setelah melintasi ke tingkat daun, kueri pada satu nilai kunci pencarian unik
memerlukan satu lagi operasi I/O acak untuk mengambil catatan yang cocok.
Kueri rentang memiliki biaya tambahan, setelah melintasi ke tingkat daun: semua penunjuk dalam
rentang yang diberikan harus diambil. Pointer ini berada di simpul daun berurutan; dengan demikian,
jikaM pointer seperti itu diambil, paling banyak kanM(n/2)+ 1 simpul daun perlu diakses untuk
mengambil pointer (karena setiap simpul daun setidaknya memiliki n/2 pointer, tetapi bahkan dua
pointer dapat dibagi menjadi dua halaman). Untuk biaya ini, kita perlu menambahkan biaya untuk
mengakses catatan yang sebenarnya. Untuk indeks sekunder, setiap catatan tersebut mungkin berada di
blok yang berbeda, yang dapat mengakibatkanM operasi I/O acak dalam kasus terburuk. Untuk indeks
berkerumun, catatan ini akan berada di blok berurutan, dengan setiap blok berisi beberapa catatan,
menghasilkan biaya yang jauh lebih rendah.
Sekarang, mari kita perhatikan kasus kunci yang tidak unik. Seperti yang dijelaskan sebelumnya, jika kita mau
untuk membuat indeks pada atribut ASaya yang bukan kunci kandidat, dan dengan demikian mungkin
memiliki duplikat, kami malah membuat indeks pada kunci komposit yang bebas duplikat. NS
kunci komposit dibuat dengan menambahkan atribut tambahan, seperti kunci utama, untuk ASaya, untuk
memastikan keunikan. Misalkan kita membuat indeks pada kunci komposit (ASaya, AP) sebagai gantinya
membuat indeks pada ASaya.
Pertanyaan penting, kemudian, adalah bagaimana kita mengambil semua tupel dengan nilai yang diberikan
v untuk ASaya menggunakan indeks di atas? Pertanyaan ini mudah dijawab dengan menggunakan
fungsi findRange(lb, ub), dengan lb = (v,) dan ub = (v, ), dimana∞ dan ∞ menunjukkan
nilai terkecil dan terbesar yang mungkin dari AP. Semua catatan denganASaya = v akan dikembalikan oleh
panggilan fungsi di atas. Rentang kueri aktifASaya dapat ditangani dengan cara yang sama. Kisaran ini
14.3 B+-File Indeks Pohon 641

query mengambil pointer ke catatan cukup efisien, meskipun pengambilan catatan mungkin
mahal, seperti yang dibahas sebelumnya.

14.3.3 Pembaruan pada B+-Pohon

Ketika sebuah record dimasukkan ke dalam, atau dihapus dari suatu relasi, indeks pada relasi tersebut harus
diperbarui secara bersamaan. Ingat bahwa pembaruan ke catatan dapat dimodelkan sebagai penghapusan
catatan lama diikuti dengan penyisipan catatan yang diperbarui. Oleh karena itu kami hanya
mempertimbangkan kasus penyisipan dan penghapusan.
Penyisipan dan penghapusan lebih rumit daripada pencarian, karena mungkin perlu untuk
membelah simpul yang menjadi terlalu besar sebagai akibat dari penyisipan, atau untuk bersatu
node (yaitu, menggabungkan node) jika sebuah node menjadi terlalu kecil (kurang dari kann/2kan pointer).
Selanjutnya, ketika sebuah node dipecah atau sepasang node digabungkan, kita harus memastikan bahwa
keseimbangan dipertahankan. Untuk memperkenalkan ide di balik penyisipan dan penghapusan dalam B+-tree,
kita akan mengasumsikan sementara bahwa node tidak pernah menjadi terlalu besar atau terlalu kecil. Di
bawah asumsi ini, penyisipan dan penghapusan dilakukan seperti yang didefinisikan berikutnya.

• Insersi. Menggunakan teknik yang sama seperti untuk mencari dari fidan() fungsi (Gambar
14.11), pertama-tama kita menemukan simpul daun di mana nilai kunci pencarian akan muncul. Kami
kemudian menyisipkan entri (yaitu, nilai kunci pencarian dan pasangan penunjuk catatan) di simpul daun,
memposisikannya sedemikian rupa sehingga kunci pencarian masih berurutan.

• Penghapusan. Menggunakan teknik yang sama seperti untuk pencarian, kami menemukan simpul
daun yang berisi entri yang akan dihapus dengan melakukan pencarian pada nilai kunci pencarian
dari catatan yang dihapus; jika ada beberapa entri dengan nilai kunci telusur yang sama, kami
menelusuri semua entri dengan nilai kunci telusur yang sama hingga kami menemukan entri yang
mengarah ke rekaman yang sedang dihapus. Kami kemudian menghapus entri dari simpul daun.
Semua entri di simpul daun yang berada di sebelah kanan entri yang dihapus digeser ke kiri satu
posisi, sehingga tidak ada celah pada entri setelah entri dihapus.

Kami sekarang mempertimbangkan kasus umum penyisipan dan penghapusan, berurusan dengan pemisahan
simpul dan penggabungan simpul.

14.3.3.1 Penyisipan

Kami sekarang mempertimbangkan contoh penyisipan di mana sebuah node harus dipecah. Asumsikan
bahwa sebuah record disisipkan padapengajar hubungan, dengan nama nilai menjadi Adams. Kami
kemudian perlu memasukkan entri untuk "Adams" ke dalam B+-pohon dari Gambar 14.9. Menggunakan
algoritme untuk pencarian, kami menemukan bahwa "Adams" akan muncul di simpul daun yang berisi
"Brandt", "Califieri", dan "Crick." Tidak ada ruang di daun ini untuk memasukkan nilai kunci pencarian
"Adams." Oleh karena itu, simpulnya adalahmembelah menjadi dua node. Gambar 14.13 menunjukkan
dua simpul daun yang dihasilkan dari pemisahan simpul daun pada penyisipan “Adams”. Nilai kunci
pencarian "Adams" dan "Brandt" ada di satu daun, dan "Califieri" dan "Crick" ada di daun lainnya. Secara
umum, kami mengambiln nilai kunci pencarian (the n1 nilai di daun
642 Bab 14 Pengindeksan

Adams Brandt Kaligrafi krik

Gambar 14.13 Pemisahan simpul daun pada penyisipan "Adams".

simpul ditambah nilai yang dimasukkan), dan letakkan yang pertama kann/2kan di node yang ada
dan nilai yang tersisa di node yang baru dibuat.
Setelah membagi simpul daun, kita harus memasukkan simpul daun baru ke dalam B+-struktur pohon
Dalam contoh kita, node baru memiliki “Califieri” sebagai nilai kunci pencarian terkecilnya.
Kita perlu memasukkan entri dengan nilai kunci pencarian ini, dan sebuah penunjuk ke
simpul baru, ke dalam induk dari simpul daun yang telah dipisah. B+-pohon Gambar 14.14
menunjukkan hasil penyisipan. Penyisipan ini dapat dilakukan tanpa pemisahan simpul lebih
lanjut, karena ada ruang di simpul induk untuk entri baru. Jika tidak ada ruang, induknya
harus dipisah, membutuhkan entri untuk ditambahkan ke induknya. Dalam kasus terburuk,
semua node di sepanjang jalur ke root harus dipecah. Jika akar itu sendiri terbelah, seluruh
pohon menjadi lebih dalam.
Pemisahan node nonleaf sedikit berbeda dari pemisahan node daun. Angka
14.15 menunjukkan hasil penyisipan record dengan kunci pencarian "Lamport" ke dalam pohon
yang ditunjukkan pada Gambar 14.14. Node daun di mana "Lamport" akan dimasukkan sudah
memiliki entri "Emas", "Katz", dan "Kim", dan sebagai hasilnya simpul daun harus dipecah. Node
sisi kanan baru yang dihasilkan dari pemisahan berisi nilai kunci pencarian "Kim" dan "Lamport".
Sebuah entri (Kim,n1) kemudian harus ditambahkan ke simpul induk, di mana n1 adalah penunjuk
ke simpul baru, Namun, tidak ada ruang di simpul induk untuk menambahkan entri baru, dan
simpul induk harus dipisah. Untuk melakukannya, simpul induk secara konseptual diperluas
sementara, entri ditambahkan, dan simpul yang terlalu penuh kemudian segera dipecah.
Ketika node nonleaf yang terlalu penuh dipisah, pointer anak dibagi di antara node asli
dan node yang baru dibuat; dalam contoh kita, node asli dibiarkan dengan tiga pointer
pertama, dan node yang baru dibuat di sebelah kanan mendapatkan dua pointer yang
tersisa. Namun, nilai kunci pencarian ditangani sedikit berbeda. Nilai kunci pencarian yang
terletak di antara pointer yang dipindahkan ke node kanan (dalam contoh kita, nilai “Kim”)
dipindahkan bersama dengan pointer, sedangkan yang terletak di antara pointer yang tetap
di kiri (dalam contoh kita, “ Califiri" dan "Einstein") tetap tidak terganggu.

Mozart

Calififi Einstein Gold Srinivasan

Adams Brandt Kaligrafi krik Einstein El Said Emas Katz Kim Mozart Singh Srinivasan Wu

Gambar 14.14 Penyisipan "Adams" ke dalam B+-pohon dari Gambar 14.9.


14.3 B+-File Indeks Pohon 643

Emas Mozart

Kaligrafi Einstein Kim Srinivasan

Adams Brandt Kaligrafi krik Einstein El Said Emas Katz Kim Lamport Mozart Singh Srinivasan Wu

Gambar 14.15 Penyisipan "Lamport" ke dalam B+-pohon Gambar 14.14.

Namun, nilai kunci pencarian yang terletak di antara pointer yang tetap berada di kiri, dan
pointer yang berpindah ke node kanan diperlakukan secara berbeda. Dalam contoh kami, nilai
kunci pencarian "Emas" terletak di antara tiga pointer yang menuju ke node kiri, dan dua pointer
yang menuju ke node kanan. Nilai "Emas" tidak ditambahkan ke salah satu dari node split.
Sebaliknya, sebuah entri (Emas,n2) ditambahkan ke simpul induk, di mana n2 adalah penunjuk ke
simpul yang baru dibuat yang dihasilkan dari pemisahan. Dalam hal ini, node induk adalah root,
dan memiliki cukup ruang untuk entri baru.
Teknik umum untuk penyisipan ke dalam B+-pohon adalah untuk menentukan simpul daun aku
di mana penyisipan harus terjadi. Jika hasil split, masukkan simpul baru ke induknya

prosedur memasukkan(nilai K, penunjuk P)


jika (pohon kosong) buat simpul daun kosong L, yang juga merupakan akarnya
lain Temukan simpul daun L yang harus berisi nilai kunci K
jika (L memiliki kurang dari n - 1 nilai kunci)
kemudian masukkan ke dalam daun (L, K, P)

lain mulai /* L memiliki n - 1 nilai kunci sudah, pisahkan */


Buat simpul Lkan
Salinan LP1 …LKn1 ke blok memori T yang dapat
memegang n (pointer, nilai kunci) pasang
masukkan ke dalam daun (T, K, P)

Mengatur Lkan.Pn = LPn; MengaturLPn = Lkan


Menghapus LP1 melalui LKn1 dari L
Salinan Tp1 melalui TKkann/2kan dari T ke dalam L mulai dari LP1
Salinan Tpkann/2+1 melalui TKn dari T ke dalam Lkan mulai dari Lkan.P1
Membiarkan Kkan menjadi nilai kunci terkecil di Lkan
masukkan orang tua (L, Kkan, Lkan)
akhir

Gambar 14.16 Penyisipan entri dalam B+-pohon.


644 Bab 14 Pengindeksan

dari simpul aku. Jika penyisipan ini menyebabkan perpecahan, lanjutkan secara rekursif ke atas pohon sampai
penyisipan tidak menyebabkan perpecahan atau root baru dibuat.
Gambar 14.16 menguraikan algoritma penyisipan dalam pseudocode. Prosedurmemasukkan
memasukkan pasangan penunjuk nilai kunci ke dalam indeks, menggunakan dua prosedur tambahan
masukkan ke dalam daun dan masukkan di induk, ditunjukkan pada Gambar 14.17. Dalam kode semu,L, n, P
dan T menunjukkan pointer ke node, dengan L digunakan untuk menunjukkan simpul daun. LKSaya dan LPSaya
menunjukkan Sayanilai th dan Sayapenunjuk ke dalam simpul L, masing-masing; TKSaya dan TpSaya
digunakan serupa. Pseudocode juga menggunakan fungsiinduk(n) untuk menemukan orang tua
dari sebuah simpul n. Kita dapat menghitung daftar node di jalur dari akar ke daun saat awalnya
menemukan node daun, dan kita dapat menggunakannya nanti untuk menemukan induk dari setiap
node di jalur secara efisien.

prosedur masukkan ke dalam daun (simpul L, nilai K, penunjuk P)


jika (K < LK1)
kemudian memasukkan P, K ke dalam L sebelum LP1
lain mulai
Membiarkan KSaya menjadi nilai tertinggi dalam L yang kurang dari atau sama dengan K

Memasukkan P, K ke dalam L sehabis LKSaya


akhir

prosedur masukkan di induk(simpul N, nilai Kkan, simpul Nkan)


jika (n adalah akar pohon)
lalu mulai
Buat simpul baru R mengandung n, Kkan, nkan /* n dan nkan adalah pointer
*/ Make R akar pohon
kembali
akhir

Membiarkan P = induk (n)


jika (P memiliki kurang dari n petunjuk)
kemudian memasukkan (Kkan, nkan) di dalam P sehabis n

lain mulai /* Membelah P */


Salinan P ke blok memori T yang bisa menahan P dan (Kkan, nkan)
Memasukkan (Kkan, nkan) ke dalam T sehabis n
Hapus semua entri dari P; Buat simpulPkan
Salinan Tp1 …Tp(n+1)/2kan ke dalam P

Membiarkan Kkan = TK(n+1)/2kan


Salinan Tp(n+1)/2+1 …Tpn+1 ke dalam Pkan
masukkan orang tua (P, Kkan, Pkan)
akhir

Gambar 14.17 Prosedur tambahan untuk penyisipan entri dalam B+-pohon.


14.3 B+-File Indeks Pohon 645

Prosedur masukkan di induk mengambil sebagai parameter n, Kkan, nkan, dimana simpul n dibagi
menjadi n dan nkan, dengan Kkan menjadi nilai terkecil dalam nkan. Prosedur memodifikasi induk darin
untuk merekam perpecahan. Prosedurmasukkan ke dalam indeks dan masukkan di induk
gunakan area memori sementara T untuk menyimpan isi dari node yang sedang dipecah. Prosedur
dapat dimodifikasi untuk menyalin data dari node yang dipecah secara langsung ke node yang baru
dibuat, sehingga mengurangi waktu yang diperlukan untuk menyalin data. Namun, penggunaan ruang
sementaraT menyederhanakan prosedur.

14.3.3.2 Penghapusan

Kami sekarang mempertimbangkan penghapusan yang menyebabkan simpul pohon berisi terlalu sedikit
pointer. Pertama, mari kita hapus “Srinivasan” dari B+-pohon Gambar 14.14. B . yang dihasilkan+-pohon
muncul pada Gambar 14.18. Kami sekarang mempertimbangkan bagaimana penghapusan dilakukan.
Kami pertama-tama menemukan entri untuk "Srinivasan" dengan menggunakan algoritma pencarian
kami. Ketika kita menghapus entri untuk "Srinivasan" dari simpul daunnya, simpul yang tersisa hanya
satu entri, "Wu". Karena, dalam contoh kita,n = 4 dan 1 < (n - 1)/2, kita harus menggabungkan node
dengan node saudara atau mendistribusikan kembali entri di antara node, untuk memastikan bahwa
setiap node setidaknya setengah penuh. Dalam contoh kita, node underfull dengan entri untuk "Wu"
dapat digabungkan dengan node saudara kirinya. Kami menggabungkan node dengan memindahkan
entri dari kedua node ke saudara kiri dan menghapus saudara kanan yang sekarang kosong. Setelah
node dihapus, kita juga harus menghapus entri di node induk yang menunjuk ke node yang baru saja
dihapus.
Dalam contoh kita, entri yang akan dihapus adalah (Srinivasan, n3), dimana n3 adalah penunjuk ke
daun yang mengandung “Srinivasan”. (Dalam hal ini entri yang akan dihapus di simpul nonleaf kebetulan
memiliki nilai yang sama dengan yang dihapus dari daun; itu tidak akan terjadi pada sebagian besar
penghapusan.) Setelah menghapus entri di atas, simpul induk, yang memiliki nilai kunci pencarian
"Srinivasan" dan dua pointer, sekarang memiliki satu pointer (pointer paling kiri di node) dan tidak ada
nilai kunci pencarian. Sejak 1< kann/2kan untuk n = 4, simpul induk kurang penuh. (Untuk lebih besarn,
sebuah simpul yang menjadi kurang penuh akan tetap memiliki beberapa nilai serta petunjuk.)

Emas

Kaligrafi Einstein Mozart

Adams Brandt Kaligrafi krik Einstein El Said Emas Katz Kim Mozart Singh Wu

Gambar 14.18 Penghapusan "Srinivasan" dari B+-pohon Gambar 14.14.


646 Bab 14 Pengindeksan

Dalam hal ini, kita melihat simpul saudara; dalam contoh kita, satu-satunya saudara
kandung adalah node nonleaf yang berisi kunci pencarian "Califieri", "Einstein", dan "Emas".
Jika memungkinkan, kami mencoba menggabungkan node dengan saudaranya. Dalam hal
ini, penggabungan tidak mungkin, karena simpul dan saudaranya bersama-sama memiliki
lima pointer, melawan maksimal empat. Solusi dalam hal ini adalahmendistribusikan
kembali pointer antara node dan saudaranya, sehingga masing-masing memiliki setidaknya
kann/2= 2 penunjuk anak. Untuk melakukannya, kami memindahkan pointer paling kanan
dari saudara kiri (yang menunjuk ke simpul daun yang berisi "Emas") ke saudara kanan yang
kurang lengkap. Namun, saudara kandung kanan yang kurang lengkap sekarang akan
memiliki dua pointer, yaitu pointer paling kiri, dan pointer yang baru dipindahkan, tanpa
nilai yang memisahkannya. Faktanya, nilai yang memisahkan mereka tidak ada di salah satu
node, tetapi ada di node induk, antara pointer dari induk ke node dan saudara kandungnya.
Dalam contoh kami, nilai "Mozart" memisahkan dua pointer dan hadir di saudara kandung
yang tepat setelah redistribusi. Redistribusi pointer juga berarti bahwa nilai "Mozart" di
induk tidak lagi dengan benar memisahkan nilai kunci pencarian di dua saudara kandung.
Faktanya,
Akibatnya, seperti yang dapat dilihat pada B+-pohon pada Gambar 14.18, setelah redistribusi
pointer antara saudara kandung, nilai "Emas" telah pindah ke induk, sedangkan
nilai yang ada sebelumnya, "Mozart", telah pindah ke saudara kanan.
Kami selanjutnya menghapus nilai kunci pencarian "Singh" dan "Wu" dari B+-pohon Gambar
14.18. Hasilnya ditunjukkan pada Gambar 14.19. Penghapusan pertama dari nilai-nilai ini tidak
membuat simpul daun kurang penuh, tetapi penghapusan nilai kedua tidak. Tidak mungkin untuk
menggabungkan node underfull dengan saudaranya, sehingga redistribusi nilai dilakukan,
memindahkan nilai kunci pencarian "Kim" ke dalam node yang berisi "Mozart", menghasilkan
pohon yang ditunjukkan pada Gambar 14.19. Nilai yang memisahkan dua saudara kandung telah
diperbarui di induknya, dari "Mozart" menjadi "Kim".
Sekarang kami menghapus "Emas" dari pohon di atas; hasilnya ditunjukkan pada Gambar 14.20. Ini
menghasilkan daun yang kurang penuh, yang sekarang dapat digabungkan dengan saudara
kandungnya. Penghapusan yang dihasilkan dari entri dari node induk (node nonleaf berisi "Kim")
membuat induk kurang penuh (hanya tersisa satu pointer). Kali ini, simpul induk dapat digabungkan
dengan saudara kandungnya. Penggabungan ini menghasilkan nilai kunci pencarian "Emas"

Emas

Kaligrafi Einstein Kim

Adams Brandt Kaligrafi krik Einstein El Said Emas Katz Kim Mozart

Gambar 14.19 Penghapusan "Singh" dan "Wu" dari B+-pohon Gambar 14.18.
14.3 B+-File Indeks Pohon 647

Kaligrafi Einstein Emas

Adams Brandt Kaligrafi krik Einstein El Said Katz Kim Mozart

Gambar 14.20 Penghapusan "Emas" dari B+-pohon Gambar 14.19.

bergerak turun dari induk ke simpul gabungan. Sebagai hasil dari penggabungan ini,
sebuah entri dihapus dari induknya, yang merupakan akar dari pohon. Dan sebagai
hasil dari penghapusan itu, root hanya memiliki satu pointer anak dan tidak ada nilai
kunci pencarian, melanggar ketentuan bahwa root harus memiliki setidaknya dua
anak. Akibatnya, simpul akar dihapus dan anak tunggalnya menjadi akar, dan
kedalaman B+-pohon berkurang 1.
Perlu dicatat bahwa, sebagai akibat dari penghapusan, nilai kunci yang ada di node
nonleaf dari B+-pohon mungkin tidak ada di setiap daun pohon. Misalnya, pada Gambar
14.20, nilai "Emas" telah dihapus dari level daun tetapi masih ada di simpul
nonleaf.
Secara umum, untuk menghapus nilai dalam B+-tree, kami melakukan pencarian pada nilai dan
Hapus. Jika node terlalu kecil, kami menghapusnya dari induknya. Penghapusan ini
menghasilkan aplikasi rekursif dari algoritma penghapusan sampai akar tercapai, induk
tetap cukup penuh setelah penghapusan, atau redistribusi diterapkan.
Gambar 14.21 menguraikan pseudocode untuk penghapusan dari B+-pohon. Prosedur
tukar variabel(n, nkan) hanya menukar nilai variabel (penunjuk) n dan nkan; swap ini tidak berpengaruh
pada pohon itu sendiri. Pseudocode menggunakan kondisi "terlalu sedikit pointer/nilai." Untuk simpul
tak berdaun, kriteria ini berarti kurang darikann/2kan petunjuk; untuk simpul daun, artinya kurang dari(n
1)/2kan nilai-nilai. Pseudocode mendistribusikan ulang entri dengan meminjam satu entri dari node yang
berdekatan. Kami juga dapat mendistribusikan ulang entri dengan mempartisi ulang entri secara merata
di antara dua node. Pseudocode mengacu pada penghapusan entri (K, P) dari sebuah simpul. Dalam
kasus simpul daun, penunjuk ke entri sebenarnya mendahului nilai kunci, jadi penunjukP mendahului
nilai kunci K. Untuk simpul tak berdaun,
P mengikuti nilai kunci K.

14.3.4 Kompleksitas B+-Pembaruan Pohon

Meskipun operasi penyisipan dan penghapusan pada B+-pohon rumit, mereka membutuhkan
operasi I/O yang relatif sedikit, yang merupakan manfaat penting karena operasi I/O mahal.
Dapat ditunjukkan bahwa jumlah operasi I/O yang dibutuhkan dalam kasus terburuk
untuk penyisipan sebanding dengan catatankann/2kan(n), di mana n adalah jumlah maksimum
pointer dalam sebuah node, dan n adalah jumlah record dalam file yang diindeks.
Kompleksitas kasus terburuk dari prosedur penghapusan juga sebanding dengan
catatankann/2kan(n), asalkan tidak ada nilai duplikat untuk kunci pencarian; kita membahas kasus
kunci pencarian yang tidak unik nanti dalam bab ini.
648 Bab 14 Pengindeksan

prosedur menghapus(nilai K, penunjuk P)


temukan simpul daun L yang berisi (K, P)
hapus entri(L, K, P)

prosedur hapus entri(simpul N, nilai K, penunjuk P)


menghapus (K, P) dari n
jika (n adalah akarnya dan n hanya memiliki satu anak yang tersisa)
kemudian membuat anak dari n akar baru pohon dan hapus n
lain jika (n memiliki terlalu sedikit nilai/petunjuk) lalu mulai
Membiarkan nkan menjadi anak sebelumnya atau berikutnya dari induk(n)
Membiarkan Kkan menjadi nilai antara pointer n dan nkan di dalam induk(n)
jika (entri di n dan nkan bisa muat dalam satu node)
lalu mulai /* Node gabungan */
jika (n adalah pendahulu dari nkan) kemudian bertukar variabel (n, nkan)
jika (n bukan daun)
kemudian menambahkan Kkan dan semua petunjuk dan nilai dalam n ke nkan

lain tambahkan semua (KSaya, PSaya) berpasangan n ke nkan; mengaturnkan.Pn = NPn

hapus entri(induk(n), Kkan, n); hapus simpuln


akhir

lain mulai /* Redistribusi: pinjam entri dari nkan */


jika (nkan adalah pendahulu dari n) lalu mulai
jika (n adalah simpul tak berdaun) lalu mulai
membiarkan M jadilah seperti itu nkan.PM adalah penunjuk terakhir dalam nkan

menghapus (nkan.KM1, nkan.PM) dari nkan


memasukkan (nkan.PM, Kkan) sebagai penunjuk dan nilai pertama dalam n,
dengan menggeser pointer dan nilai lainnya ke kanan
mengganti Kkan di dalam induk(n) oleh nkan.KM1
akhir

lain mulai
membiarkan M jadilah (nkan.PM, nkan.KM) adalah pasangan penunjuk/nilai terakhir
di nkan
menghapus (nkan.PM, nkan.KM) dari nkan
memasukkan (nkan.PM, nkan.KM) sebagai penunjuk dan nilai pertama dalam n,
dengan menggeser pointer dan nilai lainnya ke kanan
mengganti Kkan di dalam induk(n) oleh nkan.KM

akhir

akhir

lain … simetris dengan kemudian kasus …


akhir

akhir

Gambar 14.21 Penghapusan entri dari B+-pohon.


14.3 B+-File Indeks Pohon 649

Dengan kata lain, biaya operasi penyisipan dan penghapusan dalam hal operasi I/O
sebanding dengan ketinggian B+-pohon, dan karena itu rendah. Ini adalah kecepatan
operasi pada B+-trees yang menjadikannya struktur indeks yang sering digunakan dalam
implementasi basis data.
Dalam prakteknya, operasi pada B+-pohon menghasilkan lebih sedikit operasi I/O daripada yang terburuk-
batas kasus. Dengan fanout 100, dan dengan asumsi akses ke simpul daun terdistribusi
secara seragam, induk dari simpul daun 100 kali lebih mungkin untuk diakses daripada
simpul daun. Sebaliknya, dengan fanout yang sama, jumlah total node nonleaf di B+- pohon
hanya sedikit lebih dari 1/100 jumlah simpul daun. Akibatnya, dengan ukuran memori
beberapa gigabyte yang umum saat ini, untuk B+-pohon yang sering digunakan, bahkan jika
relasinya sangat besar, kemungkinan besar sebagian besar node nonleaf sudah berada di
buffer database saat diakses. Jadi, biasanya hanya satu atau dua operasi I/O yang diperlukan
untuk melakukan pencarian. Untuk pembaruan, kemungkinan terjadinya pemisahan simpul
sangat kecil. Bergantung pada urutan sisipan, dengan fanout 100, hanya dari 1 dalam 100
hingga 1 dalam 50 sisipan yang akan menghasilkan pemisahan simpul, yang membutuhkan
lebih dari satu blok untuk ditulis. Akibatnya, rata-rata penyisipan hanya memerlukan sedikit
lebih dari satu operasi I/O untuk menulis blok yang diperbarui.
Meskipun B+-trees hanya menjamin bahwa node setidaknya setengah penuh, jika entrinya
dimasukkan dalam urutan acak, rata-rata node dapat diharapkan lebih dari dua pertiga penuh. Jika entri
dimasukkan dalam urutan yang diurutkan, di sisi lain, node hanya akan setengah penuh. (Kami
meninggalkannya sebagai latihan bagi pembaca untuk mencari tahu mengapa node hanya setengah
penuh dalam kasus terakhir.)

14.3.5 Tombol Pencarian Tidak Unik

Kami telah mengasumsikan sejauh ini bahwa kunci pencarian itu unik. Ingat juga yang kami
jelaskan sebelumnya, di Bagian 14.3.1, cara membuat kunci pencarian unik dengan membuat
kunci pencarian gabungan yang berisi kunci pencarian asli dan atribut tambahan, yang bersama-
sama unik di semua catatan.
Atribut tambahan dapat berupa record-id, yang merupakan pointer ke record, atau
primary key, atau atribut lain yang nilainya unik di antara semua record dengan nilai search-
key yang sama. Atribut tambahan disebut apemersatu atribut.
Pencarian dengan atribut kunci pencarian asli dapat dilakukan dengan menggunakan pencarian rentang
seperti yang kita lihat di Bagian 14.3.2; sebagai alternatif, kita dapat membuat varian darifindRange
fungsi yang hanya menggunakan nilai kunci pencarian asli sebagai parameter dan mengabaikan
nilai atribut uniquifier saat membandingkan nilai kunci pencarian.
Dimungkinkan juga untuk memodifikasi B+-struktur pohon untuk mendukung kunci pencarian duplikat.
Metode penyisipan, penghapusan, dan pencarian semuanya harus dimodifikasi secara bersamaan.

• Salah satu alternatifnya adalah menyimpan setiap nilai kunci hanya sekali di pohon, dan
menyimpan ember (atau daftar) penunjuk catatan dengan nilai kunci pencarian, untuk menangani
kunci pencarian yang tidak unik. Pendekatan ini hemat ruang karena hanya menyimpan nilai kunci
satu kali; namun, ini menciptakan beberapa komplikasi ketika B+-pohon dilaksanakan. jika
650 Bab 14 Pengindeksan

ember disimpan di simpul daun, kode tambahan diperlukan untuk menangani ember ukuran
variabel, dan untuk menangani ember yang tumbuh lebih besar dari ukuran simpul daun. Jika
bucket disimpan dalam blok terpisah, operasi I/O tambahan mungkin diperlukan untuk mengambil
record.

• Pilihan lainnya adalah menyimpan nilai kunci pencarian sekali per record; pendekatan ini
memungkinkan simpul daun untuk dipecah dengan cara biasa jika ditemukan penuh selama
penyisipan. Namun, pendekatan ini membuat penanganan split dan pencarian pada node
internal secara signifikan lebih rumit, karena dua daun mungkin berisi nilai kunci pencarian
yang sama. Ini juga memiliki overhead ruang yang lebih tinggi, karena nilai kunci disimpan
sebanyak ada catatan yang berisi nilai itu.

Masalah utama dengan kedua pendekatan ini, dibandingkan dengan pendekatan kunci
pencarian yang unik, terletak pada efisiensi penghapusan catatan. (Kompleksitas pencarian dan
penyisipan sama dengan kedua pendekatan ini, serta dengan pendekatan kunci pencarian yang
unik.) Misalkan nilai kunci pencarian tertentu muncul berkali-kali, dan salah satu catatan dengan
kunci pencarian itu akan dihapus. Penghapusan mungkin harus mencari melalui sejumlah entri
dengan nilai kunci pencarian yang sama, berpotensi melintasi beberapa simpul daun, untuk
menemukan entri yang sesuai dengan catatan tertentu yang sedang dihapus. Dengan demikian,
kompleksitas penghapusan kasus terburuk mungkin linier dalam jumlah catatan.
Sebaliknya, penghapusan record dapat dilakukan secara efisien menggunakan pendekatan
kunci pencarian yang unik. Saat record akan dihapus, nilai kunci pencarian gabungan dihitung
dari record dan kemudian digunakan untuk mencari indeks. Karena nilainya unik, entri tingkat
daun yang sesuai dapat ditemukan dengan satu traversal dari akar ke daun, tanpa akses lebih
lanjut pada tingkat daun. Biaya penghapusan kasus terburuk adalah logaritmik dalam jumlah
catatan, seperti yang kita lihat sebelumnya.
Karena inefisiensi penghapusan, serta komplikasi lain karena duplikat kunci pencarian, B+
implementasi -tree di sebagian besar sistem database hanya menangani kunci pencarian yang unik, dan
mereka secara otomatis menambahkan record-id atau atribut lain untuk membuat kunci pencarian yang
tidak unik menjadi unik.

14.4 B+-Ekstensi Pohon

Pada bagian ini, kita membahas beberapa ekstensi dan variasi dari B+-struktur indeks pohon.

14.4.1 B+-Organisasi File Pohon


Seperti disebutkan dalam Bagian 14.3, kelemahan utama dari pengorganisasian file urutan indeks
adalah penurunan kinerja seiring pertumbuhan file: Dengan pertumbuhan, persentase entri
indeks dan catatan aktual yang meningkat menjadi rusak dan disimpan dalam blok overflow. Kami
memecahkan degradasi pencarian indeks dengan menggunakan B+-indeks pohon pada file.
14.4 B+-Ekstensi Pohon 651

Saya

C F km

(A,4) (B,8) (C,1) (D,9) (E,4) (F,7) (G,3) (H,3)

(I,4) (J,8) (K,1) (L,6) (M,4) (N,8) (P,6)

Gambar 14.22 B+-organisasi file pohon.

Kami memecahkan masalah degradasi untuk menyimpan catatan aktual dengan menggunakan
level daun dari B+-tree untuk mengatur blok yang berisi catatan aktual. Kami menggunakan B+
-struktur pohon tidak hanya sebagai indeks, tetapi juga sebagai pengatur catatan dalam sebuah
file. Di sebuahB+-organisasi file pohon, simpul daun dari pohon menyimpan catatan, alih-alih
menyimpan pointer ke catatan. Gambar 14.22 menunjukkan contoh B+-organisasi file pohon.
Karena record biasanya lebih besar dari pointer, jumlah maksimum record yang dapat disimpan di
leaf node kurang dari jumlah pointer di nonleaf node. Namun, simpul daun masih harus
setidaknya setengah penuh.
Penyisipan dan penghapusan catatan dari B+-organisasi file pohon ditangani di
dengan cara yang sama seperti penyisipan dan penghapusan entri dalam B+-indeks pohon Ketika
sebuah record dengan nilai kunci yang diberikanv dimasukkan, sistem menempatkan blok yang
seharusnya berisi catatan dengan mencari B+-pohon untuk kunci terbesar di pohon yaitu ≤ v. Jika blok
yang terletak memiliki ruang kosong yang cukup untuk catatan, sistem menyimpan catatan di blok. Jika
tidak, seperti pada B+penyisipan -tree, sistem membagi blok menjadi dua dan mendistribusikan kembali
catatan di dalamnya (di B+-tree–key order) untuk membuat ruang untuk record baru. Perpecahan
menyebar ke atas B+-pohon dengan cara biasa. Saat kami menghapus catatan, sistem terlebih dahulu
menghapusnya dari blok yang memuatnya. Jika sebuah blokB menjadi kurang dari setengah penuh
sebagai hasilnya, catatan di B didistribusikan kembali dengan catatan di blok yang berdekatan Bkan.
Dengan asumsi catatan berukuran tetap, setiap blok akan menampung setidaknya setengah dari jumlah
maksimum yang dapat dipegangnya. Sistem memperbarui node nonleaf dari B+-pohon dengan cara
biasa.
Ketika kita menggunakan B+-pohon untuk organisasi file, pemanfaatan ruang sangat penting-
tant, karena ruang yang ditempati oleh catatan kemungkinan lebih besar daripada ruang yang ditempati
oleh tombol dan pointer. Kita dapat meningkatkan pemanfaatan ruang di B+-tree dengan melibatkan
lebih banyak simpul saudara dalam redistribusi selama pemisahan dan penggabungan. Teknik ini
berlaku untuk node daun dan node nonleaf, dan bekerja sebagai berikut:
Selama penyisipan, jika sebuah node penuh, sistem mencoba untuk mendistribusikan
kembali beberapa entrinya ke salah satu node yang berdekatan, untuk memberi ruang bagi entri
baru. Jika upaya ini gagal karena node yang berdekatan itu sendiri penuh, sistem membagi node
dan membagi entri secara merata di antara salah satu node yang berdekatan dan dua node yang
diperoleh dengan memisahkan node asli. Karena tiga simpul bersama-sama berisi satu catatan lagi
652 Bab 14 Pengindeksan

daripada yang bisa muat di dua node, setiap node akan menjadi sekitar dua pertiga penuh. Lebih tepatnya,
setiap node akan memiliki setidaknyakan2n/3kan entri, di mana n adalah jumlah maksimum entri yang dapat
ditampung oleh node. (kanxkan menunjukkan bilangan bulat terbesar yang kurang dari atau sama dengan x;
yaitu, kami membuang bagian pecahan, jika ada.)
Selama penghapusan catatan, jika hunian sebuah node turun di bawah kan2n/3, sistem
mencoba meminjam entri dari salah satu node saudara. Jika kedua node saudara memilikikan2n/3
kan catatan, alih-alih meminjam entri, sistem mendistribusikan kembali entri di node dan di dua
saudara kandung secara merata di antara dua node dan menghapus node ketiga. Kita dapat
menggunakan pendekatan ini karena jumlah total entri adalah 3kan2n/3⌋ - 1, yang kurang dari 2n.
Dengan tiga node yang berdekatan digunakan untuk redistribusi, setiap node dapat dijamin
memilikikan3n/4kan entri. Secara umum, jikaMsimpul (M1 saudara kandung) terlibat dalam
redistribusi, setiap node dapat dijamin mengandung setidaknya (M1)n/Mkan entri. Namun, biaya
pembaruan menjadi lebih tinggi karena lebih banyak node saudara yang terlibat dalam
redistribusi.
Perhatikan bahwa dalam B+-indeks pohon atau organisasi file, simpul daun yang berdekatan satu sama lain
lainnya di pohon mungkin terletak di tempat yang berbeda pada disk. Ketika organisasi file baru dibuat
pada sekumpulan record, dimungkinkan untuk mengalokasikan blok yang sebagian besar bersebelahan
pada disk ke node daun yang bersebelahan di pohon. Dengan demikian, pemindaian sekuensial node
daun akan sesuai dengan sebagian besar pemindaian berurutan pada disk. Saat penyisipan dan
penghapusan terjadi di pohon, sekuensial semakin hilang, dan akses sekuensial harus menunggu
pencarian disk semakin sering. Rekondisi indeks mungkin diperlukan untuk memulihkan urutan.

B+-organisasi file pohon juga dapat digunakan untuk menyimpan objek besar, seperti SQL clobs
dan gumpalan, yang mungkin lebih besar dari satu blok disk, dan sebesar beberapa gigabyte.
Objek besar seperti itu dapat disimpan dengan membaginya menjadi urutan catatan yang lebih
kecil yang diatur dalam B+-organisasi file pohon. Catatan dapat diberi nomor secara berurutan,
atau diberi nomor dengan offset byte dari catatan dalam objek besar, dan nomor catatan dapat
digunakan sebagai kunci pencarian.

14.4.2 Indeks Sekunder dan Relokasi Catatan


Beberapa organisasi file, seperti B+-organisasi file pohon, dapat mengubah lokasi catatan bahkan
ketika catatan belum diperbarui. Sebagai contoh, ketika simpul daun dipecah menjadi B+-tree file
organization, sejumlah record dipindahkan ke node baru. Dalam kasus seperti itu, semua indeks
sekunder yang menyimpan penunjuk ke rekaman yang dipindahkan harus diperbarui, meskipun
nilai dalam rekaman mungkin tidak berubah. Setiap simpul daun mungkin berisi sejumlah catatan
yang cukup besar, dan masing-masing mungkin berada di lokasi yang berbeda pada setiap indeks
sekunder. Jadi, pemisahan leaf-node mungkin memerlukan puluhan atau bahkan ratusan operasi
I/O untuk memperbarui semua indeks sekunder yang terpengaruh, menjadikannya operasi yang
sangat mahal.
Solusi yang banyak digunakan untuk masalah ini adalah sebagai berikut: Dalam indeks sekunder, sebagai
pengganti pointer ke catatan yang diindeks, kami menyimpan nilai kunci pencarian indeks utama
14.4 B+-Ekstensi Pohon 653

atribut. Misalnya, kita memiliki indeks utama pada atributIndo hubungan


pengajar; kemudian indeks sekunder padanama departemen akan menyimpan dengan masing-
masing departemen nama daftar instruktur Indo nilai catatan yang sesuai, alih-alih menyimpan
pointer ke catatan.
Relokasi catatan karena pemisahan leaf-node maka tidak memerlukan pembaruan apa pun pada indeks
sekunder semacam itu. Namun, mencari catatan menggunakan indeks sekunder sekarang memerlukan dua
langkah: Pertama kita menggunakan indeks sekunder untuk menemukan nilai kunci pencarian indeks utama,
dan kemudian kita menggunakan indeks utama untuk menemukan catatan yang sesuai.
Pendekatan ini dengan demikian sangat mengurangi biaya pembaruan indeks karena reorganisasi
file, meskipun meningkatkan biaya mengakses data menggunakan indeks sekunder.

14.4.3 String Pengindeksan

Membuat B+-indeks pohon pada atribut bernilai string menimbulkan dua masalah. Masalah
pertama adalah string dapat memiliki panjang variabel. Masalah kedua adalah string bisa
panjang, menyebabkan fanout yang rendah dan tinggi pohon yang meningkat.
Dengan kunci pencarian dengan panjang variabel, node yang berbeda dapat memiliki fanout yang
berbeda meskipun penuh. Sebuah node kemudian harus dipecah jika sudah penuh, yaitu, tidak ada ruang untuk
menambahkan entri baru, terlepas dari berapa banyak entri pencarian yang dimilikinya. Demikian pula, node
dapat digabungkan atau entri didistribusikan kembali tergantung pada fraksi ruang di node yang digunakan,
alih-alih didasarkan pada jumlah maksimum entri yang dapat disimpan oleh node.
Fanout node dapat ditingkatkan dengan menggunakan teknik yang disebut kompresi awalan.
Dengan kompresi awalan, kami tidak menyimpan seluruh nilai kunci pencarian di node nonleaf.
Kami hanya menyimpan awalan dari setiap nilai kunci pencarian yang cukup untuk membedakan
antara nilai kunci dalam subpohon yang dipisahkannya. Misalnya, jika kita memiliki indeks pada
nama, nilai kunci pada simpul nonleaf bisa menjadi awalan nama; mungkin cukup untuk
menyimpan "Silb" di simpul nonleaf, alih-alih "Silberschatz" penuh jika nilai terdekat dalam dua
subpohon yang dipisahkan adalah, katakanlah, "Silas" dan "Silver" masing-masing.

14.4.4 Pemuatan Massal B+-Indeks Pohon

Seperti yang kita lihat sebelumnya, penyisipan catatan dalam B+-tree membutuhkan sejumlah
operasi I/O yang dalam kasus terburuk sebanding dengan tinggi pohon, yang biasanya cukup
kecil (biasanya lima atau kurang, bahkan untuk relasi besar).
Sekarang perhatikan kasus di mana a B+-tree sedang dibangun di atas relasi besar. Memperkirakan
relasi secara signifikan lebih besar dari memori utama, dan kami sedang membangun indeks
nonclustering pada relasi sedemikian rupa sehingga indeks juga lebih besar dari memori utama.
Dalam hal ini, saat kita memindai relasi dan menambahkan entri ke B+-tree, kemungkinan besar
setiap simpul daun yang diakses tidak berada dalam buffer database saat diakses, karena tidak
ada urutan entri tertentu. Dengan akses yang dipesan secara acak ke blok, setiap kali entri
ditambahkan ke daun, pencarian disk akan diperlukan untuk mengambil blok yang berisi simpul
daun. Blok mungkin akan dikeluarkan dari buffer disk sebelum entri lain ditambahkan ke blok,
yang mengarah ke disk lain yang berusaha menulis blok kembali
654 Bab 14 Pengindeksan

ke disk. Jadi, operasi baca acak dan tulis acak mungkin diperlukan untuk setiap entri yang
dimasukkan.
Misalnya, jika relasi memiliki 100 juta record, dan setiap operasi I/O membutuhkan waktu sekitar 10
milidetik pada disk magnetik, dibutuhkan setidaknya 1 juta detik untuk membangun indeks, hanya
menghitung biaya membaca simpul daun, bahkan tidak menghitung biaya penulisan node yang
diperbarui kembali ke disk. Ini jelas merupakan waktu yang sangat lama; sebaliknya, jika setiap record
menempati 100 byte, dan subsistem disk dapat mentransfer data dengan kecepatan 50 megabyte per
detik, hanya dibutuhkan 200 detik untuk membaca seluruh relasi.
Penyisipan sejumlah besar entri pada suatu waktu ke dalam indeks disebut sebagai
pemuatan massal dari indeks. Cara yang efisien untuk melakukan pemuatan indeks secara massal
adalah sebagai berikut: Pertama, buat file sementara yang berisi entri indeks untuk relasi, lalu
urutkan file pada kunci pencarian indeks yang sedang dibangun, dan terakhir pindai file yang
diurutkan dan masukkan entri ke dalam indeks. Ada algoritma yang efisien untuk menyortir relasi
besar, yang dijelaskan kemudian di Bagian 15.4, yang dapat mengurutkan bahkan file besar
dengan biaya I/O yang sebanding dengan membaca file beberapa kali, dengan asumsi tersedia
jumlah memori utama yang wajar.
Ada manfaat yang signifikan untuk menyortir entri sebelum memasukkannya ke dalam B+
-pohon. Ketika entri dimasukkan dalam urutan yang diurutkan, semua entri yang masuk ke simpul
daun tertentu akan muncul secara berurutan, dan daun hanya perlu ditulis sekali; node tidak akan
pernah harus dibaca dari disk selama beban massal, jika B+-tree kosong untuk memulai. Setiap
simpul daun dengan demikian hanya akan dikenakan satu operasi I/O meskipun banyak entri
dapat dimasukkan ke dalam simpul. Jika setiap daun berisi 100 entri, tingkat daun akan berisi 1
juta node, menghasilkan hanya 1 juta operasi I/O untuk membuat tingkat daun. Bahkan operasi I/
O ini dapat diharapkan menjadi sekuensial, jika node daun yang berurutan dialokasikan pada blok
disk yang berurutan, dan beberapa pencarian disk akan diperlukan. Dengan disk magnetik, 1
milidetik per blok adalah perkiraan yang masuk akal untuk sebagian besar operasi I/O sekuensial,
berbeda dengan 10 milidetik per blok untuk operasi I/O acak.

Kami akan mempelajari biaya penyortiran hubungan besar nanti, di Bagian 15.4, tetapi
sebagai perkiraan kasar, indeks yang seharusnya memakan waktu hingga 1.000.000 detik untuk
membangun pada disk magnetik dapat dibangun di bawah 1000 detik dengan menyortir entri
sebelum memasukkannya ke dalam B+-pohon. Jika B+-pohon awalnya kosong, dapat dibangun
lebih cepat dengan membangunnya di bawah-
naik, dari tingkat daun, alih-alih menggunakan prosedur penyisipan biasa. Di dalambawah ke atas B+-
konstruksi pohon, setelah mengurutkan entri seperti yang baru saja kami jelaskan, kami memecah entri
yang diurutkan ke dalam blok, menyimpan entri sebanyak mungkin dalam satu blok; blok yang
dihasilkan membentuk tingkat daun B+-pohon. Nilai minimum di setiap blok, bersama dengan penunjuk
ke blok, digunakan untuk membuat entri di level B . berikutnya+- pohon, menunjuk ke blok daun. Setiap
level selanjutnya dari pohon dibangun dengan cara yang sama menggunakan nilai minimum yang
terkait dengan setiap node satu level di bawahnya, hingga root dibuat. Kami meninggalkan detail
sebagai latihan untuk pembaca.
Sebagian besar sistem database menerapkan teknik yang efisien berdasarkan penyortiran entri,
dan konstruksi bottom-up, saat membuat indeks pada relasi, meskipun mereka menggunakan
14.4 B+-Ekstensi Pohon 655

Einstein Katz Singh

Einstein
Katz Singh
catatan
catatan catatan

Brandt Crick Kalifiri El Said Emas Kim Mozart Srinivasan Wu

Brandt Kaligrafi
. . . dan seterusnya untuk catatan lainnya...
catatan catatan

Gambar 14.23 B-pohon setara dengan B+-pohon pada Gambar 14.9.

prosedur penyisipan normal ketika tupel ditambahkan satu per satu ke relasi dengan indeks
yang ada. Beberapa sistem database merekomendasikan bahwa jika sejumlah besar tupel
ditambahkan sekaligus ke relasi yang sudah ada, indeks pada relasi (selain indeks apa pun
pada kunci utama) harus dihapus, dan kemudian dibuat kembali setelah tupel dimasukkan. ,
untuk memanfaatkan teknik pemuatan massal yang efisien.

14.4.5 File Indeks B-Tree


indeks B-pohon mirip dengan B+-indeks pohon. Perbedaan utama antara kedua pendekatan
tersebut adalah bahwa B-tree menghilangkan penyimpanan nilai kunci pencarian yang
berlebihan. Di B+-pohon pada Gambar 14.9, kunci pencarian “Einstein”, “Emas”, “Mozart”, dan
“Srinivasan” muncul di node nonleaf, selain muncul di node daun. Setiap nilai kunci pencarian
muncul di beberapa simpul daun; beberapa diulang dalam node nonleaf.
B-tree memungkinkan nilai kunci pencarian muncul hanya sekali (jika unik), tidak seperti
B+-tree, di mana nilai dapat muncul di simpul nonleaf, selain muncul di simpul daun. Gambar
14.23 menunjukkan B-tree yang mewakili kunci pencarian yang sama dengan B+-pohon dari
Gambar 14.9. Karena kunci pencarian tidak diulang di pohon B, kami mungkin dapat
menyimpan indeks di simpul pohon yang lebih sedikit daripada di B yang sesuai.+-indeks
pohon Namun, karena kunci pencarian yang muncul di node nonleaf muncul di tempat lain
di B-tree, kami dipaksa untuk memasukkan bidang pointer tambahan untuk setiap kunci
pencarian di node nonleaf. Pointer tambahan ini mengarah ke record file atau bucket untuk
kunci pencarian terkait.
Perlu dicatat bahwa banyak manual sistem database, artikel dalam literatur industri, dan
profesional industri menggunakan istilah B-tree untuk merujuk pada struktur data yang kita sebut
B.+-pohon. Bahkan, akan adil untuk mengatakan bahwa dalam penggunaan saat ini, istilah B-tree
diasumsikan identik dengan B.+-pohon. Namun, dalam buku ini kami menggunakan istilah B-tree
dan B+-tree seperti yang didefinisikan pada awalnya, untuk menghindari kebingungan antara dua
struktur data.
Sebuah simpul daun B-tree umum muncul pada Gambar 14.24a; node nonleaf muncul
pada Gambar 14.24b. Node daun sama dengan di B+-pohon. Dalam node nonleaf, pointer
PSaya adalah penunjuk pohon yang kami gunakan juga untuk B+-pohon, sedangkan penunjuknya BSaya adalah
pointer ember atau file-record. Dalam pohon B yang digeneralisasi pada gambar, adan - 1 kunci masuk
656 Bab 14 Pengindeksan

P1 K1 P2 … Pn-1 Kn-1 Pn

(A)

P1 B1 K1 P2 B2 K2 … PM-1 BM-1 KM-1 PM

(B)

Gambar 14.24 Node tipikal dari B-tree. (a) Nodus daun. (b) Node tak berdaun.

simpul daun, tetapi ada M - 1 kunci di simpul nonleaf. Perbedaan ini terjadi
karena node nonleaf harus menyertakan pointer BSaya, sehingga mengurangi jumlah kunci
pencarian yang dapat disimpan di node ini. Jelas,m < n, tetapi hubungan yang tepat antara
M dan n tergantung pada ukuran relatif dari tombol pencarian dan pointer.
Jumlah node yang diakses dalam pencarian di B-tree tergantung di mana kunci pencarian berada.
Sebuah pencarian pada B+-tree membutuhkan lintasan lintasan dari akar pohon ke beberapa simpul
daun. Sebaliknya, kadang-kadang mungkin untuk menemukan nilai yang diinginkan dalam pohon-B
sebelum mencapai simpul daun. Namun, kira-kiran kali lebih banyak kunci disimpan di tingkat daun dari
pohon-B seperti di tingkat bukan daun, dan, karena n biasanya besar, manfaat menemukan nilai-nilai
tertentu lebih awal relatif kecil. Selain itu, fakta bahwa lebih sedikit kunci pencarian yang muncul di node
B-tree nonleaf, dibandingkan dengan B+-trees, menyiratkan bahwa B-tree memiliki fanout yang lebih
kecil dan oleh karena itu mungkin memiliki kedalaman yang lebih besar daripada B+-pohon. Jadi,
pencarian di B-tree lebih cepat untuk beberapa kunci pencarian tetapi lebih lambat untuk yang lain,
meskipun, secara umum, waktu pencarian masih sebanding dengan logaritma dari jumlah kunci
pencarian.
Penghapusan di B-tree lebih rumit. dalam B+-pohon, entri yang dihapus selalu
muncul di daun. Dalam B-tree, entri yang dihapus mungkin muncul di node nonleaf. Nilai
yang tepat harus dipilih sebagai pengganti dari subpohon dari simpul yang mengandung
entri yang dihapus. Khususnya, jika kunci pencarianKSaya dihapus, kunci pencarian terkecil muncul
di subpohon pointer PSaya +1 harus dipindahkan ke lapangan yang sebelumnya ditempati oleh KSaya.
Tindakan lebih lanjut perlu diambil jika simpul daun sekarang memiliki terlalu sedikit entri. Sebaliknya,
penyisipan di B-tree hanya sedikit lebih rumit daripada penyisipan di B+-pohon. Keuntungan ruang
dari pohon-B adalah marjinal untuk indeks besar dan biasanya tidak melebihi kerugian yang
telah kami catat. Jadi, hampir semua implementasi sistem database menggunakan B+-struktur
data pohon, bahkan jika (seperti yang telah kita bahas sebelumnya) mereka mengacu pada
struktur data sebagai pohon-B.

14.4.6 Pengindeksan pada Penyimpanan Flash

Dalam deskripsi pengindeksan kami sejauh ini, kami berasumsi bahwa data berada di disk
magnetik. Meskipun asumsi ini tetap benar untuk sebagian besar, kapasitas penyimpanan
flash telah tumbuh secara signifikan, dan biaya penyimpanan flash per gigabyte juga turun,
dan penyimpanan SSD berbasis flash kini telah menggantikan penyimpanan disk magnetik
untuk banyak aplikasi.
14.4 B+-Ekstensi Pohon 657

Standar B+-indeks pohon dapat terus digunakan bahkan pada SSD, dengan dapat diterima
memperbarui kinerja dan secara signifikan meningkatkan kinerja pencarian dibandingkan dengan penyimpanan
disk.
Penyimpanan flash disusun sebagai halaman, dan B+-struktur indeks pohon dapat digunakan
dengan SSD berbasis flash. SSD menyediakan operasi I/O acak yang jauh lebih cepat daripada disk magnetik,
hanya membutuhkan sekitar 20 hingga 100 mikrodetik untuk pembacaan halaman acak, daripada sekitar 5
hingga 10 milidetik dengan disk magnetik. Dengan demikian, pencarian berjalan lebih cepat dengan data pada
SSD, dibandingkan dengan data pada disk magnetik.
Kinerja operasi tulis lebih rumit dengan penyimpanan flash. Perbedaan penting antara penyimpanan flash
dan disk magnetik adalah bahwa penyimpanan flash tidak mengizinkan pembaruan data di tempat pada tingkat
fisik, meskipun tampaknya melakukannya secara logis. Setiap pembaruan berubah menjadi salinan+penulisan
dari seluruh halaman penyimpanan flash, yang mengharuskan salinan lama dari halaman tersebut untuk
kemudian dihapus. Halaman baru dapat ditulis dalam 20 hingga 100 mikrodetik, tetapi pada akhirnya halaman
lama perlu dihapus untuk mengosongkan halaman untuk penulisan lebih lanjut. Penghapusan dilakukan pada
tingkat blok yang berisi banyak halaman, dan penghapusan blok membutuhkan waktu 2 hingga 5 milidetik.

B yang optimal+-ukuran simpul pohon untuk penyimpanan flash lebih kecil daripada dengan magnet
disk, karena halaman flash lebih kecil dari blok disk; masuk akal jika ukuran simpul pohon dicocokkan dengan
halaman flash, karena simpul yang lebih besar akan menyebabkan beberapa penulisan halaman saat sebuah
simpul diperbarui. Meskipun halaman yang lebih kecil mengarah ke pohon yang lebih tinggi dan lebih banyak
operasi I/O untuk mengakses data, pembacaan halaman acak jauh lebih cepat dengan penyimpanan flash
sehingga dampak keseluruhan pada kinerja baca cukup kecil.
Meskipun I/O acak jauh lebih murah dengan SSD dibandingkan dengan disk magnetik, pemuatan
massal masih memberikan manfaat kinerja yang signifikan, dibandingkan dengan penyisipan tuple-at-a-
time, dengan SSD. Secara khusus, konstruksi bottom-up mengurangi jumlah penulisan halaman
dibandingkan dengan penyisipan tuple-at-a-time, bahkan jika entri diurutkan pada kunci pencarian.
Karena penulisan halaman pada flash tidak dapat dilakukan di tempat dan memerlukan penghapusan
blok yang relatif mahal di lain waktu, pengurangan jumlah penulisan halaman dengan B bottom-up+
-Konstruksi pohon memberikan manfaat kinerja yang signifikan. Beberapa ekstensi dan alternatif untuk B
+-pohon telah diusulkan untuk penyimpanan flash-
usia, dengan fokus pada pengurangan jumlah operasi penghapusan yang dihasilkan karena penulisan ulang
halaman. Salah satu pendekatan adalah menambahkan buffer ke node internal B+-trees dan merekam
pembaruan sementara di buffer di level yang lebih tinggi, mendorong pembaruan ke level yang lebih rendah
dengan malas. Ide utamanya adalah ketika sebuah halaman diperbarui, beberapa pembaruan diterapkan
bersama-sama, mengurangi jumlah penulisan halaman per pembaruan. Pendekatan lain membuat banyak
pohon dan menggabungkannya; pohon gabungan berstruktur log dan variannya didasarkan pada ide ini.
Sebenarnya, kedua pendekatan ini juga berguna untuk mengurangi biaya penulisan pada disk magnetik; kami
menguraikan kedua pendekatan ini di Bagian 14.8.

14.4.7 Pengindeksan di Memori Utama

Memori utama saat ini cukup besar dan murah sehingga banyak organisasi mampu membeli memori
utama yang cukup untuk memuat semua data operasional mereka dalam memori. B+-pohon bisa
658 Bab 14 Pengindeksan

digunakan untuk mengindeks data dalam memori, tanpa mengubah strukturnya. Namun, beberapa
pengoptimalan dimungkinkan.
Pertama, karena memori lebih mahal daripada ruang disk, struktur data internal dalam basis data memori
utama harus dirancang untuk mengurangi kebutuhan ruang. Teknik yang kita lihat di Bagian 14.4.1 untuk
meningkatkan B+-penggunaan penyimpanan pohon dapat digunakan untuk mengurangi penggunaan memori
untuk dalam memori B+-pohon.
Struktur data yang memerlukan traversal beberapa pointer dapat diterima untuk data
memori, tidak seperti dalam kasus data berbasis disk, di mana biaya I/O untuk melintasi beberapa
halaman akan sangat tinggi. Dengan demikian, struktur pohon dalam database memori utama
bisa relatif dalam, tidak seperti B+-pohon.
Perbedaan kecepatan antara memori cache dan memori utama, dan fakta bahwa data
ditransfer antara memori utama dan cache dalam unit a baris-cache (biasanya sekitar 64 byte),
menghasilkan situasi di mana hubungan antara cache dan memori utama tidak berbeda dengan
hubungan antara memori utama dan disk (meskipun dengan perbedaan kecepatan yang lebih
kecil). Saat membaca lokasi memori, jika ada dalam cache, CPU dapat menyelesaikan pembacaan
dalam 1 atau 2 nanodetik, sedangkan kehilangan cache menyebabkan penundaan sekitar 50
hingga 100 nanodetik untuk membaca data dari memori utama.
B+-pohon dengan node kecil yang sesuai dengan baris cache telah ditemukan untuk menyediakan sangat
kinerja yang baik dengan data dalam memori. seperti B+-trees memungkinkan operasi indeks diselesaikan
dengan cache miss yang jauh lebih sedikit daripada struktur pohon yang tinggi dan kurus seperti pohon biner,
karena setiap traversal node cenderung menghasilkan cache miss. Dibandingkan dengan B+-pohon dengan
node yang cocok dengan garis cache, pohon dengan node besar juga cenderung memiliki lebih banyak cache
miss karena menemukan data dalam sebuah node memerlukan pemindaian penuh konten node, mencakup
beberapa baris cache, atau pencarian biner, yang juga menghasilkan beberapa cache tidak terjawab.

Untuk database di mana data tidak sepenuhnya muat di memori, tetapi data yang sering digunakan sering
kali menjadi penghuni memori, ide berikut digunakan untuk membuat B+-struktur pohon yang menawarkan
kinerja yang baik pada disk maupun di dalam memori. Node besar digunakan untuk mengoptimalkan akses
berbasis disk, tetapi alih-alih memperlakukan data dalam node sebagai array tunggal besar kunci dan pointer,
data dalam node terstruktur sebagai pohon, dengan node yang lebih kecil yang cocok dengan ukuran garis
cache . Alih-alih memindai data secara linier atau menggunakan pencarian biner dalam sebuah node, struktur
pohon dalam B . besar+-tree node digunakan untuk mengakses data dengan jumlah cache miss yang minimal.

14.5 Indeks Hash

Hashing adalah teknik yang banyak digunakan untuk membangun indeks di memori utama; indeks tersebut
dapat dibuat sementara untuk memproses operasi gabungan (seperti yang akan kita lihat di Bagian 15.5.5) atau
mungkin merupakan struktur permanen dalam database memori utama. Hashing juga telah digunakan sebagai
cara mengatur catatan dalam file, meskipun organisasi file hash tidak terlalu banyak digunakan. Kami awalnya
hanya mempertimbangkan indeks hash dalam memori, dan kami mempertimbangkan hashing berbasis disk
nanti di bagian ini.
14.5 Indeks Hash 659

Dalam deskripsi hashing kami, kami akan menggunakan istilah Keranjang untuk menunjukkan unit
penyimpanan yang dapat menyimpan satu atau lebih catatan. Untuk indeks hash dalam memori, bucket
dapat berupa daftar entri atau catatan indeks yang ditautkan. Untuk indeks berbasis disk, ember akan
menjadi daftar blok disk yang ditautkan. Di sebuahorganisasi file hash, alih-alih penunjuk catatan, bucket
menyimpan catatan aktual; struktur seperti itu hanya masuk akal dengan data penduduk disk. Deskripsi
kami lainnya tidak bergantung pada apakah bucket menyimpan pointer record atau record yang
sebenarnya.
Secara formal, mari K menunjukkan himpunan semua nilai kunci pencarian, dan biarkan B
menunjukkan set semua alamat bucket. Afungsi hash H adalah fungsi dari K ke B. MembiarkanH
menunjukkan fungsi hash. Dengan indeks hash dalam memori, kumpulan ember hanyalah sebuah array
dari pointer, denganSayaember di offset Saya. Setiap penunjuk menyimpan kepala daftar tertaut yang
berisi entri dalam ember itu.
Untuk menyisipkan catatan dengan tombol pencarian KSaya, kita hitung H(KSaya), yang memberikan alamat
ember untuk catatan itu. Kami menambahkan entri indeks untuk catatan ke daftar di offset
Saya. Perhatikan bahwa ada varian lain dari indeks hash yang menangani kasus beberapa catatan dalam
ember secara berbeda; bentuk yang dijelaskan di sini adalah varian yang paling banyak digunakan dan
disebutrantai melimpah.
Pengindeksan hash menggunakan overflow chaining juga disebut pengalamatan tertutup (atau, lebih
jarang, hashing tertutup). Skema hashing alternatif yang disebut pengalamatan terbuka digunakan di beberapa
aplikasi, tetapi tidak cocok untuk sebagian besar aplikasi pengindeksan basis data karena pengalamatan
terbuka tidak mendukung penghapusan secara efisien. Kami tidak mempertimbangkannya lebih lanjut.
Indeks hash secara efisien mendukung kueri kesetaraan pada kunci pencarian. Untuk melakukan
mencari nilai kunci pencarian KSaya, kita cukup menghitung H(KSaya), lalu telusuri bucket dengan
alamat tersebut. Misalkan dua kunci pencarian,K5 dan K7, memiliki nilai hash yang sama; itu adalah,
H(K5) = H(K7). Jika kita melakukan pencarian padaK5, ember H(K5) berisi catatan
dengan nilai kunci pencarian K5 dan merekam dengan nilai kunci pencarian K7. Jadi, kita harus memeriksa nilai
kunci pencarian dari setiap record dalam bucket untuk memverifikasi bahwa record adalah salah satu yang
kami ingin.
Tidak seperti B+-indeks pohon, indeks hash tidak mendukung kueri rentang; misalnya
kueri yang ingin mengambil semua nilai kunci pencarian v seperti yang aku ≤ v ≤ kamu tidak dapat
dijawab secara efisien menggunakan indeks hash.
Penghapusan sama mudahnya. Jika nilai kunci pencarian dari catatan menjadi
dihapus adalah KSaya, kita hitung H(KSaya), lalu telusuri bucket yang sesuai untuk record tersebut
dan hapus record dari bucket. Dengan representasi daftar tertaut, penghapusan dari
daftar tertaut sangat mudah.
Dalam indeks hash berbasis disk, ketika kami memasukkan catatan, kami menemukan ember
dengan menggunakan hashing pada kunci pencarian, seperti yang dijelaskan sebelumnya. Asumsikan
sekarang bahwa ada ruang di ember untuk menyimpan catatan. Kemudian, catatan disimpan dalam
ember itu. Jika ember tidak memiliki cukup ruang, aember meluap dikatakan terjadi. Kami menangani
luapan ember dengan menggunakanember meluap. Jika catatan harus dimasukkan ke dalam emberB,
dan B sudah penuh, sistem menyediakan ember pelimpah untuk B dan memasukkan catatan ke dalam
ember luapan. Jika ember pelimpah juga penuh, sistem menyediakan ember pelimpah lain, dan
seterusnya. Semua ember luapan dari ember yang diberikan dirantai bersama dalam satu tautan
660 Bab 14 Pengindeksan

ember 0

ember 1

ember meluap untuk ember 1

ember 2

ember 3

Gambar 14.25 Overflow chaining dalam struktur hash berbasis disk.

daftar, seperti pada Gambar 14.25. Dengan rangkaian overflow, diberikan kunci pencariank, algoritma
pencarian kemudian harus mencari tidak hanya ember H(k), tetapi juga ember luapan yang ditautkan dari ember
H(k).
Bucket overflow dapat terjadi jika bucket tidak mencukupi untuk jumlah record yang
diberikan. Jika jumlah record yang diindeks diketahui sebelumnya, jumlah bucket yang
diperlukan dapat dialokasikan; kita akan segera melihat bagaimana menangani situasi di
mana jumlah catatan menjadi jauh lebih banyak daripada yang awalnya diantisipasi. Bucket
overflow juga dapat terjadi jika beberapa bucket diberi lebih banyak record daripada yang
lain, yang mengakibatkan satu bucket meluap bahkan saat bucket lain masih memiliki
banyak ruang kosong.
Seperti condong dalam pendistribusian record dapat terjadi jika beberapa record mungkin memiliki
kunci pencarian yang sama. Tetapi bahkan jika hanya ada satu record per kunci pencarian, kemiringan
dapat terjadi jika fungsi hash yang dipilih menghasilkan distribusi kunci pencarian yang tidak seragam.
Peluang masalah ini dapat diminimalkan dengan memilih fungsi hash dengan hati-hati, untuk
memastikan distribusi kunci di seluruh ember seragam dan acak. Namun demikian, beberapa
kemiringan mungkin terjadi.
Agar peluang ember meluap berkurang, jumlah ember adalah
dipilih menjadi (nR/FR) (1 + D), di mana nR menunjukkan jumlah record, FR menunjukkan
jumlah record per bucket, D adalah faktor fudge, biasanya sekitar 0.2. Dengan fudge
faktor 0.2, sekitar 20 persen ruang di ember akan kosong. Tetapi manfaatnya
adalah kemungkinan overflow berkurang.
Meskipun alokasi beberapa ember lebih banyak dari yang dibutuhkan, overflow ember masih
bisa terjadi, terutama jika jumlah catatan meningkat melebihi apa yang awalnya diharapkan.
14.6 Akses Multi-Kunci 661

Pengindeksan hash seperti dijelaskan di atas, di mana jumlah ember ditetapkan saat indeks dibuat,
disebut hashing statis. Salah satu masalah dengan hashing statis adalah kita perlu mengetahui berapa
banyak catatan yang akan disimpan dalam indeks. Jika dari waktu ke waktu sejumlah besar catatan
ditambahkan, menghasilkan jauh lebih banyak catatan daripada ember, pencarian harus mencari
melalui sejumlah besar catatan yang disimpan dalam satu ember, atau dalam satu atau lebih ember
meluap, dan dengan demikian akan menjadi tidak efisien.
Untuk menangani masalah ini, indeks hash dapat dibangun kembali dengan jumlah bucket
yang lebih banyak. Misalnya, jika jumlah record menjadi dua kali jumlah bucket, indeks dapat
dibangun kembali dengan bucket dua kali lebih banyak dari sebelumnya. Namun, membangun
kembali indeks memiliki kelemahan yaitu dapat memakan waktu lama jika relasinya besar,
menyebabkan gangguan pada pemrosesan normal. Beberapa skema telah diusulkan yang
memungkinkan jumlah ember ditingkatkan dengan cara yang lebih bertahap. Skema seperti itu
disebuthashing dinamis teknik; NShashing linier teknik dan hashing yang dapat diperpanjang
teknik adalah dua skema tersebut; lihat Bagian 24.5 untuk rincian lebih lanjut dari teknik ini.

14.6 Akses Multi-Kunci

Sampai saat ini, kita mengasumsikan secara implisit bahwa hanya satu indeks pada satu atribut yang digunakan
untuk memproses kueri pada suatu relasi. Namun, untuk jenis kueri tertentu, sebaiknya menggunakan
beberapa indeks jika ada, atau menggunakan indeks yang dibangun di atas kunci pencarian multiatribut.

14.6.1 Menggunakan Beberapa Indeks Kunci Tunggal

Asumsikan bahwa pengajar file memiliki dua indeks: satu untuk nama departemen dan satu untuk gaji.
Pertimbangkan pertanyaan berikut: "Temukan semua instruktur di departemen Keuangan dengan gaji
sama dengan $80.000." Kami menulis

Pilih Indo
dari pengajar
di mana nama departemen = 'Keuangan' dan gaji = 80000;

Ada tiga strategi yang mungkin untuk memproses kueri ini:

1. Gunakan indeks pada nama departemen untuk menemukan semua catatan yang berkaitan dengan departemen
Keuangan. Periksa setiap catatan tersebut untuk melihat apakahgaji = 80000.

2. Gunakan indeks pada gaji untuk menemukan semua catatan yang berkaitan dengan instruktur dengan gaji
$80.000. Periksa setiap catatan tersebut untuk melihat apakah nama departemen adalah "Keuangan".
662 Bab 14 Pengindeksan

3. Gunakan indeks pada nama departemen mencari petunjuk untuk semua catatan yang berkaitan
dengan departemen Keuangan. Juga, gunakan indeks padagaji untuk menemukan petunjuk ke
semua catatan yang berkaitan dengan instruktur dengan gaji $80.000. Ambil persimpangan dari
dua set pointer ini. Petunjuk-petunjuk yang berada di titik persimpangan ke catatan yang
berkaitan dengan instruktur departemen Keuangan dan dengan gaji $80.000.

Strategi ketiga adalah satu-satunya dari tiga yang memanfaatkan keberadaan beberapa indeks.
Namun, bahkan strategi ini mungkin merupakan pilihan yang buruk jika semua hal berikut
berlaku:

• Ada banyak catatan yang berkaitan dengan departemen Keuangan.

• Ada banyak catatan yang berkaitan dengan instruktur dengan gaji $80.000.

• Hanya ada beberapa catatan yang berkaitan dengan keduanya departemen Keuangan dan
instruktur dengan gaji $80.000.

Jika kondisi ini berlaku, kita harus memindai sejumlah besar pointer untuk menghasilkan hasil yang kecil.
Struktur indeks yang disebut "indeks bitmap" dalam beberapa kasus dapat sangat mempercepat operasi
persimpangan yang digunakan dalam strategi ketiga. Indeks bitmap diuraikan dalam Bagian 14.9.

14.6.2 Indeks pada Beberapa Tombol

Strategi alternatif untuk kasus ini adalah membuat dan menggunakan indeks pada kunci
pencarian gabungan (nama departemen, gaji)—yaitu, kunci pencarian yang terdiri dari nama
departemen yang digabungkan dengan gaji instruktur.
Kita dapat menggunakan perintah (B+-tree) indeks pada kunci pencarian komposit sebelumnya untuk
menjawab pertanyaan formulir secara efisien

Pilih Indo
dari pengajar
di mana nama departemen = 'Keuangan' dan gaji = 80000;

Kueri seperti kueri berikut, yang menetapkan kondisi kesetaraan pada atribut pertama dari
kunci penelusuran (nama departemen) dan rentang pada atribut kedua dari kunci pencarian
(gaji), juga dapat ditangani secara efisien karena sesuai dengan kueri rentang pada atribut
penelusuran.

Pilih Indo
dari pengajar
di mana nama departemen = 'Keuangan' dan gaji < 80000;

Kami bahkan dapat menggunakan indeks terurut pada kunci pencarian (nama departemen, gaji) untuk
menjawab kueri berikut hanya pada satu atribut secara efisien:
14.6 Akses Multi-Kunci 663

Pilih Indo
dari pengajar
di mana nama departemen = 'Keuangan';

Kondisi kesetaraan nama departemen = “Keuangan” setara dengan kueri rentang pada rentang
dengan ujung bawah (Keuangan,) dan ujung atas (Keuangan, +). Rentangkan kueri hanya di nama
departemen atribut dapat ditangani dengan cara yang sama.
Penggunaan struktur indeks-terurut pada kunci pencarian komposit, bagaimanapun, memiliki
beberapa kekurangan. Sebagai ilustrasi, perhatikan pertanyaannya

Pilih Indo
dari pengajar
di mana nama departemen < 'Keuangan' dan gaji < 80000;

Kami dapat menjawab pertanyaan ini dengan menggunakan indeks berurutan pada kunci pencarian (nama departemen,

gaji): Untuk setiap nilai nama departemen yang kurang dari "Keuangan" dalam urutan
abjad, sistem menempatkan catatan dengan a gaji nilai 80000. Namun, setiap catatan
kemungkinan berada di blok disk yang berbeda, karena urutan catatan dalam file, yang
mengarah ke banyak operasi I/O.
Perbedaan antara kueri ini dan dua kueri sebelumnya adalah kondisi pada
atribut pertama (nama departemen) adalah kondisi perbandingan, bukan kondisi
kesetaraan. Kondisi tidak sesuai dengan kueri rentang pada kunci pencarian.
Untuk mempercepat pemrosesan kueri kunci pencarian komposit umum (yang dapat melibatkan
satu atau lebih operasi perbandingan), kita dapat menggunakan beberapa struktur khusus. Kami akan
mempertimbangkanindeks bitmap di Bagian 14.9. Ada struktur lain, yang disebutR-pohon, yang dapat
digunakan untuk tujuan ini. R-tree adalah perpanjangan dari B+-tree untuk menangani pengindeksan
pada beberapa dimensi dan dibahas dalam Bagian 14.10.1.

14.6.3 Indeks Penutup


Indeks penutup adalah indeks yang menyimpan nilai dari beberapa atribut (selain atribut kunci
pencarian) bersama dengan pointer ke record. Menyimpan nilai atribut tambahan berguna dengan
indeks sekunder, karena memungkinkan kita untuk menjawab beberapa pertanyaan hanya dengan
menggunakan indeks, bahkan tanpa mencari catatan yang sebenarnya.
Sebagai contoh, misalkan kita memiliki indeks nonclustering pada Indo atribut dari
pengajar hubungan. Jika kita menyimpan nilai darigaji atribut bersama dengan penunjuk record,
kita dapat menjawab pertanyaan yang membutuhkan gaji (tetapi bukan atribut lainnya, nama
departemen) tanpa mengakses pengajar catatan.
Efek yang sama dapat diperoleh dengan membuat indeks pada kunci pencarian (Indo,
gaji), tetapi indeks penutup mengurangi ukuran kunci pencarian, memungkinkan fanout yang
lebih besar di node nonleaf, dan berpotensi mengurangi tinggi indeks.
664 Bab 14 Pengindeksan

14.7 Pembuatan Indeks

Meskipun standar SQL tidak menentukan sintaks khusus untuk pembuatan indeks, sebagian besar
database mendukung perintah SQL untuk membuat dan menghapus indeks. Seperti yang kita lihat di
Bagian 4.6, indeks dapat dibuat menggunakan sintaks berikut, yang didukung oleh sebagian besar
database.

buat indeks <nama-indeks> pada <nama-hubungan> (<daftar-atribut>);

NS daftar-atribut adalah daftar atribut dari relasi yang membentuk kunci pencarian untuk indeks.
Indeks dapat dijatuhkan menggunakan perintah formulir

turunkan indeks <nama-indeks>;

Misalnya, untuk mendefinisikan indeks bernama indeks departemen di pengajar hubungan dengan
nama departemen sebagai kunci pencarian, kami menulis:

buat indeks indeks departemen pada pengajar (nama departemen);

Untuk mendeklarasikan bahwa suatu atribut atau daftar atribut adalah kunci kandidat, kita
dapat menggunakan sintaks buat indeks unik di tempat buat indeks di atas. Basis data yang
mendukung beberapa jenis indeks juga memungkinkan jenis indeks ditentukan sebagai bagian
dari perintah pembuatan indeks. Lihat manual sistem database Anda untuk mengetahui tipe
indeks apa yang tersedia, dan sintaks untuk menentukan tipe indeks.
Saat pengguna mengirimkan kueri SQL yang dapat memanfaatkan indeks, pemroses
kueri SQL secara otomatis menggunakan indeks.
Indeks bisa sangat berguna pada atribut yang berpartisipasi dalam kondisi pemilihan atau
bergabung dengan kondisi kueri, karena indeks dapat mengurangi biaya kueri secara signifikan.
Pertimbangkan kueri yang mengambilmengambil catatan untuk ID siswa tertentu 12345 (dinyatakan
dalam aljabar relasional sebagaiIndo=12345(mengambil)). Jika ada indeks pada atribut ID dari
mengambil, pointer ke catatan yang diperlukan dapat diperoleh hanya dengan beberapa operasi I/O
tion. Karena siswa biasanya hanya mengambil beberapa puluh mata kuliah, bahkan mengambil
catatan yang sebenarnya hanya membutuhkan beberapa puluh operasi I/O selanjutnya.
Sebaliknya, dengan tidak adanya indeks ini, sistem database akan dipaksa untuk membaca semua
mengambil record dan pilih yang memiliki nilai ID yang cocok. Membaca seluruh relasi bisa sangat
mahal jika ada banyak siswa.
Namun, indeks memiliki biaya, karena harus diperbarui setiap kali ada pembaruan pada relasi yang
mendasarinya. Membuat terlalu banyak indeks akan memperlambat pemrosesan pembaruan, karena
setiap pembaruan juga harus memperbarui semua indeks yang terpengaruh.
Terkadang masalah kinerja terlihat selama pengujian, misalnya, jika kueri membutuhkan waktu
puluhan detik, jelas bahwa itu cukup lambat. Namun, misalkan setiap kueri membutuhkan 1 detik untuk
memindai relasi besar tanpa indeks, dibandingkan 10 milidetik untuk mengambil rekaman yang sama
menggunakan indeks. Jika penguji menjalankan satu kueri pada satu waktu, kueri
14.8 Struktur Indeks yang Dioptimalkan untuk Tulis 665

merespons dengan cepat, bahkan tanpa indeks. Namun, misalkan kueri adalah bagian dari
sistem pendaftaran yang digunakan oleh seribu siswa dalam satu jam, dan tindakan setiap
siswa memerlukan 10 kueri tersebut untuk dieksekusi. Total waktu eksekusi akan menjadi
10.000 detik untuk kueri yang dikirimkan dalam 1 jam, yaitu, 3600 detik. Siswa kemudian
cenderung menemukan bahwa sistem pendaftaran sangat lambat, atau bahkan sama sekali
tidak responsif. Sebaliknya, jika indeks yang diperlukan ada, waktu eksekusi yang diperlukan
adalah 100 detik untuk pertanyaan yang diajukan dalam 1 jam, dan kinerja sistem
pendaftaran akan sangat baik.
Oleh karena itu, saat membangun aplikasi, penting untuk mengetahui indeks
mana yang penting untuk kinerja dan membuatnya sebelum aplikasi ditayangkan.
Jika suatu relasi dideklarasikan memiliki primary key, kebanyakan sistem database
secara otomatis membuat indeks pada primary key. Setiap kali sebuah tuple dimasukkan ke
dalam relasi, indeks dapat digunakan untuk memeriksa bahwa batasan kunci utama tidak
dilanggar (yaitu, tidak ada duplikat pada nilai kunci utama). Tanpa indeks pada kunci utama,
setiap kali sebuah tupel dimasukkan, seluruh relasi harus dipindai untuk memastikan bahwa
batasan kunci utama terpenuhi.
Meskipun sebagian besar sistem database tidak secara otomatis membuatnya, seringkali merupakan ide
yang baik untuk membuat indeks pada atribut kunci asing juga. Sebagian besar gabungan berada di antara
atribut kunci asing dan kunci utama, dan kueri yang berisi gabungan semacam itu, di mana ada juga kondisi
pemilihan pada tabel yang direferensikan, tidak jarang. Pertimbangkan
pertanyaan mengambil ⋈ σnama= Shankar(murid), di mana ID atribut kunci asing dari
mengambil referensi ID atribut primary-key siswa. Karena sangat sedikit siswa yang mungkin
bernama Shankar, indeks pada atribut kunci asing mengambil.ID dapat digunakan untuk mengambil
secara efisien mengambil tupel yang sesuai dengan siswa ini.
Banyak sistem basis data menyediakan alat yang membantu administrator basis data
melacak kueri dan pembaruan apa yang sedang dijalankan pada sistem dan merekomendasikan
pembuatan indeks tergantung pada frekuensi kueri dan pembaruan. Alat-alat tersebut disebut
sebagai wizard atau penasehat penyetelan indeks.
Beberapa sistem basis data berbasis cloud baru-baru ini juga mendukung pembuatan indeks yang
sepenuhnya otomatis setiap kali sistem menemukan bahwa hal itu akan menghindari pemindaian relasi
berulang, tanpa campur tangan administrator basis data.

14.8 Struktur Indeks yang Dioptimalkan untuk Tulis

Salah satu kelemahan B+-struktur indeks pohon adalah bahwa kinerjanya bisa sangat buruk dengan
penulisan acak. Pertimbangkan indeks yang terlalu besar untuk muat di memori; karena sebagian besar
ruang berada di tingkat daun, dan ukuran memori cukup besar akhir-akhir ini, kami berasumsi untuk
kesederhanaan bahwa tingkat indeks yang lebih tinggi sesuai dengan memori.
Sekarang anggaplah penulisan atau penyisipan dilakukan dalam urutan yang tidak sesuai dengan
urutan pengurutan indeks. Kemudian, setiap penulisan/penyisipan kemungkinan akan menyentuh
simpul daun yang berbeda; jika jumlah simpul daun secara signifikan lebih besar dari ukuran buffer,
sebagian besar akses daun ini akan memerlukan operasi baca acak, serta operasi tulis berikutnya
666 Bab 14 Pengindeksan

untuk menulis halaman daun yang diperbarui kembali ke disk. Pada sistem dengan disk magnetik,
dengan waktu akses 10 milidetik, indeks akan mendukung tidak lebih dari 100 penulisan/
penyisipan per detik per disk; dan ini adalah perkiraan optimis, dengan asumsi bahwa pencarian
membutuhkan sebagian besar waktu, dan kepala tidak berpindah antara membaca dan menulis
halaman daun. Pada sistem dengan SSD berbasis flash, I/O acak jauh lebih cepat, tetapi penulisan
halaman masih memiliki biaya yang signifikan karena (pada akhirnya) memerlukan penghapusan
halaman, yang merupakan operasi yang mahal. Jadi, dasar B+-struktur pohon tidak ideal untuk
aplikasi yang perlu mendukung sejumlah besar penulisan/penyisipan acak per detik.
Beberapa struktur indeks alternatif telah diusulkan untuk menangani beban kerja dengan
kecepatan tulis/masukkan yang tinggi. NSpohon gabungan berstruktur log atau pohon LSM dan
variannya adalah struktur indeks yang dioptimalkan untuk penulisan yang telah mengalami adopsi yang
sangat signifikan. Pohon penyangga adalah pendekatan alternatif, yang dapat digunakan dengan
berbagai struktur pohon pencarian. Kami menguraikan struktur ini di sisa bagian ini.

14.8.1 LSM Pohon


Sebuah pohon LSM terdiri dari beberapa B+-pohon, dimulai dengan pohon dalam memori, disebut L0,
dan pohon di disk L1, L2,…, Lk untuk beberapa k, di mana k disebut tingkat. Gambar 14.26
menggambarkan struktur pohon LSM untukk = 3.
Pencarian indeks dilakukan dengan menggunakan operasi pencarian terpisah pada masing-masing
pepohonan L0,…, Lk, dan menggabungkan hasil pencarian. (Kami berasumsi untuk saat ini bahwa hanya
ada sisipan, dan tidak ada pembaruan atau penghapusan; pencarian indeks dengan adanya
pembaruan/penghapusan lebih rumit dan dibahas nanti.)
Ketika sebuah catatan pertama kali dimasukkan ke dalam pohon LSM, catatan itu dimasukkan ke dalam memori
B+-struktur pohon L0. Jumlah ruang memori yang cukup besar dialokasikan untuk pohon ini. Pohon
tumbuh saat lebih banyak sisipan diproses, hingga memenuhi memori yang dialokasikan untuknya.
Pada titik ini, kita perlu memindahkan data dari struktur dalam memori ke B+-pohon pada disk.

L0 Penyimpanan

L1
Disk

L2

L3

Gambar 14.26 Pohon gabungan berstruktur log dengan tiga tingkat.


14.8 Struktur Indeks yang Dioptimalkan untuk Tulis 667

Jika pohon L1 kosong, seluruh pohon dalam memori L0 ditulis ke disk untuk membuat
pohon awal L1. Namun, jikaL1 tidak kosong, tingkat daun L0 dipindai dalam peningkatan
urutan kunci, dan entri digabungkan dengan entri level daun dari L1 (juga dipindai dalam urutan kunci
yang meningkat). Entri gabungan digunakan untuk membuat B baru+-pohon, menggunakan
proses pembangunan dari bawah ke atas. Pohon baru dengan entri yang digabungkan kemudian menggantikan yang lama

L1. Dalam kedua kasus, setelah entri dariL0 telah dipindahkan ke L1, semua entri di L0 demikian juga
seperti yang lama L1, jika ada, akan dihapus. Sisipan kemudian dapat dibuat ke yang sekarang kosongL0
dalam kenangan.

Perhatikan bahwa semua entri di tingkat daun yang lama L1 pohon, termasuk yang ada di simpul
daun yang tidak memiliki pembaruan, disalin ke pohon baru alih-alih melakukan pembaruan
pada yang ada L1 simpul pohon. Hal ini memberikan manfaat sebagai berikut.

1. Daun pohon baru ditempatkan secara berurutan, menghindari I/O acak selama
penggabungan berikutnya.

2. Daunnya penuh, menghindari overhead daun yang terisi sebagian yang dapat terjadi dengan
pemisahan halaman.

Namun, ada biaya untuk menggunakan struktur LSM seperti yang dijelaskan di atas: keseluruhan
isi pohon disalin setiap kali satu set entri dari L0 disalin ke L1. Salah satu dari dua
teknik digunakan untuk mengurangi biaya ini:

1. Beberapa level digunakan, dengan level LSaya+1 pohon yang memiliki ukuran maksimum yaitu k
kali ukuran maksimum level LSaya pohon. Jadi, setiap catatan ditulis paling banyakk
kali pada tingkat tertentu. Jumlah level proporsionalcatatank(Saya/M) di mana
Saya adalah jumlah entri danM adalah jumlah entri yang sesuai dalam memori
pohon L0.

2. Setiap tingkat (selain L0) dapat memiliki hingga beberapa nomor B pohon, bukan hanya 1 pohon.
Ketika sebuahL0 pohon ditulis ke disk, baru L1 pohon dibuat alih-alih menggabungkannya dengan
yang sudah ada L1 pohon. Ketika adaB seperti L1 pohon, mereka digabung menjadi satu yang
baru L2 pohon. Demikian pula ketika adaB pohon di tingkat LSaya mereka
digabungkan menjadi yang baru LSaya+1 pohon.

Varian dari pohon LSM ini disebut indeks penggabungan bertahap. yang melangkah-
indeks gabungan mengurangi biaya penyisipan secara signifikan dibandingkan dengan hanya
memiliki satu pohon per level, tetapi dapat mengakibatkan peningkatan biaya kueri, karena
beberapa pohon mungkin perlu dicari. Struktur berbasis bitmap disebutFilter mekar, yang
dijelaskan di Bagian 24.1, digunakan untuk mengurangi jumlah pencarian dengan mendeteksi
secara efisien bahwa kunci pencarian tidak ada di pohon tertentu. Filter Bloom menempati ruang
yang sangat sedikit, tetapi cukup efektif dalam mengurangi biaya kueri.

Detail dari semua varian pohon LSM ini dapat ditemukan di Bagian 24.2.
Sejauh ini kami hanya menjelaskan sisipan dan pencarian. Penghapusan ditangani dengan
cara yang menarik. Alih-alih langsung menemukan entri indeks dan menghapusnya, hapus
668 Bab 14 Pengindeksan

menghasilkan penyisipan yang baru entri penghapusan yang menunjukkan entri indeks mana
yang akan dihapus. Proses memasukkan entri penghapusan identik dengan proses memasukkan
entri indeks normal.
Namun, pencarian harus melakukan langkah ekstra. Seperti disebutkan sebelumnya, pencarian
mengambil entri dari semua pohon dan menggabungkannya dalam urutan nilai kunci yang diurutkan.
Jika ada entri penghapusan untuk beberapa entri, keduanya akan memiliki nilai kunci yang sama.
Dengan demikian, pencarian akan menemukan entri penghapusan dan entri asli untuk kunci itu, yang
akan dihapus. Jika entri penghapusan ditemukan, entri yang akan dihapus disaring dan tidak
dikembalikan sebagai bagian dari hasil pencarian.
Ketika pohon digabungkan, jika salah satu pohon berisi entri, dan yang lain memiliki entri
penghapusan yang cocok, entri akan dicocokkan selama penggabungan (keduanya akan memiliki
kunci yang sama), dan keduanya dibuang.
Pembaruan ditangani dengan cara yang mirip dengan penghapusan, dengan memasukkan entri
pembaruan. Pencarian harus mencocokkan entri pembaruan dengan entri asli dan mengembalikan nilai
terbaru. Pembaruan sebenarnya diterapkan selama penggabungan, ketika satu pohon memiliki entri dan yang
lain memiliki entri pembaruan yang cocok; proses penggabungan akan menemukan catatan dan catatan
pembaruan dengan kunci yang sama, menerapkan pembaruan, dan membuang entri pembaruan.
Pohon LSM pada awalnya dirancang untuk mengurangi biaya menulis dan mencari disk
magnetik. SSD berbasis flash memiliki overhead yang relatif rendah untuk operasi I/O acak karena
tidak memerlukan pencarian, dan dengan demikian manfaat menghindari I/O acak yang
disediakan oleh varian pohon LSM tidak terlalu penting dengan SSD.
Namun, ingatlah bahwa memori flash tidak mengizinkan pembaruan di tempat, dan menulis
bahkan satu byte ke halaman memerlukan seluruh halaman untuk ditulis ulang ke lokasi fisik
baru; lokasi asli halaman pada akhirnya perlu dihapus, yang merupakan operasi yang relatif
mahal. Pengurangan jumlah penulisan menggunakan varian pohon LSM, dibandingkan dengan
B . tradisional+-trees, dapat memberikan manfaat kinerja yang substansial ketika pohon LSM
digunakan dengan SSD.
Varian dari pohon LSM yang mirip dengan indeks penggabungan bertahap, dengan beberapa
pohon di setiap lapisan, digunakan dalam sistem BigTable Google, serta di Apache HBase, klon open
source BigTable. Sistem ini dibangun di atas sistem file terdistribusi yang memungkinkan penambahan
file tetapi tidak mendukung pembaruan data yang ada. Fakta bahwa pohon LSM tidak melakukan
pembaruan di tempat membuat pohon LSM sangat cocok untuk sistem ini.
Selanjutnya, sejumlah besar sistem penyimpanan BigData seperti Apache Cassandra, Apache
AsterixDB, dan MongoDB menambahkan dukungan untuk pohon LSM, dengan sebagian besar
versi implementasi dengan beberapa pohon di setiap lapisan. Pohon LSM juga didukung di MySQL
(menggunakan mesin penyimpanan MyRocks) dan dalam sistem basis data tertanam SQLite4 dan
LevelDB.

14.8.2 Pohon Penyangga

Pohon penyangga adalah alternatif dari pendekatan pohon gabungan berstruktur log. Ide utama di balik
pohon penyangga adalah untuk mengasosiasikan buffer dengan setiap node internal dari B+-pohon,
14.8 Struktur Indeks yang Dioptimalkan untuk Tulis 669

simpul internal

pkpkp
1 1 2 2 3 kp3 4 kp4 5 kp5 6 Penyangga

Gambar 14.27 Struktur simpul internal dari pohon penyangga.

termasuk simpul akar; ini digambarkan dalam Gambar 14.27. Kami pertama-tama menguraikan bagaimana
penyisipan dan pencarian ditangani, dan selanjutnya kami menguraikan bagaimana penghapusan dan
pembaruan ditangani.
Ketika catatan indeks dimasukkan ke dalam pohon penyangga, alih-alih melintasi pohon ke
daun, catatan indeks dimasukkan ke dalam penyangga akar. Jika buffer menjadi penuh, setiap
record indeks dalam buffer didorong satu tingkat ke bawah pohon ke node anak yang sesuai. Jika
simpul anak adalah simpul internal, catatan indeks ditambahkan ke buffer simpul anak; jika buffer
itu penuh, semua record di buffer itu juga didorong ke bawah. Semua catatan dalam buffer
diurutkan pada kunci pencarian sebelum didorong ke bawah. Jika simpul anak adalah simpul
daun, catatan indeks dimasukkan ke dalam daun dengan cara biasa. Jika penyisipan menghasilkan
simpul daun yang terlalu penuh, simpul tersebut dibagi menjadi B . biasa+-tree dengan cara split
berpotensi menyebar ke node induk. Pemisahan simpul internal yang terlalu penuh dilakukan
dengan cara biasa, dengan langkah tambahan juga pemisahan buffer; entri buffer dipartisi di
antara dua node terpisah berdasarkan nilai kuncinya.
Pencarian dilakukan dengan melintasi B+-struktur pohon dengan cara biasa, untuk menemukan daun
yang berisi catatan yang cocok dengan kunci pencarian. Tetapi ada satu langkah tambahan: pada setiap
simpul internal yang dilalui oleh pencarian, buffer node harus diperiksa untuk melihat apakah ada
catatan yang cocok dengan kunci pencarian. Pencarian rentang dilakukan seperti pada B . normal+-
pohon, tetapi mereka juga harus memeriksa buffer semua node internal di atas node daun mana pun
yang diakses.
Misalkan buffer pada simpul internal memegang k kali lebih banyak catatan karena ada node
anak. Kemudian, rata-rata,k catatan akan didorong ke bawah pada satu waktu untuk setiap anak
(terlepas dari apakah anak itu adalah simpul internal atau simpul daun). Penyortiran catatan
sebelum didorong memastikan bahwa semua catatan ini didorong ke bawah secara berurutan.
Manfaat dari pendekatan pohon penyangga untuk sisipan adalah bahwa biaya mengakses simpul
anak dari penyimpanan, dan menulis kembali simpul yang diperbarui, diamortisasi (dibagi), rata-
rata, antarak catatan. Dengan cukup besark, penghematannya bisa sangat signifikan
dibandingkan dengan sisipan dalam B . biasa+-pohon.
Penghapusan dan pembaruan dapat diproses dengan cara yang mirip dengan pohon LSM, menggunakan
entri penghapusan atau entri pembaruan. Atau, penghapusan dan pembaruan dapat diproses menggunakan B .
normal+algoritma -tree, dengan risiko biaya I/O yang lebih tinggi per penghapusan/pembaruan dibandingkan
dengan biaya saat menggunakan entri penghapusan/pembaruan.
Pohon penyangga memberikan batas kompleksitas kasus terburuk yang lebih baik pada jumlah
operasi I/O daripada varian pohon LSM. Dalam hal biaya baca, pohon penyangga secara signifikan lebih
cepat daripada pohon LSM. Namun, operasi tulis pada pohon penyangga melibatkan I/O acak,
670 Bab 14 Pengindeksan

membutuhkan lebih banyak pencarian, berbeda dengan operasi I/O sekuensial dengan varian pohon LSM. Untuk
penyimpanan disk magnetik, biaya pencarian yang tinggi menghasilkan pohon penyangga berkinerja lebih buruk
daripada pohon LSM pada beban kerja intensif penulisan. Dengan demikian, pohon LSM telah menemukan penerimaan
yang lebih besar untuk beban kerja intensif penulisan dengan data yang disimpan pada disk magnetik. Namun, karena I/
Ooperasi acak sangat efisien pada SSD, dan pohon penyangga cenderung melakukan lebih sedikit operasi tulis secara
keseluruhan dibandingkan dengan pohon LSM, pohon penyangga dapat memberikan kinerja tulis yang lebih baik pada
SSD. Beberapa struktur indeks yang dirancang untuk penyimpanan flash menggunakan konsep buffer yang
diperkenalkan oleh pohon buffer.
Manfaat lain dari pohon penyangga adalah bahwa ide kunci untuk mengasosiasikan penyangga
dengan simpul internal, untuk mengurangi jumlah penulisan, dapat digunakan dengan semua jenis
indeks terstruktur pohon. Misalnya, buffering telah digunakan sebagai cara untuk mendukung
pemuatan massal indeks spasial seperti R-tree (yang kita pelajari di Bagian 14.10.1), serta jenis indeks
lainnya, yang pengurutan dan konstruksi bottom-upnya tak dapat diterapkan.
Pohon penyangga telah diimplementasikan sebagai bagian dari Pohon Pencarian Umum (Inti)
struktur indeks di PostgreSQL. Indeks GiST memungkinkan kode yang ditentukan pengguna dieksekusi untuk
mengimplementasikan operasi pencarian, pembaruan, dan pemisahan pada node dan telah digunakan untuk
mengimplementasikan R-tree dan struktur indeks spasial lainnya.

14.9 Indeks Bitmap

Indeks bitmap adalah jenis indeks khusus yang dirancang untuk memudahkan kueri pada beberapa
kunci, meskipun setiap indeks bitmap dibangun di atas satu kunci. Kami menjelaskan fitur utama dari
indeks bitmap di bagian ini tetapi memberikan rincian lebih lanjut di Bagian 24.3.
Untuk indeks bitmap yang akan digunakan, catatan dalam suatu relasi harus diberi nomor secara
berurutan, mulai dari, katakanlah, 0. Diberikan nomor n, itu harus mudah untuk mengambil catatan bernomor
n. Ini sangat mudah untuk dicapai jika catatan berukuran tetap dan dialokasikan pada blok file
yang berurutan. Nomor catatan kemudian dapat diterjemahkan dengan mudah ke dalam nomor
blok dan nomor yang mengidentifikasi catatan di dalam blok.
Pertimbangkan relasi dengan atribut yang hanya dapat mengambil satu dari sejumlah kecil
nilai (misalnya, 2 hingga 20). Misalnya, pertimbangkan sebuah relasiinfo instruktur, yang memiliki
(selain atribut ID) sebuah atribut jenis kelamin, yang hanya dapat mengambil nilai M (laki-laki)
atau F (Perempuan). Misalkan relasi juga memiliki atributtingkat pendapatan, yang menyimpan
tingkat pendapatan, di mana pendapatan telah dipecah menjadi lima tingkat: L1: 0–999, L2: 10.000
– 19, 999, L3: 20,000–39, 999, L4: 40,000–74, 999, dan L5: 75, 000 . Di sini, data mentah dapat
mengambil banyak nilai, tetapi seorang analis data telah membagi nilai menjadi sejumlah
kecil rentang untuk menyederhanakan analisis data. Contoh dari relasi ini ditunjukkan di sisi
kiri Gambar 14.28.
A peta bit hanyalah sebuah array bit. Dalam bentuknya yang paling sederhana, aindeks
bitmap pada atribut A hubungan R terdiri dari satu bitmap untuk setiap nilai yang A dapat
mengambil. Setiap bitmap memiliki bit sebanyak jumlah record dalam relasi. NSSayasedikit dari
bitmap untuk nilai vJ diatur ke 1 jika catatan bernomor Saya memiliki nilai vJ untuk atribut A.
Semua bit bitmap lainnya diatur ke 0.
14.9 Indeks Bitmap 671

Bitmap untuk jenis kelamin Bitmap untuk


pendapatan_tingkat
catatan
Indo M 10010
nomor jenis kelamin pendapatan_tingkat

L1 10100
0 76766 M L1 F 01101

1 22222 F L2 L2 01000

2 12121 F L1 L3 00001

3 15151 M L4 L4 00010
4 58583 F L3
L5 00000

Gambar 14.28 Indeks bitmap pada relasi info instruktur.

Dalam contoh kita, ada satu bitmap untuk nilainya M dan satu untuk F. NS Sayasedikit bitmap untuk
M diatur ke 1 jika jenis kelamin nilai catatan bernomor Saya adalah M. Semua bit lain dari bitmap untuk
M diatur ke 0. Demikian pula, bitmap untuk F memiliki nilai 1 untuk bit yang sesuai dengan catatan
dengan nilai F Untuk jenis kelamin atribut; semua bit lainnya memiliki nilai 0. Gambar 14.28
menunjukkan indeks bitmap padajenis kelamin dan tingkat pendapatan atribut dari info instruktur relasi,
untuk instance relasi yang ditunjukkan pada gambar yang sama.
Kami sekarang mempertimbangkan kapan bitmap berguna. Cara paling sederhana untuk
mengambil semua catatan dengan nilaiM (atau nilai F) adalah dengan hanya membaca semua catatan
relasi dan memilih catatan tersebut dengan nilai M (atau F, masing-masing). Indeks bitmap tidak terlalu
membantu untuk mempercepat pemilihan seperti itu. Meskipun memungkinkan kita untuk membaca
hanya catatan tersebut untuk jenis kelamin tertentu, kemungkinan setiap blok disk untuk file tersebut
harus tetap dibaca.
Faktanya, indeks bitmap berguna untuk pilihan terutama ketika ada pilihan pada
banyak kunci. Misalkan kita membuat indeks bitmap pada atributtingkat pendapatan, yang
kami jelaskan sebelumnya, selain indeks bitmap pada jenis kelamin.
Pertimbangkan sekarang kueri yang memilih wanita dengan pendapatan di kisaran 10.000 hingga
19.999. Permintaan ini dapat dinyatakan sebagai

Pilih *
dari info instruktur
di mana jenis kelamin = 'F' dan tingkat pendapatan = 'L2';

Untuk mengevaluasi pilihan ini, kami mengambil bitmap untuk jenis kelamin nilai F dan bitmap untuk
tingkat pendapatan nilai L2, dan melakukan persimpangan (logis-dan) dari dua bitmap. Dengan
kata lain, kami menghitung bitmap baru di mana bitSaya bernilai 1 jika Sayabit kedua dari dua
bitmap keduanya 1, dan memiliki nilai 0 sebaliknya. Pada contoh pada Gambar 14.28,
perpotongan bitmap untukjenis kelamin = (01101) dan bitmap untuk tingkat pendapatan = L2
(01000) memberikan bitmap 01000.
672 Bab 14 Pengindeksan

Karena atribut pertama dapat mengambil dua nilai, dan atribut kedua dapat mengambil lima
nilai, kami mengharapkan rata-rata hanya sekitar 1 dari 10 catatan untuk memenuhi kondisi
gabungan pada dua atribut. Jika ada kondisi lebih lanjut, fraksi catatan yang memenuhi semua
kondisi kemungkinan akan cukup kecil. Sistem kemudian dapat menghitung hasil kueri dengan
menemukan semua bit dengan nilai 1 di bitmap persimpangan dan mengambil catatan yang
sesuai. Jika fraksinya besar, memindai seluruh relasi akan tetap menjadi alternatif yang lebih
murah.
Cakupan indeks bitmap yang lebih detail, termasuk cara mengimplementasikan operasi
agregat secara efisien, cara mempercepat operasi bitmap, dan indeks hibrid yang
menggabungkan B+-pohon dengan bitmap, dapat ditemukan di Bagian 24.3.

14.10 Pengindeksan Data Spasial dan Temporal

Struktur indeks tradisional, seperti indeks hash dan B+-pohon, tidak cocok untuk
pengindeksan data spasial, yang biasanya dari dua atau lebih dimensi. Demikian pula, ketika
tupel memiliki interval temporal yang terkait dengannya, dan kueri dapat menentukan titik
waktu atau interval waktu, struktur indeks tradisional dapat menghasilkan kinerja yang
buruk.

14.10.1 Pengindeksan Data Spasial

Pada bagian ini kami memberikan gambaran umum tentang teknik pengindeksan data spasial. Rincian
lebih lanjut dapat ditemukan di Bagian 24.4. Data spasial mengacu pada data yang mengacu pada suatu
titik atau wilayah dalam ruang dua dimensi atau lebih tinggi. Misalnya, lokasi restoran, yang
diidentifikasi dengan pasangan (lintang, bujur), adalah bentuk data spasial. Demikian pula, luas spasial
sebuah peternakan atau danau dapat diidentifikasi dengan poligon, dengan setiap sudut diidentifikasi
oleh pasangan (lintang, bujur).
Ada banyak bentuk query pada data spasial, yang perlu didukung secara efisien
menggunakan indeks. Kueri yang meminta restoran pada pasangan yang ditentukan secara tepat
(lintang, bujur) dapat dijawab dengan membuat B+-pohon pada atribut komposit (lintang, bujur).
Namun, seperti B+-tree index tidak dapat secara efisien menjawab kueri yang menanyakan semua
restoran yang berada dalam radius 500 meter dari lokasi pengguna, yang diidentifikasi oleh
pasangan (lintang, bujur). Indeks semacam itu juga tidak dapat secara efisien menjawab kueri
yang menanyakan semua restoran yang berada dalam wilayah minat persegi panjang. Keduanya
merupakan bentuk darijangkauan kueri, yang mengambil objek dalam area tertentu. Indeks
semacam itu juga tidak dapat menjawab pertanyaan yang menanyakan restoran terdekat ke
lokasi tertentu secara efisien; kueri seperti itu adalah contoh daritetangga terdekat pertanyaan.
Tujuan dari pengindeksan spasial adalah untuk mendukung berbagai bentuk kueri spasial, dengan
kueri jangkauan dan tetangga terdekat menjadi perhatian khusus, karena mereka banyak digunakan.

Untuk memahami bagaimana mengindeks data spasial yang terdiri dari dua atau lebih dimensi, pertama-tama kita
pertimbangkan pengindeksan titik-titik dalam data satu dimensi. Struktur pohon, seperti pohon biner dan B+-pohon,
beroperasi dengan membagi ruang secara berurutan menjadi bagian-bagian yang lebih kecil. Untuk
14.10 Pengindeksan Data Spasial dan Temporal 673

3 3

3 1 3

Gambar 14.29 Pembagian ruang oleh pohon kd.

Misalnya, setiap simpul internal dari pohon biner mempartisi interval satu dimensi menjadi dua.
Titik yang terletak di partisi kiri masuk ke subpohon kiri; titik yang terletak di partisi kanan masuk
ke subtree kanan. Dalam pohon biner seimbang, partisi dipilih sehingga kira-kira setengah dari
titik yang disimpan dalam subpohon jatuh di setiap partisi. Demikian pula, setiap tingkat B+-tree
membagi interval satu dimensi menjadi beberapa bagian. Kita dapat menggunakan intuisi itu
untuk membuat struktur pohon untuk ruang dua dimensi serta ruang dimensi yang lebih
tinggi. Struktur pohon yang disebut apohon kd adalah salah satu struktur awal yang digunakan
untuk pengindeksan dalam berbagai dimensi. Setiap tingkat pohon kd mempartisi ruang menjadi
dua. Partisi dilakukan sepanjang satu dimensi pada simpul di tingkat atas pohon, di sepanjang
dimensi lain di simpul di tingkat berikutnya, dan seterusnya, bersepeda melalui dimensi. Partisi
berlangsung sedemikian rupa sehingga, pada setiap simpul, kira-kira setengah dari titik yang
disimpan dalam subpohon jatuh di satu sisi dan setengah jatuh di sisi lain. Partisi berhenti ketika
sebuah node memiliki kurang dari jumlah poin maksimum yang diberikan.

Gambar 14.29 menunjukkan himpunan titik dalam ruang dua dimensi, dan
representasi pohon kd dari himpunan titik, di mana jumlah maksimum titik dalam
simpul daun ditetapkan pada 1. Setiap garis pada gambar (selain garis luar box) sesuai
dengan simpul di pohon kd. Penomoran garis pada gambar menunjukkan tingkat
pohon di mana simpul yang sesuai muncul.
Kueri rentang persegi panjang, yang meminta titik dalam wilayah persegi panjang tertentu,
dapat dijawab secara efisien menggunakan pohon kd sebagai berikut: Kueri semacam itu pada
dasarnya menentukan interval pada setiap dimensi. Misalnya, kueri rentang mungkin meminta
semua titik yangx dimensi terletak antara 50 dan 80, dan kamu dimensi terletak antara 40 dan 70.
Ingatlah bahwa setiap simpul internal membagi ruang pada satu dimensi, dan seperti pada B+-
674 Bab 14 Pengindeksan

pohon. Pencarian rentang dapat dilakukan dengan prosedur rekursif berikut, mulai
dari root:

1. Misalkan simpul tersebut adalah simpul internal, dan biarkan dipecah pada dimensi tertentu,
mengatakan x, pada satu titik xSaya. Entri di subpohon kiri memilikix nilai-nilai < xSaya, dan yang ada di
subpohon kanan memiliki x nilai-nilai ≥ xSaya. Jika rentang kueri berisixSaya, pencarian berulang-
dilakukan secara aktif pada kedua anak. Jika rentang kueri ada di sebelah kirixSaya, pencarian
dilakukan secara rekursif hanya pada anak kiri, dan jika tidak, pencarian hanya dilakukan
pada subpohon kanan.

2. Jika node adalah daun, semua entri yang terdapat dalam rentang kueri akan diambil.

Pencarian tetangga terdekat lebih rumit, dan kami tidak akan menjelaskannya di sini, tetapi pertanyaan
tetangga terdekat juga dapat dijawab dengan cukup efisien menggunakan pohon kd.
NS pohon kdB memperluas pohon kd untuk memungkinkan beberapa simpul anak untuk setiap simpul
internal, seperti halnya pohon-B memperluas pohon biner, untuk mengurangi ketinggian pohon. Pohon kdB
lebih cocok untuk penyimpanan sekunder daripada pohon kd. Pencarian jangkauan seperti diuraikan di atas
dapat dengan mudah diperluas ke pohon kdB, dan pertanyaan tetangga terdekat juga dapat dijawab dengan
cukup efisien menggunakan pohon kdB.
Ada sejumlah struktur indeks alternatif untuk data spasial. Alih-alih membagi data
satu dimensi pada satu waktu,pohon empat membagi ruang dua dimensi menjadi
empat kuadran pada setiap simpul pohon. Rincian dapat ditemukan di Bagian 24.4.1.
Pengindeksan wilayah ruang, seperti segmen garis, persegi panjang, dan poligon
lainnya, menghadirkan masalah baru. Ada ekstensi pohon kd dan pohon empat untuk tugas
ini. Ide kuncinya adalah bahwa jika segmen garis atau poligon melintasi garis partisi, itu
dibagi sepanjang garis partisi dan diwakili di setiap subpohon di mana potongannya terjadi.
Beberapa kemunculan segmen garis atau poligon dapat mengakibatkan inefisiensi dalam
penyimpanan, serta inefisiensi dalam kueri.
Struktur penyimpanan yang disebut an R-pohon berguna untuk mengindeks objek yang
mencakup wilayah ruang, seperti segmen garis, persegi panjang, dan poligon lainnya, selain titik.
R-tree adalah struktur pohon yang seimbang dengan objek yang diindeks disimpan dalam node
daun, seperti B+-pohon. Namun, alih-alih rentang nilai, persegi panjangkotak pembatas dikaitkan
dengan setiap simpul pohon. Kotak pembatas dari simpul daun adalah persegi panjang terkecil
yang sejajar dengan sumbu yang berisi semua objek yang disimpan dalam simpul daun. Kotak
pembatas simpul internal, demikian pula, persegi panjang terkecil yang sejajar dengan sumbu
yang berisi kotak pembatas simpul turunannya. Kotak pembatas suatu objek (seperti poligon)
didefinisikan, dengan cara yang sama, sebagai persegi panjang terkecil yang sejajar dengan
sumbu yang berisi objek tersebut.
Setiap node internal menyimpan kotak pembatas dari node anak bersama dengan
pointer ke node anak. Setiap simpul daun menyimpan objek yang diindeks.
Gambar 14.30 menunjukkan contoh satu set persegi panjang (digambar dengan garis padat) dan
kotak pembatas (digambar dengan garis putus-putus) dari node R-tree untuk himpunan persegi
panjang. Perhatikan bahwa kotak pembatas ditampilkan dengan ruang ekstra di dalamnya, untuk
membuatnya menonjol secara gambar. Pada kenyataannya, kotak-kotak itu akan lebih kecil dan pas
14.10 Pengindeksan Data Spasial dan Temporal 675

A B

1
C
BB1 BB2 BB3
G

3
H ABC DEF GHI
D Saya
2
E
F

Gambar 14.30 Sebuah R-pohon.

pada objek yang dikandungnya; yaitu, setiap sisi kotak pembatasB akan menyentuh
setidaknya salah satu objek atau kotak pembatas yang terdapat di B.
R-tree itu sendiri ada di sebelah kanan Gambar 14.30. Angka tersebut mengacu pada koordinasi
dinate dari kotak pembatas Saya sebagai BBSaya dalam gambar. Detail lebih lanjut tentang R-tree, termasuk detail
tentang bagaimana menjawab pertanyaan jangkauan menggunakan R-tree, dapat ditemukan di Bagian 24.4.2.
Tidak seperti beberapa struktur alternatif untuk menyimpan poligon dan segmen garis, seperti R*
-pohon dan pohon interval, R-pohon menyimpan hanya satu salinan dari setiap objek, dan kami dapat
memastikan dengan mudah bahwa setiap node setidaknya setengah penuh. Namun, kueri mungkin
lebih lambat dibandingkan dengan beberapa alternatif, karena banyak jalur harus dicari. Namun, karena
efisiensi penyimpanannya yang lebih baik dan kemiripannya dengan B-tree, R-tree dan variannya
terbukti populer dalam sistem database yang mendukung data spasial.

14.10.2 Mengindeks Data Temporal

Data temporal mengacu pada data yang memiliki periode waktu terkait, seperti yang dibahas dalam Bagian
7.10. Periode waktu yang terkait dengan tupel menunjukkan periode waktu yang tupel valid.
Misalnya, pengenal kursus tertentu mungkin judulnya berubah di beberapa titik waktu. Dengan
demikian, pengidentifikasi kursus dikaitkan dengan judul untuk interval waktu tertentu, setelah itu
pengidentifikasi kursus yang sama dikaitkan dengan judul yang berbeda. Ini dapat dimodelkan
dengan memiliki dua atau lebih tupel dikursus hubungannya sama ID kursus, tapi berbeda judul
nilai, masing-masing dengan interval waktu validnya sendiri.
A jarak waktu memiliki waktu mulai dan waktu berakhir. Selanjutnya interval waktu
menunjukkan apakah interval dimulai pada waktu mulai, atau tepat setelah waktu mulai, yaitu
apakah intervalnyatertutup atau membuka pada waktu mulai. Demikian pula, interval waktu
menunjukkan apakah itu tertutup atau terbuka pada akhir waktu. Untuk menyatakan fakta bahwa
tupel valid saat ini, sampai diperbarui berikutnya, waktu akhir secara konseptual diatur ke tak
terhingga (yang dapat diwakili oleh waktu besar yang sesuai, seperti tengah malam 9999-12-31).
676 Bab 14 Pengindeksan

Secara umum, masa berlaku untuk suatu fakta tertentu tidak boleh hanya terdiri dari satu interval
waktu; misalnya, seorang mahasiswa dapat terdaftar di universitas pada satu tahun akademik,
mengambil cuti untuk tahun berikutnya, dan mendaftar lagi pada tahun berikutnya. Masa berlaku
pendaftaran mahasiswa di universitas tersebut jelas bukan interval waktu tunggal. Namun, setiap
periode yang valid dapat diwakili oleh beberapa interval; dengan demikian, sebuah tupel dengan periode
valid apa pun dapat diwakili oleh beberapa tupel, yang masing-masing memiliki periode valid yang
merupakan interval waktu tunggal. Oleh karena itu, kami hanya akan mempertimbangkan interval waktu
ketika memodelkan data temporal.
Misalkan kita ingin mengambil nilai dari sebuah tuple, diberikan sebuah nilai v untuk sebuah atribut A,
dan satu titik waktu T1. Kita dapat membuat indeks padaA, dan menggunakannya untuk mengambil semua
tupel dengan nilai v untuk atribut A. Sementara indeks semacam itu mungkin memadai jika jumlah waktunya
interval untuk nilai kunci pencarian itu kecil, secara umum indeks dapat mengambil angka
dari tupel yang interval waktunya tidak termasuk titik waktu T1.
Solusi yang lebih baik adalah dengan menggunakan indeks spasial seperti R-tree, dengan tuple yang diindeks
diperlakukan sebagai memiliki dua dimensi, satu menjadi atribut yang diindeks A, dan yang lainnya
adalah dimensi waktu. Dalam hal ini, tupel membentuk segmen garis, dengan nilaiv untuk dimensi A,
dan interval waktu yang valid dari tupel sebagai interval dalam dimensi waktu. Salah satu masalah yang
memperumit penggunaan indeks spasial seperti R-tree adalah bahwa interval waktu akhir mungkin
tak terhingga (mungkin diwakili oleh nilai yang sangat besar), sedangkan indeks spasial biasanya
mengasumsikan bahwa kotak pembatas terbatas, dan mungkin buruk. kinerja jika kotak pembatas
sangat besar. Masalah ini dapat diatasi sebagai berikut:

• Semua tupel saat ini (yaitu, mereka dengan waktu akhir sebagai tak terhingga, yang mungkin
diwakili oleh nilai waktu yang besar) disimpan dalam indeks terpisah dari tupel yang memiliki
waktu akhir non-tak terbatas. Indeks pada tupel saat ini bisa menjadi B+-indeks pohon aktif (A,
waktu mulai), di mana A adalah atribut yang diindeks dan waktu mulai adalah waktu mulai,
sedangkan indeks untuk tupel non-saat ini akan menjadi indeks spasial seperti R-tree.

• Mencari nilai kunci v pada satu titik waktu TSaya perlu mencari di kedua indeks;
pencarian pada indeks Tuple saat ini adalah untuk tupel denganA = v, dan mulai ts
≤ TSaya, yang dapat dilakukan dengan kueri rentang sederhana. Kueri dengan rentang waktu dapat ditangani
dengan cara yang sama.

Alih-alih menggunakan indeks spasial yang dirancang untuk data multidimensi, seseorang dapat
menggunakan indeks khusus, seperti interval B+-tree, yang dirancang untuk mengindeks interval dalam
satu dimensi, dan memberikan jaminan kompleksitas yang lebih baik daripada indeks R-tree. Namun,
sebagian besar implementasi basis data merasa lebih mudah menggunakan indeks R-tree daripada
mengimplementasikan jenis indeks lain untuk interval waktu.
Ingat bahwa dengan data temporal, lebih dari satu tupel mungkin memiliki nilai yang sama
untuk kunci utama, selama tupel dengan nilai kunci utama yang sama memiliki interval waktu
yang tidak tumpang tindih. Indeks temporal pada atribut kunci utama dapat digunakan untuk
secara efisien menentukan apakah batasan kunci utama temporal dilanggar ketika tupel baru
dimasukkan atau interval waktu yang valid dari tupel yang ada diperbarui.
14.11 Ringkasan 677

14.11 Ringkasan

• Banyak kueri merujuk hanya sebagian kecil dari catatan dalam file. Untuk mengurangi
overhead dalam mencari catatan ini, kita dapat membangunindeks untuk file yang
menyimpan database.

• Ada dua jenis indeks yang dapat kita gunakan: indeks padat dan indeks jarang. Indeks
padat berisi entri untuk setiap nilai kunci pencarian, sedangkan indeks jarang berisi
entri hanya untuk beberapa nilai kunci pencarian.

• Jika urutan pengurutan kunci pencarian cocok dengan urutan pengurutan relasi, indeks pada kunci
pencarian disebut a indeks pengelompokan. Indeks lainnya disebutnon-pengelompokan
atau indeks sekunder. Indeks sekunder meningkatkan kinerja kueri yang menggunakan
kunci pencarian selain dari kunci pencarian indeks pengelompokan. Namun, mereka
membebankan overhead pada modifikasi database.

• File sekuensial indeks adalah salah satu skema indeks tertua yang digunakan dalam sistem basis data. Untuk
memungkinkan pengambilan cepat catatan dalam urutan kunci pencarian, catatan disimpan secara berurutan,
dan catatan yang tidak berurutan dirantai bersama. Untuk memungkinkan akses acak cepat, kami menggunakan
struktur indeks.

• Kerugian utama dari organisasi file urutan indeks adalah bahwa kinerja menurun saat
file tumbuh. Untuk mengatasi kekurangan ini, kita dapat menggunakan B+-indeks
pohon.

• AB+-indeks pohon berbentuk a seimbang pohon, di mana setiap jalan dari akar pohon
ke daun pohon adalah sama panjang. Ketinggian B+- pohon sebanding dengan
logaritma ke basis n dari jumlah record dalam relasi, di mana setiap node nonleaf
menyimpan n petunjuk; nilai darin sering sekitar 50 atau 100. B+-pohon jauh lebih
pendek daripada struktur pohon biner seimbang lainnya seperti pohon AVL, dan oleh
karena itu memerlukan lebih sedikit akses disk untuk menemukan catatan.

• Cari di B+-pohon mudah dan efisien. Penyisipan dan penghapusan,


bagaimanapun, agak lebih rumit, tetapi masih efisien. Jumlah operasi yang
diperlukan untuk pencarian, penyisipan, dan penghapusan pada B+-pohon
sebanding dengan logaritma ke basis n dari jumlah record dalam relasi, di mana
setiap node nonleaf menyimpan n petunjuk.

• Kita bisa menggunakan B+-trees untuk mengindeks file yang berisi catatan, serta untuk mengatur
catatan ke dalam file.

• Indeks B-tree mirip dengan B+-indeks pohon. Keuntungan utama dari B-tree adalah bahwa B-tree
menghilangkan penyimpanan nilai kunci pencarian yang berlebihan. Kerugian utama adalah
kompleksitas keseluruhan dan pengurangan fanout untuk ukuran node tertentu. Perancang sistem
hampir secara universal lebih menyukai B+indeks -tree di atas indeks B-tree dalam praktik.
678 Bab 14 Pengindeksan

• Hashing adalah teknik yang banyak digunakan untuk membangun indeks di memori utama serta
dalam sistem berbasis disk.

• Indeks berurutan seperti B+-pohon dapat digunakan untuk seleksi berdasarkan kondisi kesetaraan
yang melibatkan atribut tunggal. Ketika beberapa atribut terlibat dalam kondisi pemilihan, kita
dapat memotong pengidentifikasi rekaman yang diambil dari beberapa indeks.

• dasar B+-struktur pohon tidak ideal untuk aplikasi yang perlu mendukung sejumlah besar
penulisan/penyisipan acak per detik. Beberapa struktur indeks alternatif telah diusulkan
untuk menangani beban kerja dengan kecepatan tulis/masukkan yang tinggi, termasuk
pohon gabungan berstruktur log dan pohon penyangga.

• Indeks bitmap memberikan representasi yang sangat ringkas untuk mengindeks atribut
dengan sangat sedikit nilai yang berbeda. Operasi persimpangan sangat cepat pada bitmap,
menjadikannya ideal untuk mendukung kueri pada banyak atribut.

• R-tree adalah perpanjangan multidimensi dari B-tree; dengan varian seperti R+-pohon dan R*
-trees, mereka telah terbukti populer di database spasial. Struktur indeks yang mempartisi
ruang secara teratur, seperti quadtrees, membantu dalam memproses kueri gabungan
spasial.

• Ada beberapa teknik pengindeksan data temporal, antara lain penggunaan


indeks spasial dan interval B+-pohon indeks khusus.

Tinjau Persyaratan

• Jenis indeks ° indeks utama;


° Indeks yang dipesan ° Indeks nonclustering
° Indeks hash ° indeks sekunder
• Faktor evaluasi ° File indeks-urutan
° Jenis akses • entri indeks

° Waktu akses • Catatan indeks

• indeks padat
° Waktu penyisipan
• Indeks jarang
° Waktu penghapusan
• Indeks bertingkat
° Ruang di atas kepala • Kunci pencarian yang tidak unik

• Cari kunci • Kunci pencarian gabungan

• Indeks yang dipesan • B+-file indeks pohon

° Indeks yang dipesan ° Pohon seimbang


° indeks pengelompokan ° Nodus daun
Latihan Latihan 679

° Node tak berdaun ° Hashing dinamis


° Node internal • Akses multi-kunci
° Kueri rentang • Indeks penutup
° Pemisahan simpul • Struktur indeks yang dioptimalkan untuk penulisan

° Penggabungan simpul ° Pohon gabungan terstruktur-log (LSM)


° Distribusi ulang pointer ° Indeks penggabungan bertahap

° pemersatu ° Pohon penyangga

• B+-ekstensi pohon
• indeks bitmap
° Kompresi awalan • Persimpangan bitmap

° Pemuatan massal • Pengindeksan data spasial

° Bawah-atas B+-konstruksi pohon ° Kueri rentang


• indeks B-pohon ° Pertanyaan tetangga terdekat
• Organisasi file hash
° pohon kd
° Fungsi hash
° pohon kdB
° Keranjang
° Quadtrees
° Rantai luapan ° R-pohon
° Pengalamatan tertutup
° kotak pembatas
° hashing tertutup
• Indeks temporal
° Bucket meluap
• Jarak waktu
° Condong
• Interval tertutup
° Hashing statis • Interval terbuka

Latihan Latihan

14.1 Indeks mempercepat pemrosesan kueri, tetapi biasanya merupakan ide yang buruk untuk membuat
indeks pada setiap atribut, dan setiap kombinasi atribut, yang merupakan kunci pencarian potensial.
Jelaskan mengapa.

14.2 Apakah mungkin secara umum memiliki dua indeks pengelompokan pada relasi yang sama untuk kunci
pencarian yang berbeda? Jelaskan jawabanmu.

14.3 Buat B+-tree untuk set nilai kunci berikut:

(2, 3, 5, 7, 11, 17, 19, 23, 29, 31)


680 Bab 14 Pengindeksan

Asumsikan bahwa pohon awalnya kosong dan nilai ditambahkan dalam urutan menaik.
Bangun B+-trees untuk kasus di mana jumlah pointer yang akan muat dalam satu node
adalah sebagai berikut:

A. Empat

B. Enam

C. Delapan

14.4 Untuk setiap B+-pohon Latihan 14.3, tunjukkan bentuk pohon setelah setiap
rangkaian operasi berikut:

A. Sisipkan 9.

B. Sisipkan 10.

C. Sisipkan 8.

D. Hapus 23.
e. Hapus 19.
14.5 Pertimbangkan skema redistribusi yang dimodifikasi untuk B+-pohon dijelaskan di halaman
651. Berapa tinggi pohon yang diharapkan sebagai fungsi dari n?

14.6 Berikan pseudocode untuk B+-fungsi pohon findRangeIterator(), yang seperti


fungsinya temukanRentang(), kecuali bahwa ia mengembalikan objek iterator, seperti
yang dijelaskan dalam Bagian 14.3.2. Juga berikan kodesemu untuk kelas iterator,
termasuk variabel dalam objek iterator, danlanjut() metode.

14.7 Berapa hunian setiap simpul daun dari B+-tree menjadi jika entri indeks dimasukkan
dalam urutan yang diurutkan? Jelaskan mengapa.

14.8 Misalkan Anda memiliki hubungan R dengan nR tupel di mana B sekunder+-pohon


akan dibangun.

A. Berikan rumus untuk biaya membangun B+-tree index dengan memasukkan satu record
pada satu waktu. Asumsikan setiap blok akan menampung rata-rataF entri dan bahwa
semua tingkat pohon di atas daun berada dalam memori.

B. Dengan asumsi akses disk acak membutuhkan waktu 10 milidetik, berapa


biaya konstruksi indeks pada relasi dengan 10 juta record?

C. Tulis kodesemu untuk konstruksi bottom-up dari B+-pohon, yang diuraikan dalam
Bagian 14.4.4. Anda dapat mengasumsikan bahwa fungsi untuk menyortir file
besar secara efisien tersedia.

14.9 Node daun dari B+-organisasi file pohon mungkin kehilangan urutan setelah
urutan sisipan.

A. Jelaskan mengapa sekuensial bisa hilang.


Latihan Latihan 681

B. Untuk meminimalkan jumlah pencarian dalam pemindaian sekuensial, banyak database


mengalokasikan halaman daun dalam luasan:n blok, untuk beberapa yang cukup besar
n. Ketika daun pertama dari B+-tree dialokasikan, hanya satu blok dari sebuah n-blok
unit digunakan, dan halaman yang tersisa gratis. Jika halaman terbelah, dan itu
n-blok unit memiliki halaman gratis, ruang itu digunakan untuk halaman baru. jika
n-unit blok penuh, yang lain n-blok unit dialokasikan, dan yang pertama n/2
halaman daun ditempatkan dalam satu n-blok unit dan yang tersisa di detik
n-satuan blok Untuk kesederhanaan, asumsikan bahwa tidak ada operasi penghapusan.

Saya. Apa hunian terburuk dari ruang yang dialokasikan, dengan asumsi tidak ada
operasi penghapusan, setelah yang pertama?nunit -blok penuh?

ii. Apakah mungkin simpul daun dialokasikan ke sebuahn-unit blok simpul


tidak berurutan, yaitu mungkinkah dua simpul daun dialokasikan
menjadi satu? nblok -node, tetapi simpul daun lain di antara keduanya
dialokasikan ke yang berbeda n-blok simpul?
aku aku aku. Di bawah asumsi yang masuk akal bahwa ruang penyangga cukup untuk
menyimpannblok -halaman, berapa banyak pencarian yang diperlukan untuk
pemindaian tingkat daun B+-pohon, dalam kasus terburuk? Bandingkan angka ini
dengan kasus terburuk jika halaman daun dialokasikan satu blok pada satu waktu.

iv. Teknik mendistribusikan ulang nilai ke saudara kandung untuk meningkatkan


pemanfaatan ruang kemungkinan akan lebih efisien bila digunakan dengan skema
alokasi sebelumnya untuk blok daun. Jelaskan mengapa.

14.10 Misalkan Anda diberikan skema database dan beberapa kueri yang sering dieksekusi.
Bagaimana Anda menggunakan informasi di atas untuk memutuskan indeks apa yang akan
dibuat?

14.11 Di pohon yang dioptimalkan untuk penulisan seperti pohon LSM atau indeks penggabungan
bertahap, entri dalam satu level digabungkan ke level berikutnya hanya jika levelnya penuh. Sarankan
bagaimana kebijakan ini dapat diubah untuk meningkatkan kinerja baca selama periode ketika ada
banyak pembacaan tetapi tidak ada pembaruan.

14.12 Apa trade off yang ditimbulkan oleh pohon penyangga dibandingkan dengan pohon

14.13 LSM? Pertimbangkanpengajar hubungan ditunjukkan pada Gambar 14.1.

A. Buat indeks bitmap pada atributgaji, membagi gaji nilai menjadi empat rentang: di
bawah 50.000, 50.000 hingga di bawah 60.000, 60.000 hingga di bawah
70.000, dan 70.000 ke atas.
B. Pertimbangkan permintaan yang meminta semua instruktur di departemen
Keuangan dengan gaji 80.000 atau lebih. Uraikan langkah-langkah dalam
menjawab kueri, dan tunjukkan bitmap akhir dan menengah yang dibuat untuk
menjawab kueri.

14.14 Misalkan Anda memiliki relasi yang mengandung x, kamu koordinat dan nama restoran.
Misalkan juga bahwa satu-satunya pertanyaan yang akan ditanyakan adalah dari
682 Bab 14 Pengindeksan

formulir berikut: Kueri menentukan suatu titik dan menanyakan apakah ada
restoran persis di titik itu. Jenis indeks mana yang lebih disukai, R-tree atau B-tree?
Mengapa?

14.15 Misalkan Anda memiliki database spasial yang mendukung kueri wilayah dengan wilayah
melingkar, tetapi bukan kueri tetangga terdekat. Jelaskan algoritma untuk menemukan
tetangga terdekat dengan memanfaatkan beberapa kueri wilayah.

Latihan

14.16 Kapan lebih baik menggunakan indeks padat daripada indeks jarang? Jelaskan
jawabanmu.

14.17 Apa perbedaan antara indeks pengelompokan dan indeks sekunder?


14.18 Untuk setiap B+-pohon Latihan 14.3, tunjukkan langkah-langkah yang terlibat dalam pertanyaan
berikut:

A. Temukan catatan dengan nilai kunci pencarian 11.

B. Temukan catatan dengan nilai kunci pencarian antara 7 dan 17, inklusif.

14.19 Solusi yang disajikan di Bagian 14.3.5 untuk menangani kunci pencarian yang tidak unik
menambahkan atribut tambahan ke kunci pencarian. Apa pengaruh perubahan ini
terhadap ketinggian B+-pohon?

14.20 Misalkan ada hubungan R(A, B, C), dengan B+-pohon indeks dengan kunci pencarian (A, B
).

A. Berapa biaya kasus terburuk untuk menemukan catatan yang memuaskan 10< < 50
menggunakan indeks ini, dalam hal jumlah catatan yang diambil n1 dan
tingginya H dari pohon?

B. Berapa biaya kasus terburuk untuk menemukan catatan yang memuaskan 10< < 50 ∧
5 < B < 10 menggunakan indeks ini, dalam hal jumlah catatan n2 yang
memenuhi pilihan ini, serta n1 dan H didefinisikan di atas?

C. Dalam kondisi apa padan1 dan n2 akankah indeks menjadi cara yang efisien untuk
menemukan catatan yang memuaskan 10 < < 50 ∧ 5 < B < 10?

14.21 Misalkan Anda harus membuat B+-pohon indeks pada sejumlah besar nama, di mana
ukuran maksimum nama mungkin cukup besar (misalnya 40 karakter) dan nama rata-
rata itu sendiri besar (misalnya 10 karakter). Jelaskan bagaimana kompresi awalan dapat
digunakan untuk memaksimalkan fanout rata-rata node nonleaf.

14.22 Misalkan suatu relasi disimpan dalam B+-organisasi file pohon. Misalkan indeks sekunder menyimpan
pengidentifikasi rekaman yang merupakan penunjuk ke rekaman pada disk.
Bacaan lebih lanjut 683

A. Apa efeknya pada indeks sekunder jika terjadi pemisahan


simpul di organisasi file?
B. Berapa biaya memperbarui semua catatan yang terpengaruh dalam indeks
sekunder?

C. Bagaimana cara menggunakan kunci pencarian dari organisasi file sebagai pengidentifikasi
catatan logis memecahkan masalah ini?

D. Berapa biaya tambahan karena penggunaan pengidentifikasi catatan logis seperti itu?

14.23 Apa trade-off yang ditimbulkan oleh indeks yang dioptimalkan penulisan dibandingkan dengan B+-indeks pohon?

14.24 NS keberadaan bitmap memiliki bit untuk setiap posisi record, dengan bit disetel ke 1
jika record ada, dan 0 jika tidak ada record pada posisi tersebut (misalnya, jika
record dihapus). Tunjukkan cara menghitung keberadaan bitmap dari bitmap lain.
Pastikan bahwa teknik Anda berfungsi bahkan dengan adanya nilai nol dengan
menggunakan bitmap untuk nilai tersebutbatal.

14.25 Indeks spasial yang dapat mengindeks interval spasial secara konseptual dapat digunakan untuk mengindeks data
temporal dengan memperlakukan waktu yang valid sebagai interval waktu. Apa masalahnya dengan
melakukannya, dan bagaimana masalahnya diselesaikan?

14.26 Beberapa atribut relasi mungkin berisi data sensitif, dan mungkin perlu disimpan dengan
cara terenkripsi. Bagaimana enkripsi data memengaruhi skema indeks? Secara khusus,
bagaimana pengaruhnya terhadap skema yang mencoba menyimpan data dalam urutan
yang diurutkan?

Bacaan lebih lanjut

Indeks B-tree pertama kali diperkenalkan di [Bayer dan McCreight (1972)] dan [Bayer
(1972)]. B+-pohon dibahas dalam [Comer (1979)], [Bayer dan Unterauer (1977)], dan [Knuth
(1973)]. [Gray dan Reuter (1993)] memberikan gambaran yang baik tentang isu-isu dalam
implementasi B+-pohon.
Pohon log-structured merge (LSM) disajikan dalam [O'Neil et al. (1996)], sedangkan
pohon gabungan bertangga disajikan dalam [Jagadish et al. (1997)]. Pohon penyangga
disajikan dalam [Arge (2003)]. [Vitter (2001)] menyediakan survei ekstensif tentang struktur
dan algoritme data memori eksternal.
Indeks bitmap dijelaskan dalam [O'Neil dan Quass (1997)]. Mereka pertama kali
diperkenalkan di manajer file Model 204 IBM pada platform AS 400. Mereka memberikan
percepatan yang sangat besar pada jenis kueri tertentu dan saat ini diimplementasikan pada
sebagian besar sistem basis data.
[Samet (2006)] dan [Shekhar dan Chawla (2003)] memberikan cakupan buku teks
tentang struktur data spasial dan database spasial. [Bentley (1975)] menjelaskan pohon kd,
684 Bab 14 Pengindeksan

dan [Robinson (1981)] menjelaskan pohon kdB. R-pohon awalnya disajikan dalam
[Guttman (1984)].

Bibliografi

[Arge (2003)] L. Arge, “Pohon Penyangga: Teknik untuk Mendesain Data Eksternal Batch
Struktur”, algoritma, Jilid 37, Nomor 1 (2003), halaman 1–24.
[Bayer (1972)] R. Bayer, “B-tree Biner Simetris: Struktur Data dan Algoritma Pemeliharaan
ritma”, Acta Informatika, Volume 1, Nomor 4 (1972), halaman 290–306.

[Bayer dan McCreight (1972)] R. Bayer dan EM McCreight, “Organisasi dan Pemeliharaan
nance Indeks Pesanan Besar”, Acta Informatika, Volume 1, Nomor 3 (1972), halaman 173–
189.
[Bayer dan Unterauer (1977)] R. Bayer dan K. Unterauer, “Awalan B-pohon”, Transaksi ACM
pada Sistem Basis Data, Volume 2, Nomor 1 (1977), halaman 11–26.

[Bentley (1975)] JL Bentley, “Pohon Pencarian Biner Multidimensi Digunakan untuk Asosiatif
Mencari”, Komunikasi ACM, Volume 18, Nomor 9 (1975), halaman 509–517.
[Pendatang (1979)] D. Comer, “Pohon B di mana-mana”, Survei Komputasi ACM, Jilid 11,
Nomor 2 (1979), halaman 121–137.

[Gray dan Reuter (1993)] J. Gray dan A. Reuter, Pemrosesan Transaksi: Konsep dan Teknologi
barang antik, Morgan Kaufmann (1993).

[Guttman (1984)] A. Guttman, “R-Trees: Struktur Indeks ADynamic untuk Pencarian Spasial”,
Di dalam Prok. dari ACM SIGMOD Conf. tentang Pengelolaan Data(1984), halaman 47–57.

[Jagadish dkk. (1997)] HV Jagadish, PPS Narayan, S. Seshadri, S. Sudarshan, and


R. Kanneganti, “Organisasi Inkremental untuk Perekaman dan Pergudangan Data”, In
Prosiding Konferensi Internasional ke-23 tentang Basis Data Sangat Besar, VLDB '97 (1997),
halaman 16–25.

[Knuth (1973)] DE Knuth, Seni Pemrograman Komputer, Volume 3, Addison Wesley,


Penyortiran dan Pencarian (1973).

[O'Neil dan Quass (1997)] P. O'Neil dan D. Quass, “Peningkatan Kinerja Kueri dengan
Indeks Varian”, In Prok. dari ACM SIGMOD Conf. tentang Pengelolaan Data(1997), halaman 38–
49.

[O'Neil dkk. (1996)] P. O'Neil, E. Cheng, D. Gawlick, dan E. O'Neil, "The Log-terstruktur
Merge-tree (LSM-tree)”, Akta Inf., Volume 33, Nomor 4 (1996), halaman 351–385.

[Robinson (1981)] J. Robinson, “Pohon kdB: Struktur Pencarian untuk Multidimensi Besar
Indeks nasional”, In Prok. dari ACM SIGMOD Conf. tentang Pengelolaan Data(1981), halaman
10–18.

[Samet (2006)] H. Samat, Fondasi Struktur Data Multidimensi dan Metrik, Mor-
gan Kaufmann (2006).
Bacaan lebih lanjut 685

[Shekhar dan Chawla (2003)] S. Shekhar dan S. Chawla, Basis Data Spasial: TOUR, Pir-
putra (2003).

[Vitter (2001)] JS Vitter, “Algoritma Memori Eksternal dan Struktur Data: Berurusan dengan
Data Besar”, Survei Komputasi ACM, Volume 33, (2001), halaman 209–271.

Kredit

Foto perahu layar di awal bab ini dibuat oleh ©Pavel Nesvadba/
Shutterstock.

Anda mungkin juga menyukai