Mi conocimiento de bases de datos y SQL se basa principalmente en clases universitarias. De todos modos, pasé unos pocos meses (casi un año) en una empresa, donde trabajaba con bases de datos.
He leído algunos libros y he participado en unos entrenamientos sobre bases de datos como MySQL
, PostgreSQL
, SQLite
, Oracle
y también unos nonSQL
db
s como nosotros MongoDB
, Redis
, ElasticSearch
etc.
Como dije, soy un principiante, con mucha falta de conocimiento, pero hoy, alguien dijo algo, lo que está totalmente en contra de mi conocimiento del principiante.
Dejame explicar. Tomemos una base de datos SQL y creemos una tabla simple Person
con pocos registros dentro:
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
Ahora, es la parte en la que me gustaría centrarme, id
es la INDEX
.
Hasta ahora, pensé que funcionaba de esta manera: cuando se crea una tabla, la INDEX
está vacía. Cuando agrego un nuevo registro a mi tabla, el INDEX
cálculo se vuelve a calcular en función de algunos resultados. Por ejemplo:
Agrupando uno por uno:
1 ... N
N+1 ... 2N
...
XN+1 ... (X+1)N
entonces, para mi ejemplo con size = 11 elements
y N = 3
será así:
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
Entonces, cuando estoy usando la consulta SELECT * FROM Person WHERE id = 8
, hará un cálculo simple 8 / 3 = 2
, por lo que debemos buscar este objeto group2
y luego se devolverá esta fila:
8 | Hubert | 53
Este enfoque funciona a tiempo O(k)
donde k << size
. Por supuesto, un algoritmo para organizar filas en grupos es mucho más complicado, pero creo que este simple ejemplo muestra mi punto de vista.
Así que ahora, me gustaría presentar otro enfoque, que me han mostrado hoy.
Tomemos nuevamente esta tabla:
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
Ahora, estamos creando algo similar a Hashmap
(de hecho, literalmente es un Hash Map) que se asigna id
a la address
fila con esta identificación. Digamos:
id | addr
---------
1 | @0001
2 | @0010
3 | @0011
4 | @0100
5 | @0101
6 | @0110
7 | @0111
8 | @1000
9 | @1001
10 | @1010
11 | @1011
Entonces, cuando estoy ejecutando mi consulta: SELECT * FROM Person WHERE id = 8
se asignará directamente id = 8
a la dirección en la memoria y se devolverá la fila. Por supuesto, la complejidad de esto esO(1)
.
Así que ahora tengo algunas preguntas.
1. ¿Cuáles son las ventajas y desventajas de ambas soluciones?
2. ¿Cuál es más popular en las implementaciones de bases de datos actuales? ¿Quizás diferentes dbs usan diferentes enfoques?
3. ¿Existe en dbs no SQL?
Gracias de antemano
COMPARACIÓN
| 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 - número de registros
Estoy en lo cierto? ¿Qué pasa con el costo de reconstruir la tabla B-tree y Hash después de cada inserción / eliminación ? En el caso del árbol B, tenemos que cambiar algunos punteros, pero en el caso del árbol B equilibrado, se necesita más esfuerzo. También en el caso de la tabla Hash , tenemos que hacer pocas operaciones, especialmente si nuestra operación genera conflictos .
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.
Por supuesto, sé que es mucho mucho más complicado. Finalmente, cuando digo en mi código INDEX
cuál de mis soluciones ( 1ra o 2da ) está más cerca de esta real? Y en cuanto al tiempo necesario para acceder a un registro basado en INDEX
. ¿Es realmente O(1)
? Con el índice B-tree se parece mucho O(log2(N))
. Estoy en lo cierto?
O(1)
ti lo hizo bien! En la primera forma, parece que estás describiendo un índice de árbol B pero tienes algunos malentendidos. No hay cálculo (división por 3 ni nada), es más complejo ya que el árbol tiene más niveles (es un árbol, tiene ramas grandes, pequeñas y más pequeñas, ..., y luego se va :)