2010-01-25 2 views
0

Надеясь кто-то может предоставить некоторые MySQL советы ...Правильный MySQL структура данных для полнотекстового поиска

У меня есть 2 таблицы, которые выглядят следующим образом:

searchTagsTable 
    ID 
    tag 

dataTable 
    ID 
    title 
    desc 
    tagID 

Так колонна «TagID» в «DataTable» представляет собой запятую строку идентификаторов, указывающую на searchTagsTable.

Я хотел бы использовать возможности mysql для полнотекстового поиска для поиска заголовков, описаний и тегов.

Мне интересно: что считается «лучшим» решением в такой ситуации?

Должен ли я оставить структуру данных так, как она есть? Если да, то каким образом я должен структурировать sql для полнотекстового поиска всех трех столбцов - название, desc и tag?

Или было бы предпочтительнее просто избавиться от keywordsTable и иметь фактические метки, запятые в столбце «теги» в dataTable?

Заранее за вашу помощь.

Travis

ответ

0

Должен ли я оставить структура данных, как это? Если да, то каким образом я должен структурировать sql для полнотекстового поиска всех трех столбцов - название, desc и tag?

Это было невозможно. Индексы могут охватывать только столбцы одной таблицы.

Или было бы предпочтительнее просто избавиться от keywordsTable и иметь фактические метки, запятые в столбце «теги» в dataTable?

Это, безусловно, было бы самым простым решением. В настоящее время вы не получаете какой-либо выгоды от предоставления тегам собственной идентификации, поскольку вы не можете использовать внешние ключи и индексировать их.

Однако FULLTEXT индексирование MySQL не является идеальным для системы тегов:

  • по умолчанию, он не будет индексировать слова короче четырех букв;
  • по умолчанию у него много (много) столов, он не будет индексировать, что вы можете использовать для тегов;
  • он будет менее эффективным, чем нормальный индекс;
  • он работает только в MyISAM, что во всех других отношениях значительно хуже, чем у InnoDB. За исключением случаев, когда вам действительно нужно, вы сегодня не должны использовать MyISAM.

Вы можете исправить минимальную длину слова и стоп-слова, изменив конфигурацию MySQL. Это сделает ваши индексы намного большими. Это может быть приемлемым решением, если вы будете управлять базой данных везде, где будет развернуто ваше приложение, и если вы используете только теги как «лишние слова» в полнотекстовом поисковом корму, а не полную систему категоризации.

В противном случае ... с разделителями-запятыми что-либо в базе данных является подозрительным ИМО. Обычно лучше использовать таблицу соединений «один-ко-многим», чтобы выразить идею о том, что у одного объекта есть много тегов.Затем вы можете использовать простой индекс для поиска запросов вместо ограниченной схемы индексирования FULLTEXT, которая будет быстрее, надежнее и позволит вам использовать InnoDB и внешние ключи. например .:

dataTable 
    ID  (primary key) 
    title 
    desc 

dataTags 
    ID  (foreign key -> dataTable) 
    tagName (index this column) 

(Вы можете все еще есть tagID-> отображение тэгу, а на вершине этого, если вы хотите теги иметь независимую личность. Я не уверен, если он делает что-то полезное в вашем случае хотя.)

Если вам нужно получить список, разделенный запятой, из отношения «один ко многим», как указано выше, вы можете сделать это, используя функцию GROUP_CONCAT, специфичную для MySQL.

SELECT dataTable.*, GROUP_CONCAT(dataTags.tagName) 
FROM dataTable 
JOIN dataTags ON dataTags.ID=dataTable.ID 
GROUP BY dataTable.ID; 

Это оставляет полнотекстовое индексирование названия и desc. К сожалению, вам нужно разместить их в таблице MyISAM.

Общей альтернативой этому, которую вы могли бы также рассмотреть, было бы сохранение «канонических» копий в основной таблице (возможно, в ACID-безопасной таблице InnoDB) и сохранение отдельной копии всех заголовков, desc и теги вместе в таблице MyISAM, индексированной FULLTEXT, исключительно для полнотекстового поиска. Это означает, что вы должны делать дополнительное обновление каждый раз, когда вы меняете первичные данные (хотя, если вы терпите неудачу или должны отменить транзакцию, по крайней мере, это только относительно неважная поисковая приманка, которая сейчас не так), но преимущество заключается в том, что вы можете применить дополнительная обработка для него, такая как обработка прерывания и пунктуации, которую индексирует индексатор MySQL FULLTEXT сам по себе.

+0

Спасибо за подробный ответ, это очень полезно. Относительно этого: «Обычно лучше использовать таблицу соединений« один-ко-многим », чтобы выразить идею о том, что у одного объекта есть много тегов». Пожалуйста, несите меня. Я хочу быть уверенным, что я понимаю отношения, которые вы предлагаете между таблицами dataTable и dataTags. Предположим, у меня есть две различные строки в dataTable (ID 1, ID 2), которые я хотел бы связать с определенным тегом «mysql». Не могли бы вы объяснить, как будут выглядеть данные в таблице dataTags? Еще раз спасибо за вашу помощь, это очень ценится. Travis – Travis

+0

Да, у вас есть 'dataTags (ID, tagName)' values ​​'(1, 'mysql')' и '(2, 'mysql')'. «ID» - это только внешний ключ обратно к 'dataTable', а не первичный ключ сам по себе. Первичный ключ был бы равен ID и tagName. – bobince

+0

Замечательный. Спасибо за вашу помощь. -Travis – Travis

Смежные вопросы