Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Libpuzzle Indeksujesz miliony zdjęć?

Spójrzmy więc na podany przez nich przykład i spróbujmy go rozwinąć.

Załóżmy, że masz tabelę, która przechowuje informacje dotyczące każdego obrazu (ścieżka, nazwa, opis itp.). W tej tabeli umieścisz pole dla skompresowanego podpisu, obliczanego i przechowywanego podczas początkowego wypełniania bazy danych. Zdefiniujmy tę tabelę w ten sposób:

CREATE TABLE images (
    image_id INTEGER NOT NULL PRIMARY KEY,
    name TEXT,
    description TEXT,
    file_path TEXT NOT NULL,
    url_path TEXT NOT NULL,
    signature TEXT NOT NULL
);

Kiedy początkowo obliczasz podpis, obliczysz również liczbę słów z podpisu:

// this will be run once for each image:
$cvec = puzzle_fill_cvec_from_file('img1.jpg');
$words = array();
$wordlen = 10; // this is $k from the example
$wordcnt = 100; // this is $n from the example
for ($i=0; $i<min($wordcnt, strlen($cvec)-$wordlen+1); $i++) {
    $words[] = substr($cvec, $i, $wordlen);
}

Teraz możesz umieścić te słowa w tabeli, zdefiniowanej w następujący sposób:

CREATE TABLE img_sig_words (
    image_id INTEGER NOT NULL,
    sig_word TEXT NOT NULL,
    FOREIGN KEY (image_id) REFERENCES images (image_id),
    INDEX (image_id, sig_word)
);

Teraz wstawiasz do tej tabeli, poprzedzony indeksem pozycji, w którym słowo zostało znalezione, aby wiedzieć, kiedy słowo pasuje do tego samego miejsca w podpisie:

// the signature, along with all other data, has already been inserted into the images
// table, and $image_id has been populated with the resulting primary key
foreach ($words as $index => $word) {
    $sig_word = $index.'__'.$word;
    $dbobj->query("INSERT INTO img_sig_words (image_id, sig_word) VALUES ($image_id,
        '$sig_word')"); // figure a suitably defined db abstraction layer...
}

Twoje dane zostały w ten sposób zainicjowane, możesz stosunkowo łatwo pobrać obrazy z pasującymi słowami:

// $image_id is set to the base image that you are trying to find matches to
$dbobj->query("SELECT i.*, COUNT(isw.sig_word) as strength FROM images i JOIN img_sig_words
    isw ON i.image_id = isw.image_id JOIN img_sig_words isw_search ON isw.sig_word =
    isw_search.sig_word AND isw.image_id != isw_search.image_id WHERE
    isw_search.image_id = $image_id GROUP BY i.image_id, i.name, i.description,
    i.file_path, i.url_path, i.signature ORDER BY strength DESC");

Możesz poprawić zapytanie, dodając HAVING klauzula, która wymaga minimalnej strength , co jeszcze bardziej zredukuje Twój zestaw dopasowywania.

Nie gwarantuję, że jest to najbardziej wydajna konfiguracja, ale powinna być z grubsza funkcjonalna, aby osiągnąć to, czego szukasz.

Zasadniczo, dzielenie i przechowywanie słów w ten sposób pozwala na zgrubne sprawdzenie odległości bez konieczności uruchamiania specjalnej funkcji na sygnaturach.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Obsługa danych z wielu pól wyboru

  2. Moje zapytanie SQL Dynamic wykonuje się i otrzymuje dane wyjściowe do zmiennej w procedurze składowanej

  3. Nie można utworzyć tabeli w mysql -Błąd 1064

  4. mysqli_connect():(HY000/2002):Nie można połączyć się z lokalnym serwerem MySQL przez gniazdo

  5. Najszybszy sposób na podzbiór — data.table vs. MySQL