Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails: mixing NOSQL & SQL Databases

I'm looking for the better way (aka architecture) to have different kind of DBs ( MySQL + MongoDB ) backending the same Rails app.

I was speculating on a main Rails 3.1 app, mounting Rails 3.1 engines linking each a different kind of DB ...

... or having a main Rails 3.0.x app routing a sinatra endpoint for each MySQL/MongoDB istance ...

Do you think it's possible ..., any idea or suggestions ?

I notice some other similar questions here, but I think that "mounting apps" is moving fast in Rails 3.1 / Rack / Sinatra and we all need to adjust our paradigms.

Thanks in advance Luca G. Soave

like image 653
Luca G. Soave Avatar asked May 29 '11 11:05

Luca G. Soave


People also ask

Can we use both SQL and NoSQL together?

Using a NoSQL database doesn't mean you can't use SQL; SQL is just the query language. In fact, NoSQL and SQL can be complementary. Some NoSQL databases use SQL to search the data.

Is Raven DB a NoSQL?

A World Class NoSQL Document Database RavenDB was the first NoSQL Database to become Fully Transactional.

Is NoSQL still relevant?

SQL Is Still the Top Language for Data Work In the complete dataset that Stack Overflow released here, we can see that among developers who work with data (including data scientists, data analysts, data engineers, etc.), about 70% use SQL, compared to 61.7% who use Python.


2 Answers

There's no need to completely over-complicate things by running two apps just to have two types of database. It sounds like you need DataMapper. It'll do exactly what you need out of the box. Get the dm-rails gem to integrate it with Rails.

In DataMapper, unlike ActiveRecord, you have to provide all the details about your underlying data store: what fields it has, how they map the attributes in your models, what the table names are (if in a database), what backend it uses etc etc.

Read the documentation... there's a bucket-load of code to give you an idea.

Each model is just a plain old Ruby object. The class definition just mixes in DataMapper::Resource, which gives you access to all of the DataMapper functionality:

class User
  include DataMapper::Resource

  property :id,            Serial
  property :username,      String
  property :password_hash, String
  property :created_at,    DateTime
end

You have a lot of control however. For example, I can specify that this model is not store in my default data store (repository) and that it's stored in one of the other configured data stores (which can be a NoSQL store, if you like).

class User
  include DataMapper::Resource

  storage_names[:some_other_repo] = 'whatever'

  # ... SNIP ...
end

Mostly DM behaves like ActiveRecord on steroids. You get all the basics, like finding records (except you never have to use the original field names if your model abstracts them away):

new_users = User.all(:created_at.gte => 1.week.ago)

You get validations, you get observers, you get aggregate handling... then get a bunch of other stuff, like strategic eager-loading (solves the n+1 query problem), lazy loading of large text/blob fields, multiple repository support. The query logic is much nicer than AR, in my opinion. Just have a read of the docs. They're human-friendly. Not just an API reference.

What's the downside? Well, many gems don't take into account that you might not be using ActiveRecord, so there's a bit more searching to do when you need a gem for something. This will get better over time though, since before Rails 3.x seamlessly integrating DM with Rails wasn't so easy.

like image 159
d11wtq Avatar answered Sep 22 '22 22:09

d11wtq


I dont fully understand your question., like

  1. what is the problem you are facing right now using mongo and MySQL in same app, and
  2. whats the reason for going multiple rails app dealing with different dbs.

Though am not an expert in ruby & rails(picked up few months ago), i like to add something here.

I am currently building the rails app utilizing both mongo and MySQL in the back end. Mongoid & ActiveRecord are the drivers. MySql for transactions and mongo for all other kind of data (geo spatial mainly). Its just straight forward. You can create different models inheriting from mongoid and activerecord.

class Item
  include Mongoid::Document
  field :name, :type => String
  field :category, :type => String
end

and

class User < ActiveRecord::Base
end

And you can query both the way same way (except complex sql joins, also mongoid has some addition querying patterns for Geo spatial kind of queries)

Item.where(:category => 'car').skip(0).limit(10)
User.where(:name => 'ram')

Its a breeze. But there are some important points you need to know

  1. Create your Active record models before the mongoid models. Once mongoid is activated (on rails g mongoid:config - mongoid.yml added) all the scaffolding , and generations works toward mongo db. Otherwise every time you need to delete the mongoid.yml before creating the Activerecord models
  2. And don't use mongoid in a relational way. i know mongoid provides lot of options to define realtions. Like Belongs_to relations stores the refernece id's in child documents. Its quite opposite to the mongo DbRef. Its greatly confusing when leaving the mongo idioms for the favour of active record feel. So try to stick with the document nature of it. Use embed and DbRef whenever necessary. (may be someone corrcet me if am wrong)

Still Mongoid is a great work. Its fully loaded with features.

like image 40
RameshVel Avatar answered Sep 20 '22 22:09

RameshVel