我正在将我使用 Sqlite3 开发的 Ruby on Rails 应用程序部署到使用 MySQL 或 PostgreSQL 的服务器上。我很快发现,我大量使用来生成按月汇总报告的“group by”和“strftime”函数在不同数据库之间的工作方式不同或不兼容。
我可以重构我的代码来进行分组、求和和平均 - 但数据库在这方面做得非常好,减少了服务器所需的处理!高级应用程序超越了简单的选择和加入。 ActiveRecord 为我们提供了 :group,但数据库并不一致。
所以我的问题是架构问题——有人希望在 Ruby on Rails 中创建真正的“数据库可移植”应用程序吗?我是否应该修改我的代码库以仅使用 MySQL 而忘记其他数据库?我应该修改我的代码库来进行高级分组、求和和平均吗?
干杯 - 唐
最佳答案
几点评论:
使用您要部署到的相同 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 子句。
关于mysql - 数据库 SQL 兼容性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3516481/