在我的一个MySQL表中,我有以下列:
Skills varchar(80)
Industry varchar(40)
Address varchar(100)
技能可能包括以下文字: C / C ++ , MS Office , Linux 等。 行业可能包括以下文本:财务, IT 等。 地址包含完整的邮政地址以及城市名称。没有单独的城市列。
在我的网页上,我有搜索框,用户可以在其中键入每个列的关键字。我使用SQL查询,如下所示:
Select studentname where skills like '%...%';
我想改善搜索结果和性能。例如,用户可能已输入 Linex 而非 Linux 等技能。所以,我的搜索应该返回约。匹配。
请告诉我如何使搜索更准确并提高性能。目前,我已在skills
,address
和industry
列上定义了索引。但表现不太好。
表引擎是InnoDB。
修改
问题是我们从各个机构收到预先填写的MS Excel表格。我们的.NET应用程序读取Excel工作表的列值并将其存储在远程数据库中。对于拆分表,我们需要更改我们的应用程序。
答案 0 :(得分:9)
SQL子句
like '%...%'
如果您想从数据库中获得性能,是您可以做的最具破坏性的事情。
你真正应该做的是确保技能,行业等内容被分解为具有固定值的其他表(如'C','C ++','SQL '等等。)
然后在人和技能之间有一个多对多的表。例如:
People:
PersonId primary key.
Other person details.
Skills:
SkillId primary key.
SkillName.
Other skill details.
PeopleSkills:
PersonId references People(PersonId).
SkillId references Skills(SkillId).
primary key (PersonId,SkillId).
index on (SkillId).
如果您只允许从“技能”表中输入搜索词,那么这种布局将大大提高查询的速度和使得不正确的数据输入成为不可能(没有'Linex'可能在您的意思'Linux',仅仅因为'Linex'不在技能表中。)
我在表格设计中遵循的一条无懈可击的规则是:如果您尝试从列中提取一些信息,那么该信息应放在自己的列中。人们遭受的性能问题的数量,因为他们创建了一个包含逗号分隔值的列的表(他们想要从该列中提取单个值)应该证明这一点。
必须确保所有技能和行业都在一个单独的表格中的缺点将通过提高速度和准确性来弥补。数据库应始终设计为第三范式。如果您了解后果(并通过使用触发器或计算列减轻不正确数据的可能性),则可以将性能退回到2NF,但这很少是必要的。
答案 1 :(得分:4)
我建议您使用indice进行全文搜索。 InnoDB不支持全文,但您可以使用Apache Lucene,Zend_Search_Lucene(PHP)等外部引擎
答案 2 :(得分:1)
另一种解决方案是使用不同的搜索技术。看看Zend Search Lucene框架。这是基于Lucene的JAVA版本。
它有更好的搜索内容的方式。您可以搜索单个单词,短语,范围,模糊,接近,提升,突出显示等。
但是,您的搜索内容也需要存储为数据库中的平面文件,您需要保持内容同步。然而,说搜索的力量非常值得。它也很快,非常快。
Google:php lucene zend获取更多信息。
答案 3 :(得分:0)
仅为此在表格中分离技能,然后使用Id连接到当前表格,如下所示:
Skills: Id, Name
Skills_YourTable: Skills_Id, YouTable_Id
YouTable: Id, another fields.
EX:
Select y.fields
from YourTable as y
join Skills_YourTable as sy
join Skills as s
where s.Name = 'MS Office'
答案 4 :(得分:0)
正如其他海报提到的那样,首先规范化您的数据库。
要在搜索时处理拼写错误,请查看SOUNDS LIKE
答案 5 :(得分:0)
您可能想尝试sphinx