【问题标题】:Database SQL Compatibility数据库 SQL 兼容性
【发布时间】:2010-08-18 20:39:18
【问题描述】:

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

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

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

干杯 - 唐

【问题讨论】:

  • 我会在开始开发之前为工作选择正确的数据库 - 这对您来说不会那么尴尬,并且您将避免部署后的额外费用

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


【解决方案1】:

几个cmets:

  • 使用您要部署到的相同 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:ORM 不是灵丹妙药。 ORM 支持原生存储过程/等变得越来越普遍,因为尽管它们抽象了数据库交互,但这并不意味着抽象产生的 SQL 性能很好
【解决方案2】:

问题在于,特别是使用 GROUP BY MySQL 时会出错。如果您遗漏 MySQL 组中的列,则只需返回“某物”,接受结果可能不确定。

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

实际上,MySQL 中还有很多设置需要更改,以使其行为更加健全

您可能有兴趣阅读以下内容:

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

【讨论】:

    猜你喜欢
    • 2011-10-26
    • 2011-05-06
    • 2020-03-14
    • 1970-01-01
    • 2020-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多