L'appartement

Aller au contenu | Aller au menu | Aller à la recherche

Tag - innodb

Fil des billets

lundi, septembre 10 2007

Recherche Fulltext et InnoDB avec Mysql

Logo MysqlLes 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 ;)

mardi, juillet 17 2007

Passage sur Dotclear 2 Beta7

Apparement, il y avait une grosse faille de sécurité chez Dotclear. J'ai donc mis à jour. Pour mon blog, pas de problème. Pour la plateforme multiblogs que je gère, ca a été plus compliqué.

Le moteur utilisé par Dotclear 2 avec Mysql maintenant InnoDB. C'est bien. Il y a des belles contraintes d'intégrité partout ;)

Va savoir pourquoi, l'intégrité n'était plus de mise sur la base multiblogs, il y avait des enregistrements orphelins qui ne faisaient plus référence. J'ai du donc nettoyer un peu :

DELETE FROM `dc_post` WHERE blog_id NOT IN (SELECT blog_id FROM dc_blog);
DELETE FROM `dc_category` WHERE blog_id NOT IN (SELECT blog_id FROM dc_blog);
DELETE FROM `dc_link` WHERE blog_id NOT IN (SELECT blog_id FROM dc_blog);
DELETE FROM `dc_permissions` WHERE blog_id NOT IN (SELECT blog_id FROM dc_blog);
DELETE FROM `dc_setting` WHERE blog_id NOT IN (SELECT blog_id FROM dc_blog);
DELETE FROM `dc_spamrule` WHERE blog_id NOT IN (SELECT blog_id FROM dc_blog);
DELETE FROM `dc_media` WHERE user_id NOT IN (SELECT user_id FROM dc_user);
DELETE FROM `dc_comment` WHERE post_id NOT IN (SELECT post_id FROM dc_post);
DELETE FROM `dc_media` WHERE user_id NOT IN (SELECT user_id FROM dc_user);
DELETE FROM `dc_post_media` WHERE media_id NOT IN (SELECT media_id FROM dc_media);
DELETE FROM `dc_post_media` WHERE post_id NOT IN (SELECT post_id FROM dc_post);

Ca pourrait-être intégré dans le code de Dotclear avant une mise à jour ?!