La mia conoscenza di database e SQL si basa in gran parte su classi universitarie. Comunque, ho trascorso pochi mesi (quasi un anno) in un'azienda, dove lavoravo con i database.
Ho letto qualche libro e ho preso parte a pochi corsi di formazione sui database, come MySQL
, PostgreSQL
, SQLite
, Oracle
e anche alcuni nonSQL
db
s come noi MongoDB
, Redis
, ElasticSearch
etc.
Come ho già detto, sono un mendicante, con molta mancanza di conoscenza, ma oggi qualcuno ha detto qualcosa, ciò che è totalmente contro la conoscenza del mio mendicante.
Lasciatemi spiegare. Prendiamo il database SQL e creiamo una semplice tabella Person
con pochi record all'interno:
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
Ora, è la parte su cui vorrei concentrarmi - id
è la INDEX
.
Finora, ho pensato che funzionasse in questo modo: quando viene creata una tabella INDEX
è vuota. Quando aggiungo un nuovo record al mio tavolo, questo INDEX
viene ricalcolato in base ad alcuni alghortim. Per esempio:
Raggruppando uno per uno:
1 ... N
N+1 ... 2N
...
XN+1 ... (X+1)N
quindi, per il mio esempio con size = 11 elements
e N = 3
sarà così:
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
Quindi, quando sto usando la query SELECT * FROM Person WHERE id = 8
farà qualche semplice calcolo 8 / 3 = 2
, quindi dobbiamo cercare questo oggetto group2
e quindi questa riga verrà restituita:
8 | Hubert | 53
Questo approccio funziona nel tempo in O(k)
cui k << size
. Certo, un algoritmo per organizzare le file in gruppi è sicuramente molto più complicato, ma penso che questo semplice esempio mostri il mio punto di vista.
Quindi ora vorrei presentare un altro approccio, che mi è stato mostrato oggi.
Riprendiamo questa tabella:
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
Ora, stiamo creando qualcosa di simile a Hashmap
(in effetti, letteralmente è una mappa hash) che si associa id
a address
di fila con questo ID. Diciamo:
id | addr
---------
1 | @0001
2 | @0010
3 | @0011
4 | @0100
5 | @0101
6 | @0110
7 | @0111
8 | @1000
9 | @1001
10 | @1010
11 | @1011
Quindi ora, quando eseguo la mia query: SELECT * FROM Person WHERE id = 8
verrà mappato direttamente id = 8
all'indirizzo in memoria e la riga verrà restituita. Naturalmente la complessità di questo è O(1)
.
Quindi ora ho alcune domande.
1. Quali sono gli avventaggi e gli svantaggi di entrambe le soluzioni?
2. Quale è più popolare nelle attuali implementazioni del database? Forse dbs diversi usano approcci diversi?
3. Esiste in dbs non SQL?
Grazie in anticipo
CONFRONTO
| 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 - numero di record
Ho ragione? Che dire del costo di ricostruzione della tabella B-tree e Hash dopo ogni inserimento / cancellazione ? Nel caso di B-tree dobbiamo cambiare alcuni puntatori ma in caso di b-tree bilanciato ha bisogno di più sforzo. Anche nel caso della tabella hash dobbiamo fare poche operazioni, specialmente se la nostra operazione genera conflitti .
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.
certo che so che è molto molto più complicato. Quindi, infine, quando sto dicendo nel mio codice INDEX
quale delle mie soluzioni ( 1 ° o 2 ° ) è più vicina a questa vera? E che dire del tempo necessario per accedere a un record basato su INDEX
. È davvero O(1)
? Con l'indice B-tree sembra molto simile O(log2(N))
. Ho ragione?
O(1)
te ha capito bene! Nel primo modo, sembra che tu stia descrivendo un indice B-tree ma hai dei malintesi. Non esiste alcun calcolo (divisione per 3 o altro), è più complesso in quanto l'albero ha più livelli (è un albero, ha rami grandi, piccoli, più piccoli, ... e poi lascia :)