数据库SQL兼容性

时间:2010-08-18 20:39:18

标签: mysql ruby-on-rails database postgresql sqlite

我正在将使用Sqlite3开发的Ruby on Rails应用程序部署到具有MySQL或PostgreSQL的服务器。我很快发现,我正在大量使用“group by”和“strftime”函数来生成按月汇总报告,这些函数在各种数据库之间的工作方式不同或不兼容。

我可以重构我的代码来进行分组,求和和平均 - 但数据库做得很好,减少了服务器所需的处理!高级应用程序超越了简单的选择和加入。 ActiveRecord为我们提供:group,但DATABASES并不一致。

所以我的问题是架构问题 - 有人希望在Ruby on Rails中创建真正的“数据库可移植”应用程序吗?我应该修改我的代码库以仅使用MySQL而忘记其他数据库吗?我应该修改我的代码库来进行高级分组,求和和平均吗?

欢呼 - 唐

2 个答案:

答案 0 :(得分:4)

几条评论:

  • 使用您要部署的相同RDBMS品牌和版本进行开发和测试。

  • 编写可移植的SQL代码很难,因为供应商拥有所有这些非标准的额外功能和特性。例如,strftime()不是ANSI SQL标准的一部分。解决此问题的唯一方法是为您使用的每个数据库使用RTM,并了解它们共有的功能。有时它们具有不同名称的功能,您可以以类似的方式使用它们。这方面没有捷径 - 你必须学习手册。

  • 所有数据库都支持GROUP BY,但SQLite和MySQL对某些用法比标准ANSI SQL(以及遵循该标准的所有其他品牌数据库)更宽松。具体来说,在GROUP BY子句中,您必须将选择列表中不属于分组函数的每一列命名。

    以下两个例子是正确的:

    SELECT A, B, COUNT(C) FROM MyTable GROUP BY A, B;
    SELECT A, COUNT(C) FROM MyTable GROUP BY A;
    

    但下一个是错误的,因为B每组有多个值,并且它应该在给定行中返回哪个值是不明确的:

    SELECT A, B, COUNT(C) FROM MyTable GROUP BY A;
    
  • 没有框架可以写出真正的可移植SQL。 Rails的ActiveRecord仅在非常简单的情况下解决了这个问题。实际上,ActiveRecord有助于解决您提供的示例 ,特定品牌的功能以及非标准的GROUP BY子句。

答案 1 :(得分:3)

问题是,特别是GROUP BY MySQL做错了。如果你遗漏了MySQL中的列,只需返回“某些东西”,接受结果可能是不确定的。

如果你的GROUP BY的结果没有明确定义,你可以(应该)使用ONLY_FULL_GROUP_BY参数使MySQL抛出错误。

实际上还有很多设置应该在MySQL中进行更改以使其表现得更加明智

您可能有兴趣阅读此内容:

http://www.slideshare.net/ronaldbradford/mysql-idiosyncrasies-that-bite-201007