Meine Kenntnisse in Datenbanken und SQL basieren größtenteils auf Universitätsklassen. Jedenfalls habe ich einige Monate (fast ein Jahr) in einer Firma verbracht, in der ich mit Datenbanken gearbeitet habe.
Ich habe einige Bücher gelesen , und ich habe in wenigen Trainings über Datenbanken wie teilgenommen MySQL
, PostgreSQL
, SQLite
, Oracle
und auch wenige nonSQL
db
s so uns MongoDB
, Redis
, ElasticSearch
usw.
Wie gesagt, ich bin ein Anfänger mit vielen Unkenntnissen, aber heute hat jemand etwas erzählt, was völlig gegen das Wissen meines Anfängers ist.
Lassen Sie mich erklären. Nehmen wir die SQL- Datenbank und erstellen eine einfache Tabelle Person
mit wenigen darin enthaltenen Datensätzen:
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
Nun, es ist der Teil, auf den ich mich konzentrieren möchte - id
ist der INDEX
.
Bisher dachte ich, dass es so funktioniert: Wenn eine Tabelle erstellt wird, ist die INDEX
leer. Wenn ich meinem Tisch einen neuen Datensatz hinzufüge, INDEX
wird der anhand einiger Alghortims neu berechnet. Beispielsweise:
Eins nach dem anderen gruppieren:
1 ... N
N+1 ... 2N
...
XN+1 ... (X+1)N
Also, für mein Beispiel mit size = 11 elements
und wird N = 3
es so sein:
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
Wenn ich also query verwende SELECT * FROM Person WHERE id = 8
, wird eine einfache Berechnung durchgeführt 8 / 3 = 2
, daher müssen wir nach diesem Objekt in suchen group2
und dann wird diese Zeile zurückgegeben:
8 | Hubert | 53
Dieser Ansatz funktioniert in der Zeit O(k)
wo k << size
. Ein Alghoritm, Zeilen in Gruppen zu organisieren, ist natürlich viel komplizierter, aber ich denke, dieses einfache Beispiel zeigt meinen Standpunkt.
Deshalb möchte ich jetzt einen anderen Ansatz vorstellen, der mir heute gezeigt wurde.
Nehmen wir noch einmal diese Tabelle:
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
Nun sind wir etwas Ähnliches zu schaffen Hashmap
(in der Tat wörtlich ist es eine Hash - Map) , die Karten id
zu address
dieser Reihen - ID. Sagen wir:
id | addr
---------
1 | @0001
2 | @0010
3 | @0011
4 | @0100
5 | @0101
6 | @0110
7 | @0111
8 | @1000
9 | @1001
10 | @1010
11 | @1011
Wenn ich jetzt meine Abfrage starte: SELECT * FROM Person WHERE id = 8
Es wird direkt id = 8
auf die Adresse im Speicher abgebildet und die Zeile wird zurückgegeben. Natürlich ist die Komplexität davon O(1)
.
Jetzt habe ich einige Fragen.
1. Was sind die Vor- und Nachteile beider Lösungen?
2. Welches ist in aktuellen Datenbankimplementierungen beliebter? Vielleicht verwenden unterschiedliche DBs unterschiedliche Ansätze?
3. Existiert es in Nicht-SQL-Datenbanken?
Danke im Voraus
VERGLEICH
| 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 - Anzahl der Datensätze
Habe ich recht? Was ist mit den Kosten für die Neuerstellung von B-Tree und Hash-Tabelle nach jedem Einfügen / Löschen ? Im Falle eines B-Baums müssen wir einige Zeiger ändern, aber im Falle eines ausgeglichenen B-Baums ist mehr Aufwand erforderlich. Auch im Fall einer Hash-Tabelle müssen wir nur wenige Operationen ausführen, insbesondere wenn unsere Operationen Konflikte erzeugen .
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.
Natürlich weiß ich, dass es viel, viel komplizierter ist. Wenn ich also in meinem Code sage, INDEX
welche meiner Lösungen ( 1. oder 2. ) ist näher an dieser realen? Und was ist mit der Zeit, die benötigt wird, um auf einen Datensatz zuzugreifen, basierend auf INDEX
. Ist es wirklich O(1)
? Mit B-Tree-Index klingt es ähnlich O(log2(N))
. Habe ich recht?
O(1)
Sie hat es richtig gemacht! Zunächst scheint es, als würden Sie einen B-Baum-Index beschreiben, aber Sie haben ein Missverständnis. Es gibt keine Berechnung (Division durch 3 oder so), es ist komplexer, da der Baum mehr Ebenen hat (es ist ein Baum, er hat große, kleine, kleinere Zweige, ... und dann Blätter :)