Sequelмеханизм доступа к БД, написанный на Ruby         Piter.rb #3, март 2011                           Алексей Найден   ...
Примеры• Выполнение простых операций над  большими объемами данных: • Биллинг • Отчеты• Работа с legacy БД
ORM vs. Recordset•   ORM (O/RM) — Object-Relational Mapping.    Отображение реляций БД на ООП-сущности    (классы, объекты...
Object Query vs. Raw SQL• Object Query — генерация  запроса к БД, посредством вызова  методов  User.find(:all, :conditions ...
Основная дилемма• Скорость + Гибкость• Простота + Универсальность
Пример из реального мира     SELECT fc.fieldvalue AS category, fs.fieldvalue AS ticket_type, u.fullname as username,t.isphon...
Реализация с помощью     ActiveRecordSwticket.find(:all, :select => ‘fc.fieldvalue AS category, fs.fieldvalue AS ticket_type,...
Gem Sequel• http://sequel.rubyforge.org/• gem install sequel• require ‘rubygems’ # Чистый Ruby  require ‘sequel’• gem ‘seq...
Возможности•   RecordSet / ORM•   Raw SQL / Object Query•   Thread-safe, connection pooling•   Работает с ADO, JDBC, MySQL...
Работа с Sequel
Dataset I•   chanmems = DB[:mems].filter(:source => 4chan.org)    chanmems.avg(:uses)    SELECT avg(uses) FROM mems WHERE s...
Dataset II•   my_posts = posts.filter(:category => ruby, :author => david)    my_posts = posts.filter(:stamp => (Date.today ...
Модели•   class Post < Sequel::Model•   post = Post[123]    post = Post[:title => ‘Hello’]•   post.title #=> ‘Hello’    po...
Чистый SQL•   DB.fetch("SELECT * FROM albums WHERE name LIKE :pattern", :pattern=>A%) do |row|      puts row[:name]    end...
Сравнение с        DataMapper• DataMapper — только ORM• Даже в ORM другая философия: DM  модель > БД, Sequel БД > модель• ...
Производительность
Вопросы?• alexey.nayden@gmail.com• twitter.com/alexnayden• http://evilmartians.ru
Upcoming SlideShare
Loading in …5
×

Sequel — механизм доступа к БД, написанный на Ruby

2,805 views
2,588 views

Published on

Доклад с Piter.rb #3

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,805
On SlideShare
0
From Embeds
0
Number of Embeds
7
Actions
Shares
0
Downloads
8
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Sequel — механизм доступа к БД, написанный на Ruby

    1. 1. Sequelмеханизм доступа к БД, написанный на Ruby Piter.rb #3, март 2011 Алексей Найден EvilMartians.ru
    2. 2. Примеры• Выполнение простых операций над большими объемами данных: • Биллинг • Отчеты• Работа с legacy БД
    3. 3. ORM vs. Recordset• ORM (O/RM) — Object-Relational Mapping. Отображение реляций БД на ООП-сущности (классы, объекты, методы). Фактически создается виртуальная объектная БД users.first.login• Recordset — доступ к результату запроса через хеш, массив или их комбинацию db[‘users’][0][‘login’]
    4. 4. Object Query vs. Raw SQL• Object Query — генерация запроса к БД, посредством вызова методов User.find(:all, :conditions => {:active => true})• Raw SQL — использование чистого SQL для доступа к БД User.find_by_sql(‘select * from users’)
    5. 5. Основная дилемма• Скорость + Гибкость• Простота + Универсальность
    6. 6. Пример из реального мира SELECT fc.fieldvalue AS category, fs.fieldvalue AS ticket_type, u.fullname as username,t.isphonecall AS phone, t.isemailed AS email, coalesce((CASE WHEN fp.fieldvalue IS NULL ORt.isphonecall = 1 THEN 0 ELSE 1 END), 0) AS web, l.actionmsg AS action_text, t.ticketid asticket_id FROM swtickets t LEFT JOIN swcustomfieldvalues fc ON fc.typeid = t.ticketid AND fc.customfieldid = 23 LEFT JOIN swcustomfieldvalues fs ON fs.typeid = t.ticketid AND fs.customfieldid = 24 INNER JOIN swusers u ON u.userid = t.userid LEFT JOIN swauditlogs l ON l.ticketid = t.ticketid AND l.second_line = 1 LEFT JOIN swcustomfieldvalues fp ON fp.typeid = t.ticketid AND fp.customfieldid = 26 WHERE t.ticketstatusid IN ? AND FROM_UNIXTIME(t.lastactivity) BETWEENDATE(?) AND DATE(?) ORDER BY t.ticketid, l.dateline DESC
    7. 7. Реализация с помощью ActiveRecordSwticket.find(:all, :select => ‘fc.fieldvalue AS category, fs.fieldvalue AS ticket_type, u.fullname asusername, t.isphonecall AS phone, t.isemailed AS email, coalesce((CASE WHEN fp.fieldvalue ISNULL OR t.isphonecall = 1 THEN 0 ELSE 1 END), 0) AS web, l.actionmsg AS action_text,t.ticketid as ticket_id’,:joins =>[‘LEFT JOIN swcustomfieldvalues fc ON fc.typeid = t.ticketid AND fc.customfieldid = 23’,‘LEFT JOIN swcustomfieldvalues fs ON fs.typeid = t.ticketid AND fs.customfieldid = 24’,‘INNER JOIN swusers u ON u.userid = t.userid’,‘LEFT JOIN swauditlogs l ON l.ticketid = t.ticketid AND l.second_line = 1’,‘LEFT JOIN swcustomfieldvalues fp ON fp.typeid = t.ticketid AND fp.customfieldid = 26’],:conditions =>[‘t.ticketstatusid IN ? AND from_unixtime(t.lastactivity) BETWEEN DATE(?) AND DATE(?)’,25, 3.days.ago, Date.today],:order => ‘t.ticketid, l.dateline DESC’)
    8. 8. Gem Sequel• http://sequel.rubyforge.org/• gem install sequel• require ‘rubygems’ # Чистый Ruby require ‘sequel’• gem ‘sequel’ # Gemfile (Rails)
    9. 9. Возможности• RecordSet / ORM• Raw SQL / Object Query• Thread-safe, connection pooling• Работает с ADO, JDBC, MySQL, ODBC, Oracle, PostgreSQL, SQLite3 и еще десятью СУБД• Поддерживает prepared statements, хранимые процедуры, сейвпоинты, master/slave, шардинг
    10. 10. Работа с Sequel
    11. 11. Dataset I• chanmems = DB[:mems].filter(:source => 4chan.org) chanmems.avg(:uses) SELECT avg(uses) FROM mems WHERE source = 4chan.org• chanmems.map(:name) #=> [Trollface, FFFFUUU, Pedobear, ...] chanmems.to_hash(:name, :author) #=> {Trollface => ‘Anonymous’, FfFFUUU => ‘Anonymous’, ...}• dataset = DB[select id from mems] dataset.count #=> 31337• DB[select * from items where name = ?, name].each do |row| p row end
    12. 12. Dataset II• my_posts = posts.filter(:category => ruby, :author => david) my_posts = posts.filter(:stamp => (Date.today - 9)..(Date.today - 2)) my_posts = posts.filter(:category => [ruby, postgres, linux])• my_posts = posts.exclude(:category => [ruby, postgres, linux])• posts.filter(stamp IS NOT NULL)• posts.filter(stamp < ?, Date.today - 3).delete # DELETE FROM posts WHERE stamp < 2010-07-11• posts.insert(:category => ruby, :author => david) # INSERT INTO posts (category, author) VALUES (ruby, david)• Параметры для where, подзапросы, агрегация, chaining, транзакции, join по произвольным колонкам
    13. 13. Модели• class Post < Sequel::Model• post = Post[123] post = Post[:title => ‘Hello’]• post.title #=> ‘Hello’ post[:title] #=> ‘Hello’• many_to_one :author one_to_many :comments many_to_many :tags• subset(:posts_with_few_comments){num_comments < 30}• Валидация, callbacks, бизнес-логика для датасета, STI, миграции, timestamps и т.д.
    14. 14. Чистый SQL• DB.fetch("SELECT * FROM albums WHERE name LIKE :pattern", :pattern=>A%) do |row| puts row[:name] end• DB["UPDATE albums SET name = ? WHERE name = ?", MO, RF].update• DB.run "CREATE TABLE albums (id integer primary key, name varchar(255))"• DB << "ALTER TABLE albums ADD COLUMN copies_sold INTEGER"• DB[:albums].select{function(col1, col2)} # SELECT function("col1", "col2") FROM "albums"
    15. 15. Сравнение с DataMapper• DataMapper — только ORM• Даже в ORM другая философия: DM модель > БД, Sequel БД > модель• В Sequel больше back-ends из коробки
    16. 16. Производительность
    17. 17. Вопросы?• alexey.nayden@gmail.com• twitter.com/alexnayden• http://evilmartians.ru

    ×