需要MySQL数据结构建议

时间:2011-01-12 05:42:22

标签: php sql mysql database-design full-text-search

我需要一些关于如何组织数据以进行有效和快速文本搜索的建议。

背景

我有一个应用程序(在PHP中),用户可以在其中组织文章并为此目的动态创建表单和字段。这意味着一篇文章可以例如具有Type,Brand,Color属性和另一篇文章,例如可以将Type,Material,Color,Content作为属性。 用户基本上可以创建他喜欢的任何属性......

然后我需要能够在这些"未知"之间进行搜索和排序。属性。 我还需要能够在用户想要编辑文章的情况下回读所有属性。

我的解决方案

我的第一个想法(迄今为止唯一的想法)是将所有属性编码为一个带有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"%'

如果属性为空,则不会包含该属性,这样就可以对所有具有特定属性集的文章进行搜索,无论其值如何。

问题

问题与否,我担心的是当数据库充满数千篇文章时的搜索性能。

另一个问题也是搜索特定属性中的特定单词,例如:

内容=" MP3播放器,2个苹果,1本书:拉里金"

让我们说我只想获得属性内容包含短语" Larry King"某处。我不认为我可以在同一个SQL问题中做到这一点,而不会在所有有" Larry King"某处。

对于我应该创建哪些表格,字段和关系来实现所解释的目标,我可以提出任何建议/讨论。

谢谢。

1 个答案:

答案 0 :(得分:4)

如果您经常搜索特定属性的值,为什么不将这些属性设置为表中的自己的列?或者,如果您想要更灵活的结构,请创建第二个表格,如:

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索引,以便查询文本片段,例如“Larry King”示例。