我需要一些关于如何组织数据以进行有效和快速文本搜索的建议。
我有一个应用程序(在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"某处。
对于我应该创建哪些表格,字段和关系来实现所解释的目标,我可以提出任何建议/讨论。
谢谢。
答案 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”示例。