Rails + SQLServer 航海日誌:とりあえず動かしてみた

今は仕事で、今までRails + MySQLで稼働しているアプリケーションのデータベースをSQLServerに移行している。

進捗状況としては開発環境上では「ひとまずちゃんと動いているように見える」ということで、 まだProductionで運用しないが、大丈夫そうな気もしている。

どこまで需要があるかも分からないが、 日本語での知見もほとんど見当たらないのでとりあえず書き残しておく。

前提条件

開発環境

  • 普段のPCはMac
  • Ruby 2.2.x or 2.3.x
  • Rails 4.2.x
  • MySQL 5.6.xから移行する事になっている
  • 普通の小規模Railsアプリケーション
  • 移行先はAzureのSQLServerの予定

ちなみに生のSQLも1つしか書いて無いと思うし、 Arelもほとんど使わずに済むくらいには難しいことはしてない。 プロダクトも現状は大規模な案件では動いてない。

自分のスキルについて

  • Rails 2年目くらい
  • SQL Serverは未経験
  • そこまでSQLに詳しくない・難しいSQL書けないし、書きたくない。

SQLServerへの対応に当たって使用したGem

active_record_adapter

github.com

tiny_tds

github.com

  • tiny_tdsを使えるようにするには別途freetdsをインストールする必要がある。

雑なQ&A

ActiveRecordのAdapterあるけど、まともにつかえるの??

  • starもとりあえず700超えているし、過信は禁物かもだが、まともに動いてる感ある。
  • ただし、ActiveRecordのwhereで文字列を検索するときにエスケープを意識しなければいけないシーンが他のDBシステムよりは増える。(これはActiveRecordの問題ではないが…)
  • AzureのSQLServerを使用する場合は、database.ymlに azure: trueって設定しとくくらい。

Macでしょ、開発用DBとかどうした??

  • AzureでBasicのDB立ててそこでやってる。 月に500円で安心を手に入れられるならそっちのほうがいいと思ってる。 開発環境がMacだし、Windowsでやるにしても、構築めんどくさくないこっちの方をおすすめしたい。 どうしてもオフライン環境下でも開発したい人はローカルにDB構築すればいいと思う。

  • そこまでちゃんとSpec書いているわけではないけど、 Specで使うためのテストDBもAzure使ってやっているのだけど、なんだかテストが遅くて困ってる。 ネットワークの問題なのか、DBのサイズの問題なのかまだ切り分けできてない。 こういうときにSQLServer on Linuxはいいかもしれない。

SQLServer on Linux/Macはどう??

  • まだ試してない。枯れた技術になりそうだったら、テストで使う可能性はあるかも。

UTF-8や日本語の文字化けの問題は??

  # これはNプレフィックスがないまま実行されるので、失敗する
  Subscription.where('status = "success"')
  # これらは実行されるSQLにちゃんとNプレフィックスがつくので動く
  Subscription.where(status: "success")
  Subscription.where("status = N'success'")
  • こういう部分はアプリケーションのコードだけではなく、ActiveRecordを扱ってるGemがある場合は、逐一チェックしたほうがいいかも。

Rails 5は??

  • Masterブランチでは動かない。(2016/12/02時点)
  • rails5というブランチがあり、そちらでは動くらしいが、まだMasterにMergeされてない。(未検証)

おすすめのSQL GUIクライアントアプリ for Mac

とりあえずRubyMine使っている。 自分はよく訓練されたSQL使いではないので、GUIクライアントはあったほうが良かった。 今までMySQLを使っていたので、同じGUIクライアントで使えたのは本当に大きい。 ただ若干参照できない部分があったりするので、 細かいことをしようとし始めると融通がきかない部分があったりするかも。 他のGUIクライアントはものすごく高いか、画面が残念のどちらかだと思っている。 とりあえずJetBrain製品使いましょう。

雑な感想

  • やる前はぶっちゃけ悲観的な感じだったけど、ActivreRecordのAdapterから実装するという最悪の状況は免れそう。(まだドハマりしてないだけかも…)
  • というかAdapterがいい感じに動いている。
  • Migrationも少し書き直しはあると思うけど(bigintとかその辺)、まぁだいたい大丈夫そう。
  • SQLたくさん書いてそうな大規模な案件では大変そうな感はある。
  • とはいえMySQLにはないSQLServer独特のものとかもあるので、SQLServerについての勉強はもっと必要になる。
  • Rails + SQLServerでの開発もメリットがある場合は選択肢のひとつになると思う。
  • AzureのSQLServerの場合、無停止でインスタンスサイズを変更できるのはメリットだと思う。

現時点で気をつけるポイントまとめ

  • どんなに簡単なwhere文でもテストを書いておいたほうが安心できる。
  • ちゃんと普段から本番環境と同じDBシステムを使うべき。
  • 手でNプレフィックスつけるのは面倒だし、うまくActiveRecordを使おう。

TODO

  • これまでは新規で動かしてみた結果なので、ちゃんとMySQL => SQLServerデータ移行できるかどうか
  • MySQLSQLServerユニークインデックスの仕様に違いがあったのでそのへんの対処法を書く(参考にしたQiitaの記事のURLがどっかいったのであとで探す…)
  • これだとつらそうとかいう感想もありそうでアレなので、そのうち採用するメリットについてしっかり書いておきたい。

そこまでSQLServerRailsに詳しくないので、詳しい方々のマサカリをお待ちしております。