动态搜索多个sql表的需求模式
我正在寻找一种用于对多个表执行动态搜索的模式。
我无法控制旧式(设计欠佳)的数据库表结构。
考虑一个类似于简历搜索的场景,在该场景中,用户可能希望对简历中的任何数据执行搜索,并获取与他们的搜索条件相匹配的简历列表。可以随时搜索任何字段,并且可以与一个或者多个其他字段组合使用。
实际的sql查询是根据要搜索的字段动态创建的。我发现的大多数解决方案都涉及复杂的if块,但是我不禁认为必须有一个更优雅的解决方案,因为到目前为止这必须已经解决了。
是的,所以我已经开始动态地在代码中构建sql了。看起来真令人讨厌。如果我真的尝试支持请求的功能来查询任何表中任何字段的任何组合,那么它将成为一组大量的if语句。颤抖
我相信我读到COALESCE仅在数据不包含NULL的情况下才有效。那是对的吗?如果是这样,那就别走了,因为我到处都是NULL值。
解决方案
回答
据我了解(我也是针对可怕的旧数据库编写的),没有动态的WHERE子句。尚未解决。
就个人而言,我更喜欢在代码中生成动态搜索。使测试方便。注意,在代码中创建sql查询时,请勿在用户输入中串联。使用@variables!
唯一的选择是使用COALESCE运算符。假设我们有下表:
Users ----------- Name nvarchar(20) Nickname nvarchar(10)
并且我们可以选择搜索姓名或者昵称。以下查询将执行此操作:
SELECT Name, Nickname FROM Users WHERE Name = COALESCE(@name, Name) AND Nickname = COALESCE(@nick, Nickname)
如果我们不想搜索某些内容,则只需输入一个null即可。例如,为@name传递" brian",为@nick传递null会导致对以下查询进行评估:
SELECT Name, Nickname FROM Users WHERE Name = 'brian' AND Nickname = Nickname
合并运算符将null转换为一个身份评估,该评估始终为true,并且不影响where子句。
回答
搜索和规范化可能会相互矛盾。因此,大概第一件事就是获得某种"视图",该视图显示所有可以使用单个键作为单行进行搜索的字段,从而获得简历。那么我们可以在其前面添加诸如Lucene之类的内容,以为这些行提供全文索引,有效的方法是,在此视图中要求它输入" x",然后它会返回给我们键。这是一个很好的解决方案,Joel亲自在IIRC的前两个月内的播客中推荐了它。
回答
我们需要的是SphinxSearch(用于MySQL)或者Apache Lucene。
就像我们在示例中所说的那样,让我们想象一个由多个字段组成的简历:
- 项目清单
- 姓名,
- 承认,
- 教育(可能是一张桌子)或者
- 工作经验(可以增长到自己的表中,其中每一行代表以前的工作)
因此,使用WHERE在所有这些字段中快速搜索单词成为一个包含多个JOINS的非常长的查询。
相反,我们可以更改参考框架,将整个简历视为一个文档,而我们只想搜索该文档。
这就是Sphinx Search之类的工具所处的位置。他们创建"文档"的全文索引,然后我们可以查询sphinx,它会带我们返回在数据库中找到记录的位置。
确实很好的搜索结果。
不必担心此工具不属于RDBMS,它将为我们节省很多麻烦,因为对于该应用程序,使用适当的模型" Documents"与不正确的模型" TABLES"相对应。