2010-08-18 117 views
3

我將使用Sqlite3開發的Ruby on Rails應用程序部署到使用MySQL或PostgreSQL的服務器上。我很快發現,我大量使用的「group by」和「strftime」函數在生成逐月彙總報告時在各種數據庫之間工作方式不同或不兼容。數據庫SQL兼容性

我可以重構我的代碼來進行分組,求和和平均 - 但數據庫做得很好,並減少了服務器所需的處理!高級應用程序超越了簡單的選擇和連接。 ActiveRecord給了我們:group,但是DATABASES不是一致的。

所以我的問題是一個架構問題 - 有沒有人希望在Ruby on Rails中創建真正的「數據庫可移植」應用程序?我是否應該修改我的代碼庫以僅與MySQL一起工作並忘記其他數據庫?我應該修改我的代碼庫以進行高級分組,求和和平均嗎?

歡呼聲 - 唐

+0

我會選擇合適的數據庫開始開發之前的工作 - 這對你來說不會太尷尬,你可以在部署後避免額外費用 – 2010-08-18 20:54:12

回答

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子句。

+0

+1:ORM不是一個銀彈。對於ORM來說,支持本地存儲過程/ etc變得越來越普遍,因爲儘管它們抽象了數據庫交互,但它並不意味着抽象生成的SQL執行* well *。 – 2010-08-18 21:00:02

3

問題是,特別是對於GROUP BY MySQL它錯了。如果您在MySQL中忽略了來自該組的列,只需返回「某些」,即可接受結果可能不確定。

如果您的GROUP BY的結果不明確定義,您可以(應該)使用ONLY_FULL_GROUP_BY參數使MySQL拋出一個錯誤。

其實有很多更多的設置應該在MySQL的改變,使其表現得比較三立

您可能會感興趣閱讀本:

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