Tworzę aplikację internetową o dużej objętości, której częścią jest baza danych MySQL zawierająca wpisy w dyskusji, które będą musiały bezproblemowo urosnąć do ponad 20 milionów wierszy.
Początkowo planowałem użyć MyISAM dla tabel (dla wbudowanych funkcji wyszukiwania pełnotekstowego ), ale myśl o zablokowaniu całej tabeli z powodu jednej operacji zapisu sprawia, że jestem zamknięty. Blokady na poziomie wiersza mają o wiele więcej sensu (nie wspominając o innych zaletach szybkości InnoDB w przypadku dużych tabel). Z tego powodu jestem zdecydowany użyć InnoDB.
Problem w tym, że ... InnoDB nie ma wbudowanych możliwości wyszukiwania pełnotekstowego.
Czy powinienem skorzystać z systemu wyszukiwania innej firmy? Jak Lucene (C ++) / Sphinx ? Czy któryś z was, ninja baz danych, ma jakieś sugestie / wskazówki?Zoie na LinkedIn (oparte na Lucene) wygląda w tej chwili na najlepszą opcję... ponieważ został zbudowany w oparciu o możliwości czasu rzeczywistego (co jest bardzo ważne dla mojej aplikacji). Trochę się waham, czy zaangażować się bez wglądu ...
(FYI: będę na EC2 z platformami o dużej ilości pamięci, używając PHP do obsługi interfejsu)
Odpowiedzi:
Mogę ręczyć, że pełny tekst MyISAM jest złą opcją - nawet pomijając różne problemy z tabelami MyISAM w ogóle, widziałem, jak rzeczy pełnotekstowe wypadają z szyn i zaczynają się regularnie uszkadzać i zawieszać MySQL.
Dedykowana wyszukiwarka na pewno będzie tutaj najbardziej elastyczną opcją - przechowuj dane postów w MySQL / innodb, a następnie wyeksportuj tekst do swojej wyszukiwarki. Możesz dość łatwo skonfigurować okresowe tworzenie / publikowanie pełnego indeksu i dodawać aktualizacje indeksu w czasie rzeczywistym, jeśli czujesz taką potrzebę i chcesz spędzić czas.
Lucene i Sphinx to dobre opcje, podobnie jak Xapian , który jest ładny i lekki. Jeśli pójdziesz ścieżką Lucene, nie zakładaj, że Clucene będzie lepsza, nawet jeśli wolisz nie zmagać się z Javą, chociaż nie mam kwalifikacji, aby omawiać zalety i wady obu.
źródło
Wraz z ogólnym wycofywaniem MyISAM, wyszukiwanie pełnotekstowe InnoDB (FTS) jest wreszcie dostępne w wydaniu MySQL 5.6.4.
Wiele soczystych szczegółów na https://dev.mysql.com/doc/refman/5.6/en/innodb-fulltext-index.html .
Podczas gdy inne silniki mają wiele różnych funkcji, ten to InnoDB, więc jest natywny (co oznacza, że istnieje ścieżka aktualizacji), co sprawia, że jest to opłacalna opcja.
źródło
Powinieneś poświęcić godzinę i przejść przez instalację i jazdę próbną Sphinx i Lucene. Sprawdź, czy któryś z nich spełnia Twoje potrzeby w zakresie aktualizacji danych.
Jedną z rzeczy, które rozczarowały mnie w Sphinx, jest to, że nie obsługuje on zbyt dobrze wstawek przyrostowych. Oznacza to, że ponowne zindeksowanie po wstawieniu jest bardzo drogie, tak drogie, że zalecanym rozwiązaniem jest podzielenie danych na starsze, niezmienne wiersze i nowsze, niestabilne wiersze. Dlatego każde wyszukiwanie w Twojej aplikacji wymagałoby dwukrotnego przeszukania: raz w większym indeksie dla starych wierszy, a także w mniejszym indeksie dla ostatnich wierszy. Jeśli to nie integruje się z twoimi wzorcami użytkowania, ten Sphinx nie jest dobrym rozwiązaniem (przynajmniej nie w jego obecnej implementacji).
Chciałbym wskazać inne możliwe rozwiązanie, które możesz rozważyć: Twoja wyszukiwarka Google . Jeśli możesz zastosować SEO do swojej aplikacji internetowej, zleć funkcję indeksowania i wyszukiwania firmie Google i umieść pole tekstowe wyszukiwania Google w swojej witrynie. To może być najbardziej ekonomiczny i skalowalny sposób na umożliwienie wyszukiwania w witrynie.
źródło
Być może nie powinieneś tak szybko odrzucać FT MySQL. Używał go Craigslist .
edytować
Jak skomentowano poniżej, wydaje się, że Craigslist przeszedł na Sphinx na początku 2009 roku.
źródło
Sfinks, jak zauważyłeś, jest całkiem niezły do tego materiału. Cała praca znajduje się w pliku konfiguracyjnym. Upewnij się, że tabela zawierająca ciągi znaków ma jakiś unikalny klucz typu integer id i wszystko powinno być w porządku.
źródło
Spróbuj tego
ROUND((LENGTH(text) - LENGTH(REPLACE(text, 'serchtext', ''))) / LENGTH('serchtext'),0)!=0
źródło
Powinieneś spojrzeć na Sfinksa. Warte spróbowania. Indeksowanie jest bardzo szybkie i jest dystrybuowane. Powinieneś rzucić okiem na ten (http://www.percona.com/webinars/2012-08-22-full-text-search-throwdown) webminar. Mówi o wyszukiwaniu i ma kilka zgrabnych punktów odniesienia. Może się to okazać pomocne.
źródło
Jeśli wszystko inne zawiedzie, zawsze jest soundex_match , który niestety nie jest szybki ani dokładny
źródło
Dla każdego, kto utknął na starszej wersji MySQL / MariaDB (np. Użytkownicy CentOS), gdzie InnoDB nie obsługuje wyszukiwania Fulltext, moim rozwiązaniem przy korzystaniu z tabel InnoDB było utworzenie oddzielnej tabeli MyISAM dla tego, co chciałem przeszukać.
Na przykład moja główna tabela InnoDB zawierała
products
różne klucze i referencyjną integralność. Następnie utworzyłem prostą tabelę MyISAM o nazwieproduct_search
zawierającą dwa polaproduct_id
iproduct_name
gdzie ta ostatnia była ustawiona naFULLTEXT
indeks. Oba pola są w rzeczywistości kopią tego, co jest w treściproduct
tabeli .Następnie przeszukuję tabelę MyISAM przy użyciu pełnego tekstu i wykonuję sprzężenie wewnętrzne z powrotem do tabeli InnoDB.
Zawartość tabeli MyISAM można aktualizować za pomocą wyzwalaczy lub modelu aplikacji.
Nie polecałbym tego, jeśli masz wiele tabel, które wymagają pełnego tekstu, ale w przypadku jednego stołu wydaje się to wystarczającym obejściem, dopóki nie możesz zaktualizować.
źródło