Recherche Fulltext et InnoDB avec Mysql
Par Yves Tannier le lundi, septembre 10 2007, 11:22 - Le codage - Lien permanent
Les avantages de l'utilisation du moteur de stockage InnoDB par rapport à MysIsam sur une base de données Mysql (à partir de la version 5.02) sont non négligeables sur certains projets. Il permet l'utilisation :
- de contraintes d'intégrité (Foreign Key ect...)
- de triggers (déclencheurs en français dans le texte).
- de procédures stockées
- ...
Un inconvénient est, par contre, particulièrement pénalisant dès qu'on envisage un moteur de recherche en "texte intégral". Il est en effet impossible de créer des index FULLTEXT avec le moteur InnoDB ! L'utilisation des MATCH et autres joyeusetés est donc impossible. Le classement pertinent des résultats devient plus compliqué à mettre en oeuvre.
Je me suis retrouvé confronté à ce problème récemment et voici comment je l'ai contourné. Je résume, pour l'exemple, en une unique table, ma structure de données qui en compte quelques dizaines.
J'ai donc une table "texts" qui utilise InnoDB avec quelques champs dont le "title" sur lequel je souhaite faire les recherches (la clé primaire s'appelle "idtext").
J'ai créé une table "searchs_texts" avec le moteur MyIsam, deux champs - idtext/title - et un index FULLTEXT sur le champ "title".
Cette table contient, vous l'aurez compris, l'exacte correspondance des champs idtext/title de la table texts.
Reste à tenir à jour cette table sans modifier le code de tous le site. Les triggers vont nous être bien utile pour ça :
Un pour l'INSERT :
CREATE TRIGGER trigger_insert_texts AFTER INSERT ON texts FOR EACH ROW INSERT INTO searchs_texts SET idtext=NEW.idtext, title=NEW.title;
Un pour l'UPDATE :
CREATE TRIGGER trigger_update_texts AFTER UPDATE ON texts FOR EACH ROW UPDATE searchs_texts SET title=NEW.title WHERE idtext=OLD.idtext;
Et enfin, un pour le DELETE :
CREATE TRIGGER trigger_delete_texts AFTER DELETE ON texts FOR EACH ROW DELETE FROM searchs_texts WHERE idtext=OLD.idtext;
Et voilà. Le tour est joué ! Maintenant, votre moteur de recherche pourra utiliser tous ce qui est disponible et bientôt concurrencer Google 

Commentaires
Franchement pas mal comme astuce. Je viens de mettre ça en place et je dois dire que je suis assez satisfait du résultat... malgré le coté un peu bourin de la chose
Merci. Sur que c'est un peu bourrin mais ça fonctionne correctement en production
Salut,
merci pour l'astuce des triggers avec fulltext
cependant les procédures stockés et les triggers n'ont rien à voir avec le type de moteur de la table.
++
Super !
Bonjour,
Merci pour l'astuce.
Cependant ce système, en l'état actuel, à ses limites : si je "TRUNCATE" la table texts, la table searchs_texts n'est pas mit à jour, Idem si un enregistrement de la table texts est supprimé suite à la suppression d'un élément parent (A cause de FOREIGN KEY)
A moins que l'on mette aussi des déclencheurs sur TRUNCATE et ... ?
Si c'est possible ?
Salut, j'ai fait une banque de Curriculum Vitae en ligne en asp.net et j'ai utilisé une BD MySQL. J'ai utilisé la technique mentionnée plus haut et ça fonctionne vraiment bien! Merci!
Essayez la recheche full text, très rapide : CV en ligne