【问题标题】:Need Pattern for dynamic search of multiple sql tables动态搜索多个 sql 表的需要模式
【发布时间】:2010-09-05 19:10:12
【问题描述】:

我正在寻找一种对多个表执行动态搜索的模式。

我无法控制旧的(设计不佳的)数据库表结构。

考虑类似于简历搜索的场景,其中用户可能希望对简历中的任何数据执行搜索,并获取与其搜索条件匹配的简历列表。任何字段都可以随时与一个或多个其他字段组合进行搜索。

实际的 sql 查询是根据搜索的字段动态创建的。我发现的大多数解决方案都涉及复杂的 if 块,但我不禁认为必须有一个更优雅的解决方案,因为现在这必须是一个已解决的问题。


是的,所以我开始了在代码中动态构建 sql 的路径。看起来很可怕。如果我真的尝试支持查询任何表中任何字段的任何组合的请求能力,这将是一组 MASSIVE 语句。 颤抖


我相信我读到 COALESCE 仅在您的数据不包含 NULL 时才有效。那是对的吗?如果是这样,那就不行,因为我到处都有 NULL 值。

【问题讨论】:

    标签: sql database-design design-patterns dynamic-sql table-structure


    【解决方案1】:

    据我所知(而且我也是针对可怕的遗留数据库编写的人),没有动态 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
    

    coalesce 运算符将 null 转换为身份评估,这始终为真,不会影响 where 子句。

    【讨论】:

      【解决方案2】:

      搜索和规范化可能相互矛盾。因此,第一件事可能是获得某种“视图”,它显示所有可以作为单行搜索的字段,只需一个键即可获得简历。然后你可以在前面扔Lucene 之类的东西,为你提供这些行的全文索引,工作方式是,你在这个视图中向它询问“x”,它会返回给你密钥。这是一个很好的解决方案,并在 IIRC 的前 2 个月内由 joel 本人在播客上推荐。

      【讨论】:

        【解决方案3】:

        您需要的是 SphinxSearch(用于 MySQL)或 Apache Lucene

        正如您在示例中所说,让我们想象一个由多个字段组成的简历:

        • 列表项
        • 姓名,
        • 地址,
        • 教育(这可能是一个单独的表)或
        • 工作经验(这可以增长到自己的表格,其中每一行代表以前的工作)

        因此,使用 WHERE 在所有这些字段中搜索单词很快就会变成一个包含多个 JOINS 的非常长的查询。

        相反,您可以更改参考框架,将整个简历视为单个文档,而您只想搜索该文档。

        这就是 Sphinx Search 等工具的作用所在。他们会为您的“文档”创建一个全文索引,然后您可以查询 sphinx,它会告诉您在数据库中找到该记录的位置。

        非常好的搜索结果。

        不用担心这个工具不是您的 RDBMS 的一部分,使用合适的模型“文档”与不正确的模型“表”相比,该应用程序可以省去很多麻烦。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-06-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多