Требуется совет по структуре данных MySQL - PullRequest
0 голосов
/ 12 января 2011

Мне нужен совет относительно того, как организовать свои данные для эффективного и быстрого текстового поиска.

Фон

У меня есть приложение (на PHP), где пользователь может организовывать статьи и динамически создаватьформы и поля для этой цели.Это означает, что одна статья может, например, иметь атрибуты Тип, Бренд, Цвет, а другая статья может, например, иметь атрибуты Тип, Материал, Цвет, Содержание.Пользователь может создать столько атрибутов, сколько ему нравится ...

Тогда мне нужно будет найти и отсортировать эти "неизвестные" атрибуты.Мне также нужно иметь возможность считывать все атрибуты в том случае, если пользователь хочет редактировать статью.

Мое решение

Моя первая идея (и пока единственная идея) заключается в кодированиивсе атрибуты в одном поле TEXT с индексом FULLTEXT (для работы должен быть MyISAM), например:

__Type="3",__Brand="Nokia",__Color="6"
__Type="2",__Material="7",Color="2",Content="MP3 Player,2 Apples, 1 book: Larry King"

Атрибуты получат префикс и / или постфикс, чтобы их не перепутатьсо значениями в атрибутах.Или сериализуйте атрибуты с помощью JSON.

Затем я могу построить запрос на основе выбранных атрибутов, таких как:

SELECT * FROM Articles a
WHERE Attribute LIKE '%__TYPE="2"%'
AND Attribute LIKE '%__Color="2"%'

Если атрибут пустой, он не будет включен, и это сделает егоМожно включить поиск по всем статьям, для которых задан определенный атрибут, независимо от его значения.

Проблема

Проблема или нет, меня беспокоит производительность поиска при работе с базой данныхзаполнен тысячами статей.

Другая проблема также заключается в поиске определенного слова в определенном атрибуте, например:

Content = "MP3-плеер, 2 яблока, 1 книга:Ларри Кинг "

Допустим, я хочу получить только те строки, где атрибут Content где-то содержит фразу" Ларри Кинг ".Я не думаю, что смогу сделать это в одном и том же вопросе SQL, не найдя совпадения во всех строках, где где-то есть «Ларри Кинг».

Я открыт для любых предложений / обсуждений относительно таблиц,поля и отношения, которые я должен создать для достижения поставленных целей.

Спасибо.

1 Ответ

4 голосов
/ 12 января 2011

Если вы будете часто искать значение определенного атрибута, почему бы не сделать эти атрибуты своими столбцами в таблице? Или, если вы хотите более гибкую структуру, создайте вторую таблицу, например:

CREATE TABLE attributes (
 my_id int unsigned not null default 0,
 attribute_key varchar(255) not null default '',
 attribute_value varchar(255) not null default '',
 KEY (my_id),
 KEY (attribute_key),
 KEY (attribute_value)
);

В этом случае поле my_id является первичным ключом вашей основной таблицы. Так что вместо того, чтобы сериализовать строку вроде:

__Type="2",__Material="7",Color="2",Content="MP3 Player,2 Apples, 1 book: Larry King"

Вместо этого вы должны создать несколько строк, например:

INSERT INTO attributes VALUES (1, 'Type', '2');
INSERT INTO attributes VALUES (1, 'Color', '2');
INSERT INTO attributes VALUES (1, 'Content', 'MP3 Player,2 Apples, 1 book: Larry King');

И тогда вы бы сформулировали свой поисковый запрос как:

SELECT * FROM mytable 
LEFT JOIN attributes ON mytable.my_id = attributes.my_id 
WHERE attributes.attribute_key = 'Type' AND attributes.attribute_value = '2';

Это точно не решит вторую проблему вашего вопроса, но будет работать намного лучше, чем полнотекстовый поиск по тысячам строк. Затем вы можете, конечно, добавить индекс FULLTEXT в поле attribute_value, а также запросить его для фрагментов текста, таких как ваш пример "Ларри Кинг".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...