问题
I'm trying to add a full text search to a system. The query I want to write needs to involve multiple lookups followed by the search (if that's even possible).
I've got a table of teachers and a table of subjects.
teacherProfile
teacherId [int] - primary key
subjectOneId [int]
subjectTwoId [int]
subjectThreeId [int]
teacherBiography [text]
subjects
subjectId [int]
subjectName [text]
So ultimately I want a resultset along the lines of..
teacherId [int]
teacherBiography [text]
( subjectOneName [text] )
( subjectTwoName [text] )
( subjectThreeName [text] )
So these last three fields in brackets are non existant but I do want to perform a text search upon them, do I need to setup a foriegn key constraint (which I'd rather not to do in case of further impacts on the existing system) or is there something more eloquent I can do?
回答1:
MySQL
cannot index views so what you want is impossible in MySQL
.
You can use an external fulltext indexing engine like Sphinx and load data there using a query with JOINS
Alternatively, you can create a denormalized table:
CREATE TABLE ftsearch
(
teacherId INT PRIMARY KEY,
teacherBiography TEXT,
subject1 TEXT,
subject2 TEXT,
subject3 TEXT,
)
ENGINE=MyISAM
and fill it with this query:
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
on a timely basis.
Actually, if all your tables are MyISAM
, you can apply fulltext search queries (in boolean mode) to a join, without having to create a fulltext index.
Say, if you are searching for '+Jones +math +physics'
, where Jones
is a teacher's surname and math
and physics
are subjects, you can do this query:
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)
The MATCH(teacherBiography) AGAINST ('+Jones')
will use a FULLTEXT
index on teacher
, if any; the second MATCH
will fine-filter the results.
Queries involving the OR
conditions or relevance sorting are more complex, however.
来源:https://stackoverflow.com/questions/3865384/mysql-multiple-id-lookups