Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/229.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 需要MySQL数据结构建议_Php_Sql_Mysql_Database Design_Full Text Search - Fatal编程技术网

Php 需要MySQL数据结构建议

Php 需要MySQL数据结构建议,php,sql,mysql,database-design,full-text-search,Php,Sql,Mysql,Database Design,Full Text Search,我需要一些关于如何组织有效和快速的文本搜索我的数据的建议 背景 我有一个应用程序(PHP),用户可以在其中组织文章并为此动态创建表单和字段。这意味着一篇文章可以例如具有类型、品牌、颜色属性,而另一篇文章可以例如具有类型、材质、颜色、内容属性。 用户基本上可以创建他喜欢的任意多个属性 然后我需要能够在这些“未知”属性中搜索和排序。 我还需要能够读回所有的属性,以防用户想要编辑文章 我的解决方案 我的第一个想法(也是目前为止唯一的想法)是使用全文索引将所有属性编码到一个文本字段中(需要是MyISAM

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

背景 我有一个应用程序(PHP),用户可以在其中组织文章并为此动态创建表单和字段。这意味着一篇文章可以例如具有类型、品牌、颜色属性,而另一篇文章可以例如具有类型、材质、颜色、内容属性。 用户基本上可以创建他喜欢的任意多个属性

然后我需要能够在这些“未知”属性中搜索和排序。 我还需要能够读回所有的属性,以防用户想要编辑文章

我的解决方案 我的第一个想法(也是目前为止唯一的想法)是使用
全文索引将所有属性编码到一个
文本
字段中(需要是MyISAM才能工作),如:

属性将获得前缀和/或后缀,以避免与属性中的值混淆。或者用JSON序列化属性

然后,我可以基于所选属性构建查询,如:

SELECT * FROM Articles a
WHERE Attribute LIKE '%__TYPE="2"%'
AND Attribute LIKE '%__Color="2"%'
如果某个属性为空,则不会包含该属性,这样就可以在具有特定属性集的所有项目上包含搜索,而不管其值如何

问题 不管有没有问题,我担心的是当数据库中充满数千篇文章时的搜索性能

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

Content=“MP3播放器,两个苹果,一本书:拉里·金”

假设我只想得到属性内容中有短语“Larry King”的行。我不认为我可以在同一个SQL问题中做到这一点,而不在所有有“Larry King”的行上进行匹配

我愿意接受任何关于我应该创建哪些表、字段和关系以实现所述目标的建议/讨论


谢谢。

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

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';

这并不能精确地解决问题的第二个问题,但它的性能要远远好于对数千行进行全文搜索。当然,您也可以在
属性值
字段上添加
全文
索引,以查询文本片段,如您的“Larry King”示例。

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

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';

这并不能精确地解决问题的第二个问题,但它的性能要远远好于对数千行进行全文搜索。当然,您也可以在
属性值
字段上添加
全文
索引,以查询文本片段,如您的“Larry King”示例。

Is it type=3始终具有品牌和颜色;type=2始终:材质、颜色、内容?始终会有一个“根”属性,但属性可以在多个级别上排列为树,因此此处的“type”可能会以不同的属性集/形式结束。type=3是否始终具有品牌和颜色;类型=2始终:材质、颜色、内容?始终会有一个“根”属性,但属性可以在多个级别上排列为树,因此这里的“类型”可能会以不同的属性集/形式结束。+1一个非常好的主意,我需要给它一些技巧,看看它是否能满足我的所有需求。我仍然欢迎更多的建议…@futureal,但表“attributes”将是巨大的,比实际的文章表大5到8倍。这种方法是否仍然比我最初的想法更有效?是的,非常有效。如果对行进行了适当的索引,那么拥有大量行不是问题。如果主表中有
n
行,并且您对特定属性运行了查询,那么它仍然只检查
n
行(最多)。它将只查看与查询相关的数据子集。我发现您的解决方案是这里的最佳选择,谢谢!没问题——这实际上是一个非常标准的SQL设计模式,因此了解和使用它是很好的。祝你好运!:)+这是一个非常好的主意,我需要给它一些建议,看看它是否能满足我的所有需要。我仍然欢迎更多的建议…@futureal,但表“attributes”将是巨大的,比实际的文章表大5到8倍。这种方法是否仍然比我最初的想法更有效?是的,非常有效。如果对行进行了适当的索引,那么拥有大量行不是问题。如果主表中有
n
行,并且您对特定属性运行了查询,那么它仍然只检查
n
行(最多)。它将只查看与查询相关的数据子集。我发现您的解决方案是这里的最佳选择,谢谢!没问题——这实际上是一个非常标准的SQL设计模式,因此了解和使用它是很好的。祝你好运!:)