Volltextsuche in vielen Tabellen in MySQL

7

Wir haben hohe Verkehrs Nachrichten - Websites, ich möchte eine Funktion hinzuzufügen , dass jeder Benutzer über alle Inhalte der Website durchsuchen können, wie news, polls, comments, galleriesusw. Jeder Inhaltstyp hat seine eigenen Tabellen.

Ich habe beschlossen, eine Tabelle zu erstellen, die alle Inhalte aller Typen enthält:

CREATE TABLE full_text_search
(
    master_id INT NOT NULL,
    content_text TEXT NOT NULL,
    PRIMARY KEY ( master_id )
);

Ich generiere eine eindeutige Nummer master_idfür jeden Inhalt aller Art, um jeden content_textin der full_text_searchTabelle zu identifizieren .

zum Beispiel:

News table:
+----+-------------+---------+---------+----------+------------+
| id | news_title  | lead    | subtitle|  content | master_id  |
+----+-------------+---------+---------+----------+------------+
|  1 |  sometitle  |some lead| subtitle|content 1 |     3      |
|  2 |  some title |some lead| subtitle|content 2 |     5      |
+----+-------------+---------+---------+----------+------------+

article table:
+----+-------------+---------+------------------+---------+------------+
| id | title       | author  | short description| content | master_id  |
+----+-------------+---------+------------------+---------+------------+
|  1 |  sometitle  | someone | very short desc  |content1 |     1      |
|  2 |  some title | otherone|  some short desc |content2 |     4      |
+----+-------------+---------+------------------+---------+------------+

Wie Sie sehen können, master_idist zwischen den obigen Tabellen eindeutig. Wann immer ein neuer Inhalt von jedem Typ eingefügt wird, sollte ich INSERTihn auch in die full_text_searchTabelle einfügen .

FRAGEN

  • Ist es für viele Beilagen pro Tag (ca. 3000 von allen Typen) eine gute Lösung oder ein Anti-Pattern?
  • Ist es eine bessere Wahl, wenn ich diese Tabelle von meinen anderen Tabellen trenne und sie in eine andere Datenbank wie andere RDBMS oder NoSQLs lege?
  • Irgendwelche anderen Lösungen?
Arash Mousavi
quelle
full_text_searchWie identifizieren Sie mit der Tabelle das richtige Ergebnis mit dem richtigen Typ und der richtigen ID?
Oskar Persson
1
Ich habe meine Frage bearbeitet.
Arash Mousavi

Antworten:

3

Sicher, es ist in Ordnung, den durchsuchbaren Inhalt in Ihre Tabelle full_text_search zu kopieren.

MySQL unterstützt FULLTEXT-Indizes nur in der MyISAM-Speicher-Engine (bis MySQL 5.6, aber der Volltext in InnoDB in MySQL 5.6 scheint immer noch etwas instabil zu sein). So können Sie Ihre kanonischen Daten aus Sicherheitsgründen in InnoDB und eine Kopie in MyISAM zur Indizierung speichern. MyISAM ist anfällig für Datenbeschädigungen. Wenn es sich jedoch nur um eine Kopie handelt, müssen Sie die MyISAM-Tabelle nur neu füllen, falls sie jemals beschädigt wird.

Ihre Verwendung von master_id im Unterschied zum Primärschlüssel jeder Tabelle ist etwas seltsam. Verwenden Sie den Primärschlüssel und fügen Sie Ihrer Tabelle full_text_search eine weitere Spalte für den Inhaltstyp hinzu.

CREATE TABLE full_text_search
(
    id INT NOT NULL,
    content_type ENUM('news','polls','comments','galleries','articles') NOT NULL,
    content_text TEXT NOT NULL,
    PRIMARY KEY ( id, content_type )
);

full_text_search table:
+----+--------------+---------------+
| id | content_type | content_text  |
+----+--------------+---------------+
|  1 |         news |     ...       |
|  1 |     articles |     ...       |
|  2 |     articles |     ...       |
+----+--------------+---------------+

Eine andere Möglichkeit besteht darin, einen Volltextsuchindex in einer anderen spezialisierten Technologie wie Sphinx Search oder Apache Solr zu erstellen. Das gleiche Muster wäre jedoch nützlich - speichern Sie das Primärschlüsselfeld und ein Feld für den Inhaltstyp.

Bill Karwin
quelle
1
Ich habe dein Buch gelesen SQL Antipatterns: Avoiding the Pitfalls of Database Programming. Im Abschnitt "Polymorphe Assoziationen", den Sie in MySQL gesagt haben, können wir keine polymorphe Assoziation haben. Wenn ich einen Fremdschlüssel für diese Tabelle haben möchte, sollte ich "eine gemeinsame Supertabelle" haben. Die master_id ist die ID, die von dieser gemeinsamen Super-Assoziationen generiert wird. Tabelle.
Arash Mousavi
1
Verwenden Sie dann diese master_id als Primärschlüssel in jeder Medientabelle, wie in den Beispielen, die ich in meinem Buch zeige. :-) Der gute Grund dafür ist die Tatsache, dass die Suche nach Primärschlüsseln effizienter ist als die Suche nach Sekundärschlüsseln in der InnoDB-Speicher-Engine.
Bill Karwin
Wenn Sie dies selbst tun, kann ich eine Volltextsuche durchführen, indem ich Daten aus vielen Tabellen kombiniere. Das Erstellen einer neuen Tabelle scheint die Antwort zu sein.
Daniel West