Para a apresentação do meu TCC, precisava de algo concreto para mostrar como utilizar o CouchDB. Apesar de utilizá-lo na empresa onde trabalho (ainda em testes), não podia levar os dados proprietários para a apresentação. Então, tive a idéia de pegar uma base de dados TPC-H, que é utilizado como benchmark em sistemas de apóio a decisão.
Sei que a modelagem de um banco TPC-H é o completo inverso do que prega um banco livre de esquema. Porém, isso serviu para demonstrar como utilizar um documento dentro do Couch, onde denormalizei a estrutura de Customer (nacionalidade e região) e mantive a estrutura do LineItem normalizada. Ajudou muito para demonstrar como estender o conjunto de dados, exemplificar a utilização de revisões e outras coisas da apresentação.
Segue o código Ruby que utilizei para realizar a transformação:
# # # # # Este script transforma um banco de dados TPC-H em um documento CouchDB, onde # Order é a principal entidade e leva somente duas entidades filhas: Customer (denormalizado) # e LineItem (que ainda está normalizado). # # Utilizei uma requisição HTTP manual (ao invés de uma API Rest) para ter acesso ao CouchDB # com o objetivo de estudar os detalhes desta conexão, e poder manipular melhor o seu envio. # # Livre para utilizar! :) # # Leonardo Eloy # http://leonardoeloy.com require 'rubygems' require 'postgres-pr/connection' require 'json' require 'net/http' # Garante que datas são levadas de forma correta e número são armazenados # como números, não como String. def jsonfy(ary, fields) l = {} fields.each_with_index { |f,idx| if (ary[idx].to_s.to_f > 0.0 and not f.name.to_s.include?("date")) l.store(f.name, ary[idx].to_s.to_f) else l.store(f.name,ary[idx]) end } return l end conn = PostgresPR::Connection.new('tpch', 'postgres', 'senha', 'tcp://localhost:5432') linha = conn.query("select * from orders") uri = URI.parse("http://localhost:5984/tpch/") linha.rows.each { |r| hash = jsonfy(r, linha.fields) hash.store("type", "order") # fetch customer l_cliente = conn.query("select c_phone,c_name,c_address,c_mktsegment,c_comment,c_acctbal,c_custkey,n_name as nation,r_name as region from customer, nation, region where c_nationkey = n_nationkey and r_regionkey = n_regionkey and c_custkey = #{hash['o_custkey']}") cliente = jsonfy(l_cliente.rows[0], l_cliente.fields) cliente.store("type", "customer") hash.store("customer", cliente) # fetch lineitem l_lineitem = conn.query("select * from lineitem where l_orderkey = #{hash['o_orderkey']}") lineitem = [] l_lineitem.rows.each { |rl| li = jsonfy(l_lineitem.rows[0], l_lineitem.fields) li.store("type", "lineitem") lineitem << li } hash.store("lineitem", lineitem) Net::HTTP.start(uri.host, uri.port) do |http| headers = {'Content-Type' => 'application/json'} put_data = "#{hash.to_json}" response = http.send_request('POST', uri.request_uri, put_data, headers) puts "Response #{response.code} #{response.message}: #{response.body}" end }







