If you want to do fast analysis on very large datasets or you need to extract a small sliver of data from a very wide table or set of tables, check out the free version of the Info-Bright MySql data storage engine. The non-commercial version is called ICE (InfoBright Community Edition.) http://www.infobright.org It's intended for data warehouse and archival applications.
A crucial point about ICE is that it's read-only. It doesn't support insert, delete or update. You can create a schema (with some restrictions,) and you can do any other SQL supported by MySql. What this means is that to get data into ICE tables you have to use 'load data infile'. The commercial version doesn't have that restriction.
So putting your Rails app on ICE is probably out. But what if you want to use Rails migrations to generate a schema with ICE or otherwise use Ruby Active-Record to access an ICE database?
I downloaded the Linux 64 bit version of ICE from the InfoBright website and set it up; it was basically a stand-alone version of MySql with the InfoBright storage engine built in. I was able to connect to it using the standard MySql database adapter, but attempting to re-create a schema from my Migration classes resulted in errors from MySql. It turns out ICE, because it doesn't support 'insert', doesn't allow primary keys or auto_increment type columns. In a read-only situation this is okay, but it means your old DDL won't work.
I needed to replace the DDL generated in the 'create_
table' method in migrations with something that ICE would accept. In every ActiveRecord database adapter class there's a definition of the data types for the database system in question. MySql looks like
def native_database_types #:nodoc:
{
:primary_key => “int(11) DEFAULT NULL auto_increment PRIMARY KEY”.freeze,
:string => { :name => “varchar”, :limit => 255 },
:text => { :name => “text” },
:integer => { :name => “int”, :limit => 4 },
:float => { :name => “float” },
:decimal => { :name => “decimal” },
:datetime => { :name => “datetime” },
:timestamp => { :name => “datetime” },
:time => { :name => “time” },
:date => { :name => “date” },
:binary => { :name => “blob” },
:boolean => { :name => “tinyint”, :limit => 1 }
}
end
We need to change the 'primary_key'. (And raise an exception on 'binary' -- InfoBright doesn't support blobs.) Since ICE is really just MySql with some restrictions we could extend the MySql database adapter creating an ICE adapter and over-ride the above method. It turns out to be a bit harder than that, but not much.
Below is the bare minimum you need to get the ICE adapter running. This version doesn't trap invalid DDL or unsupported SQL but it will work with simple migrations.
require 'active_record/connection_adapters/abstract_adapter'
require 'active_record/connection_adapters/mysql_adapter'
module ActiveRecord
class Base
def self.ice_connection(config)
config = config.symbolize_keys
host = config[:host]
port = config[:port]
socket = config[:socket]
username = config[:username] ? config[:username].to_s : ‘root’
password = config[:password].to_s
if config.has_key?(:database)
database = config[:database]
else
raise ArgumentError, “No database specified. Missing argument: database.”
end
require_mysql
mysql = Mysql.init
mysql.ssl_set(config[:sslkey], config[:sslcert], config[:sslca], config[:sslcapath], config[:sslcipher]) if config[:sslkey]
ConnectionAdapters::IceAdapter.new(mysql, logger, [host, username, password, database, port, socket], config)
end
end
module ConnectionAdapters
class IceAdapter < MysqlAdapter
def initialize(connection, logger, connection_options, config)
puts “connecting to ICE”
super(connection, logger, connection_options, config)
end
# Info-Bright Community Edition (BrightHouse engine)
def adapter_name
‘Ice’
end
def ice_connection
puts “Connecting to ICE”
super.mysql_connection
end
def native_database_types #:nodoc:
puts “** In BrightHouse SQL types”
{
:primary_key => “int auto_increment”,
:string => { :name => “varchar”, :limit => 255 },
:text => { :name => “text” },
:integer => { :name => “int”, :limit => 4 },
:float => { :name => “float” },
:decimal => { :name => “decimal” },
:datetime => { :name => “datetime” },
:timestamp => { :name => “datetime” },
:time => { :name => “time” },
:date => { :name => “date” },
:binary => { :name => “blob” },
:boolean => { :name => “int”, :limit => 1 }
}
end
end
end
end
You put this file alongside the other database adapter files in active_record and in your database.yml config use "adapter"=>'Ice'.