2010-10-05 6 views
3

J'essaie d'ajouter une recherche de texte intégral à un système. La requête que je veux écrire doit impliquer plusieurs recherches suivies de la recherche (si c'est possible). J'ai une table des enseignants et une table des matières.Recherches de plusieurs identifiants MySQL

teacherProfile 
teacherId [int] - primary key 
subjectOneId [int] 
subjectTwoId [int] 
subjectThreeId [int] 
teacherBiography [text] 

subjects 
subjectId [int] 
subjectName [text] 

Donc, finalement, je veux un ResultSet le long des lignes de ..

teacherId [int] 
teacherBiography [text] 
(subjectOneName [text]) 
(subjectTwoName [text]) 
(subjectThreeName [text]) 

Ces trois derniers champs entre parenthèses sont non existant, mais je ne veux effectuer une recherche de texte sur eux, dois-je besoin de mettre en place une contrainte de clé foriegn (que je préférerais ne pas faire en cas d'impacts supplémentaires sur le système existant) ou y a-t-il quelque chose de plus éloquent que je peux faire?

Répondre

2

MySQL ne peut pas vues d'index donc ce que vous voulez est impossible dans MySQL.

Vous pouvez utiliser un moteur d'indexation de texte intégral externe comme données Sphinx et charge à l'aide il y a une requête avec JOINS

Vous pouvez également créer une table dénormalisé:

CREATE TABLE ftsearch 
     (
     teacherId INT PRIMARY KEY, 
     teacherBiography TEXT, 
     subject1 TEXT, 
     subject2 TEXT, 
     subject3 TEXT, 
     ) 
ENGINE=MyISAM 

et le remplir avec cette requête:

INSERT 
INTO ftsearch 
SELECT teacherId, teacherBiography, 
     s1.name, s2.name, s3.name 
FROM teacherProfile 
LEFT JOIN 
     subject s1 
ON  s1.id = subjectOneId 
LEFT JOIN 
     subject s2 
ON  s2.id = subjectTwoId 
LEFT JOIN 
     subject s3 
ON  s3.id = subjectThreeId 

en temps opportun.

En fait, si toutes vos tables sont MyISAM, vous pouvez appliquer des requêtes de recherche de texte intégral (en mode booléen) à une jointure, sans avoir à créer un index de texte intégral.

Dites, si vous recherchez '+Jones +math +physics', où Jones est un nom de famille de l'enseignant et math et physics sont sujets, vous pouvez faire cette requête:

SELECT teacherId, teacherBiography, 
     s1.name, s2.name, s3.name 
FROM teacherProfile 
LEFT JOIN 
     subject s1 
ON  s1.id = subjectOneId 
LEFT JOIN 
     subject s2 
ON  s2.id = subjectTwoId 
LEFT JOIN 
     subject s3 
ON  s3.id = subjectThreeId 
WHERE MATCH(teacherBiography) AGAINST ('+Jones' IN BOOLEAN MODE) 
     AND MATCH(t.teacherBiography, s1.name, s2.name, s3.name) AGAINST ('+Jones +math +physics' IN BOOLEAN MODE) 

Le MATCH(teacherBiography) AGAINST ('+Jones') utilisera un indice FULLTEXT sur teacher, si tout; la seconde MATCH va filtrer les résultats.

requêtes portant sur les conditions OR ou la pertinence cependant de tri sont plus complexes,.

+0

Brillante, merci Quassnoi pour votre excellente réponse. –

+0

En fait, si je sautais la recherche en texte intégral, comment ferais-je la recherche sans l'existence des trois derniers champs? C'est à dire. obtenir les résultats pour la vue ET effectuer une recherche en texte intégral sur le bio? –

+0

@Julian: recherche de quoi? – Quassnoi

Questions connexes