Pengetahuan saya tentang database dan SQL sebagian besar berbasis di kelas universitas. Bagaimanapun, saya menghabiskan beberapa bulan (hampir setahun) di sebuah perusahaan, tempat saya bekerja dengan database.
Saya telah membaca beberapa buku dan saya telah mengambil bagian dalam beberapa pelatihan tentang database seperti MySQL
, PostgreSQL
, SQLite
, Oracle
dan juga beberapa nonSQL
db
s seperti kita MongoDB
, Redis
, ElasticSearch
dll
Seperti yang saya katakan, saya pemula, dengan banyak kekurangan pengetahuan tetapi hari ini, seseorang mengatakan sesuatu, apa yang benar-benar bertentangan dengan pengetahuan pemula saya.
Biarkan saya jelaskan. Mari kita ambil database SQL dan buat tabel sederhana Person
dengan beberapa catatan di dalamnya:
id | name | age
-----------------
1 | Alex | 24
2 | Brad | 34
3 | Chris | 29
4 | David | 28
5 | Eric | 18
6 | Fred | 42
7 | Greg | 65
8 | Hubert | 53
9 | Irvin | 17
10 | John | 19
11 | Karl | 23
Sekarang, ini bagiannya, saya ingin fokus - id
adalah INDEX
.
Sejauh ini, saya pikir ini bekerja dengan cara ini: ketika sebuah tabel sedang dibuat, INDEX
kosong. Ketika saya menambahkan catatan baru ke meja saya INDEX
sedang dihitung ulang berdasarkan beberapa alghortims. Sebagai contoh:
Pengelompokan satu per satu:
1 ... N
N+1 ... 2N
...
XN+1 ... (X+1)N
jadi, untuk contoh saya dengan size = 11 elements
dan N = 3
akan seperti ini:
id | name | age
-----------------
1 | Alex | 24 // group0
2 | Brad | 34 // group0
3 | Chris | 29 // group0
4 | David | 28 // group1
5 | Eric | 18 // group1
6 | Fred | 42 // group1
7 | Greg | 65 // group2
8 | Hubert | 53 // group2
9 | Irvin | 17 // group2
10 | John | 19 // group3
11 | Karl | 23 // group3
Jadi, ketika saya menggunakan kueri, SELECT * FROM Person WHERE id = 8
ia akan melakukan beberapa perhitungan sederhana 8 / 3 = 2
, jadi kita harus mencari objek ini group2
dan kemudian baris ini akan dikembalikan:
8 | Hubert | 53
Pendekatan ini bekerja di saat di O(k)
mana k << size
. Tentu saja, sebuah alghoritme untuk mengatur baris dalam kelompok tentu jauh lebih rumit, tetapi saya pikir contoh sederhana ini menunjukkan sudut pandang saya.
Jadi sekarang, saya ingin menyajikan pendekatan lain, yang telah ditunjukkan kepada saya hari ini.
Mari kita lihat sekali lagi tabel ini:
id | name | age
-----------------
1 | Alex | 24
2 | Brad | 34
3 | Chris | 29
4 | David | 28
5 | Eric | 18
6 | Fred | 42
7 | Greg | 65
8 | Hubert | 53
9 | Irvin | 17
10 | John | 19
11 | Karl | 23
Sekarang, kami membuat sesuatu yang mirip dengan Hashmap
(pada kenyataannya, secara harfiah itu adalah Peta Hash) yang memetakan id
ke address
baris dengan id ini. Katakanlah:
id | addr
---------
1 | @0001
2 | @0010
3 | @0011
4 | @0100
5 | @0101
6 | @0110
7 | @0111
8 | @1000
9 | @1001
10 | @1010
11 | @1011
Jadi sekarang, ketika saya menjalankan kueri saya: SELECT * FROM Person WHERE id = 8
itu akan memetakan langsung id = 8
ke alamat di memori dan baris akan dikembalikan. Tentu saja kerumitan ini O(1)
.
Jadi sekarang, saya punya beberapa pertanyaan.
1. Apa saja petualangan dan gangguan dari kedua solusi?
2. Mana yang lebih populer dalam implementasi basis data saat ini? Mungkin dbs yang berbeda menggunakan pendekatan yang berbeda?
3. Apakah ada di dbs nonSQL?
Terima kasih sebelumnya
PERBANDINGAN
| B-tree | Hash Table
----------------------------------------------------
---------------- one element -------------------
----------------------------------------------------
SEARCHING | O(log(N)) | O(1) -> O(N)
DELETING | O(log(N)) | O(1) -> O(N)
INSERTING | O(log(N)) | O(1) -> O(N)
SPACE | O(N) | O(N)
----------------------------------------------------
---------------- k elements -------------------
----------------------------------------------------
SEARCHING | k + O(log(N)) | k * O(1) -> k * O(N)
DELETING | k + O(log(N)) | k * O(1) -> k * O(N)
INSERTING | k + O(log(N)) | k * O(1) -> k * O(N)
SPACE | O(N) | O(N)
N - jumlah catatan
Apakah saya benar? Bagaimana dengan biaya membangun kembali B-tree dan tabel Hash setelah setiap sisipan / hapus ? Dalam hal B-tree kita harus mengubah beberapa pointer tetapi dalam kasus b-tree yang seimbang perlu lebih banyak usaha. Juga dalam kasus tabel Hash kita harus melakukan beberapa operasi, terutama, jika operasi kita menghasilkan konflik .
Of course, an alghoritm to organise rows in groups is for sure much more complicated but I think this simple example shows my point of view.
Tentu saja, saya tahu ini jauh lebih rumit. Jadi akhirnya, ketika saya mengatakan dalam kode saya INDEX
yang mana dari solusi saya ( 1 atau 2 ) yang lebih dekat dengan yang asli ini? Dan bagaimana dengan waktu yang diperlukan untuk mengakses catatan berdasarkan INDEX
. Benarkah itu O(1)
? Dengan indeks B-tree kedengarannya seperti O(log2(N))
. Apakah saya benar?
O(1)
Anda melakukannya dengan benar! Pertama-tama, sepertinya Anda menggambarkan indeks B-tree tetapi Anda memiliki beberapa kesalahpahaman. Tidak ada perhitungan (pembagian dengan 3 atau apapun), ini lebih kompleks karena pohon memiliki lebih banyak tingkatan (itu pohon, memiliki cabang besar, kecil, lebih kecil, ..., dan kemudian pergi :)