3

我正在开发一个用于教育研究的在线应用程序,我经常需要非常复杂的 SQL 查询:

  • 查询通常包括 5-20 个连接,通常多次连接到同一个表
  • SELECT 字段通常在派生字段/计算和 CASE 语句之间有 30-40 行高
  • 根据用户的权限和其他安全设置,在 PHP 中添加了额外的 WHERE 条件
  • 用户界面具有搜索和排序控件,可将自定义子句添加到 WHERE / ORDER / HAVING 子句。

目前,这个应用程序是基于 PHP + MYSQL + Jquery 构建的,用于移动部件。(这源于旧的 Dreamweaver 代码。)很快我们将从头开始重建应用程序,目的是整合、清理并为未来的扩展做好准备。虽然我对 PHP 很熟悉,但我正在学习一些关于 Rails 的知识并意识到,也许在更现代的框架上构建 2.0 版本会更好。但在我投入数小时的教程之前,我需要知道 Rails 查询系统(ActiveRecord?)是否能满足我们的查询需求。

这是我关心的一个查询挑战的示例。查询必须从表的 3+“实例”中进行选择,并从每个实例中获取可比较的信息:

SELECT p1.name AS my_name, pm.name AS mother_name, pf.name AS father_name
FROM people p1
    JOIN mother pm ON p1.mother_id = pm.id
    JOIN father pf ON p1.father_id = pf.id
    # etc. etc. etc.
WHERE p1.age BETWEEN 10 AND 16
# (selects this info for 10-200 people)

或者,一个类似的例子,更能代表我们的挑战。一个“原始数据”表多次连接到一个“编码选择”表,每个实例又必须查找与其存储的键关联的文本:

SELECT d.*, c1.coder_name AS name_c1, c2.coder_name AS name_c2, c3.coder_name AS name_c3, 
    (c1.result + c2.result + c3.result) AS result_combined,
    m_c1.selection AS selected_c1, m_c2.selection AS selected_c2. m_c3.selection AS selected_c3
FROM t_data d
    LEFT JOIN t_codes c1 ON d.id = c1.data_id AND c1.category = 1
        LEFT JOIN t_menu_choice m_c1 ON c1.menu_choice = m_c1.id
    LEFT JOIN t_codes c2 ON d.id = c2.data_id AND c2.category = 2
        LEFT JOIN t_menu_choice m_c2 ON c2.menu_choice = m_c2.id
    LEFT JOIN t_codes c3 ON d.id = c3.data_id AND c3.category = 3
        LEFT JOIN t_menu_choice m_c3 ON c3.menu_choice = m_c3.id 
WHERE d.date_completed BETWEEN ? AND ?
    AND c1.coder_id = ?

这些类型的连接很容易用纯 SQL 编写,当需要搜索过滤器和其他不同的元素时,几个 PHP 循环可以帮助将字符串拼凑成一个完整的查询。但是我还没有看到任何解决这种结构的 Rails / ActiveRecord 示例。如果我需要使用 find_by_sql("") 将每个查询作为纯 SQL 运行,那么与坚持使用我所知道的 PHP 相比,使用 Rails 可能不会有太大的改进。

我的问题是:ActiveRecord 是否支持表需要“昵称”的情况,例如上面的查询?主表也可以有别名吗?(在我的示例中,“p1”或“d”)我对 SELECT 语句中选择的字段有多少控制权?我可以为选定的字段创建别名吗?我可以在 SELECT 子句中进行计算并选择派生字段吗?CASE 语句呢?

如何设置指定连接表别名的 WHERE 条件?我的 WHERE 子句可以包括(使用上面的例子)“ WHERE pm.age BETWEEN p1.age AND 65 ”之类的东西吗?

这种复杂性不仅仅是偶尔出现的奇怪查询,它是应用程序的一个恒定且核心的特性(因为它目前的结构)。我关心的不仅仅是在 Rails 和 ActiveRecord 中编写这些查询是否“可能”;这是“Rails 方式”是否支持这种需求,因为我需要写很多这样的东西。因此,我正在尝试确定切换到 Rails 是否会带来比其价值更多的麻烦。

提前致谢!- 如果您在 Rails 中遇到类似的可怕查询,我很想听听您的故事及其结果。

4

1 回答 1

0

简短的回答是肯定的。Rails 通过各种类型的关系、范围等来处理这些需求的大部分。最重要的是正确地为您的应用程序建模以支持您将需要的查询类型和功能。如果某事难以向人解释,通常在 Rails 中很难做到。它经过优化以处理大多数“现实世界”类型的关系和任务,因此“异常”变得有点难以适应这个约定,后来变得更难以维护、管理、进一步开发、解耦等。底线是 rails 可以为您处理 sql 查询SomeObject.all_active_objects_with_some_quality,让您完全控制 sqlSomeObject.find_by_sql("select * from ...")以及execute("update blah set something=''...)介于两者之间的所有内容。

Rails 的优势之一是可以让您快速创建原型,我会创建您的模型概念,然后测试您拥有的最复杂的业务需求。这将使您快速了解什么是可能的和容易做的,以及您在开发中可能面临的瓶颈和潜在问题。

于 2012-10-12T20:07:56.497 回答