ricerca efficiente nei database


A chi non è mai capitato di dover eseguire più ricerca in un database all’interno di un unica richiesta, ma a avere ad esempio il problema delle query limitate?

Oggi vediamo due diverse soluzioni ed i vantaggi di ognuna.

La prima consiste di prendere tutto il contenuto della tabella e metterlo in una matrice ed inseguito eseguire una ricerca sequenziale:
N.B. per l’accesso al database vengono usate le mie classi scaricabili al seguente indirizzo http://www.thecsea.it/progetti/classi_db, precisamente viene usata la versione 1.2.2.8

<?php
function cerca($vet,$ele){
	for($i=0;$vet[$i]!=$ele && $i<count($vet);$i++);
	
	if($vet[$i]==$ele)
		return $i;
	return -1;
}

function copia_v($mat,$pos){
	for($i=0;$i<count($mat);$i++)
		$vet[$i] = $mat[$i][$pos];
	return $vet;
			
}


require_once "mysql.php";
$id_da_cercare = 0;
$mysql = new Mysql($db_host,$db_user,$db_password,$db_name);
$results = $mysql->elenca ("*","1 = 1","id","ASC",$this->table_1,1);
$id_resluts = copia_v($results,0);
$pos = cerca($id_results,$id_da_cercare);
if($i>=0)
	print "risultati alla posizione $pos";
else
	print "elemento non trovato";
?>

In pratica la funzione ricerca fa una semplice ricerca sequenziale ritornando -1 in caso l’elemento non è stato trovato altrimenti ne ritorna la posizione.
La funzione copia_v data una matrice e la posizione di una sua colonna ritorna il vettore con tutti gli elementi della colonna.
Nel resto del codice non faccio altro che restituirmi in una matrice tabellare i tutti gli elementi della tabella con al condizione 1=1.
In seguito copio in un vettore la prima colonna dei risultati, che presuppongo essere l’id.
Infine ricerco l’id nel vettore formato e stampo la posizione se l’elemento è stato trovato se no errore, nel caso volessi stampare anche le altre informazioni basterebbe fare $results[1][$pos] ad esempio per il secondo campo del database.
Questo metodo è molto efficiente quando si deve fare una o poche ricerche.

Nel caso di più ricerche è meglio fare una ricerca più evoluta come un buble sort.
basta aggiungere la funzione ordina e modificare la funzione ricerca:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?php
function ordina ($vet){
	for($i=0;$i<count($vet);$i++)
		$ordinati[$i] = $i;
 
	$n = count($vet)-1;
	do{
		$k = 0;
		for($i=0;$i<$n;$i++)
			if($vet[$ordinati[$i]] < $vet[$ordianti[$i+1]]){
				$aux = $ordinati[$i];
				$ordinati[$i] = $ordinati[$i+1];
				$ordinati[$i+1] = $aux;
				$k = $i;
			}
	}while(k);
 
	return $ordinati;
}
 
function cerca($vet,$ele, $ordianti){
	$alto = 0;
	$basso = count($vet)-1;
 
	do{
		$i = ($alto+$basso)/2;
		if($vet[$ordinati[$i]] == $ele)
			return $ordinati[$i];
		elseif($vet[$ordinati[$i]] < $ele)
			$alto = $i+1;
		else
			$basso = $i-1;
	}while($alto<=$basso)
 
	return -1;
}
?>

Nella parte di codice che richiama le funzioni bisogna mettere prima di cerca “$ordinati = ordina($vet);” e poi la funzione cerca deve essere richiamata nel seguente modo : “$pos = cerca($id_results,$id_da_cercare,$ordinati);”.
In pratica prima mi “ordino” il vettore o meglio in un secondo vettore mi metto gli indici ordinati, inseguito faccio una ricerca dicotomica.
la ricerca dicotomica è più efficiente di quella sequenziale, mentre quella sequenziale fa al massimo n iterazioni, quella dicotomica ne fa log di 2 alla n.
L’unico svantaggio è che all’inizio bisogna eseguire la funzione di ordinamento, ma se poi le ricerca da fare sono tante alla fine questa ricerca risulta più efficace.
N.B. qui non c’era bisogno di eseguire la funzione ordina in quanto io richiamavo gli elementi già ordinati dal db secondo l’id, ma è sempre meglio applicare questo metodo a meno che non si ha la certezza che l’ordinamento sql non sia lo stesso della ricerca

CC BY-SA 4.0 ricerca efficiente nei database by cardinale claudio is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

Lascia un commento