47
Нетрадиционное использование Ruby и PostgreSQL Иван Евтухович вторник, 18 декабря 12 г.

Нетрадиционное использование Ruby и PostgreSQL

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: Нетрадиционное использование Ruby и PostgreSQL

Нетрадиционное использование Ruby и

PostgreSQLИван Евтухович

вторник, 18 декабря 12 г.

Page 2: Нетрадиционное использование Ruby и PostgreSQL

вторник, 18 декабря 12 г.

Page 3: Нетрадиционное использование Ruby и PostgreSQL

вторник, 18 декабря 12 г.

Page 4: Нетрадиционное использование Ruby и PostgreSQL

вторник, 18 декабря 12 г.

Page 5: Нетрадиционное использование Ruby и PostgreSQL

О чем этот доклад?

• О смерти Ruby?

• О чем-то, что будет полезно?

вторник, 18 декабря 12 г.

Page 6: Нетрадиционное использование Ruby и PostgreSQL

• ruby внутри vim

• ruby и PostgreSQL (полезная часть)

• ruby и PostgreSQL (бесполезная часть)

вторник, 18 декабря 12 г.

Page 7: Нетрадиционное использование Ruby и PostgreSQL

• :help ruby

• 200 строк документации

• пару десятков функций

Ruby и Vim

вторник, 18 декабря 12 г.

Page 8: Нетрадиционное использование Ruby и PostgreSQL

$ pwd /Users/brun/Projects/vim/src$ wc if_ruby.c 1346 3621 35552 if_ruby.c

вторник, 18 декабря 12 г.

Page 9: Нетрадиционное использование Ruby и PostgreSQL

Этого достаточно

• волшебные методы Vim.command и Vim.evaluate

вторник, 18 декабря 12 г.

Page 10: Нетрадиционное использование Ruby и PostgreSQL

Vim.command

• выполняет любую команду командного режима Vim

:ruby Vim.command(‘help ruby’):help ruby

вторник, 18 декабря 12 г.

Page 11: Нетрадиционное использование Ruby и PostgreSQL

:ruby puts Vim.evaluate(‘2012’).classFixnum

Vim.evaluate

• вычисляет любое выражение в vim

вторник, 18 декабря 12 г.

Page 12: Нетрадиционное использование Ruby и PostgreSQL

Проблемы

• нет eval, но есть pyeval() :-(

• я не нашел хороших примеров использования

• VimL

вторник, 18 декабря 12 г.

Page 13: Нетрадиционное использование Ruby и PostgreSQL

вторник, 18 декабря 12 г.

Page 14: Нетрадиционное использование Ruby и PostgreSQL

function! Serpinski()ruby << EOFdef draw(arr, x, y) arr[x][y] = '*'end

def carpet(arr, size, x, y) if size == 1 draw(arr, x, y) else new_size = size / 3 carpet(arr, new_size, x, y) carpet(arr, new_size, x + new_size, y) carpet(arr, new_size, x + new_size * 2, y) carpet(arr, new_size, x, y + new_size) carpet(arr, new_size, x + new_size * 2, y + new_size) carpet(arr, new_size, x, y + new_size * 2) carpet(arr, new_size, x + new_size, y + new_size * 2) carpet(arr, new_size, x + new_size * 2, y + new_size * 2) endend

arr = Array.new(27) { Array.new }carpet(arr, 27, 0, 0)

arr.each_with_index do |line, i| l = line.map { |e| e.nil? ? ' ' : e } Vim::Buffer.current.append(Vim::Buffer.current.line_number + i, l.join(''))endEOFendfunction

вторник, 18 декабря 12 г.

Page 15: Нетрадиционное использование Ruby и PostgreSQL

• :call Serpinski()

• :nmap <F7> :call Serpinski() <CR>

вторник, 18 декабря 12 г.

Page 16: Нетрадиционное использование Ruby и PostgreSQL

• расширение в PostgreSQL

• хранить ключ-значение• нет вложенности• ключ и значение — строки

• CREATE EXTENSION hstore

HSTORE

вторник, 18 декабря 12 г.

Page 17: Нетрадиционное использование Ruby и PostgreSQL

CREATE table test(id serial, value hstore);

“ заполним таблицу тестовыми данными

CREATE INDEX ON test USING GIN(value);

EXPLAIN SELECT value -> '111' FROM test WHERE value ? '111'; QUERY PLAN------------------------------------------------------------------------------ Bitmap Heap Scan on test (cost=12.01..16.02 rows=1 width=114) Recheck Cond: (value ? '111'::text) -> Bitmap Index Scan on test_value_idx (cost=0.00..12.01 rows=1 width=0) Index Cond: (value ? '111'::text)

вторник, 18 декабря 12 г.

Page 19: Нетрадиционное использование Ruby и PostgreSQL

Спецсредстваhttps://github.com/engageis/activerecord-postgres-hstore

rails  g  model  User  email:string  value:hstore

User.where("value ? 'name'")

User.where("value @> 'name=>Ivan'")

SELECT "users".* FROM "users" WHERE (value @> 'name=>Ivan')

вторник, 18 декабря 12 г.

Page 20: Нетрадиционное использование Ruby и PostgreSQL

explain SELECT "users".* FROM "users" WHERE (value @> 'name=>Ivan');

QUERY PLAN------------------------------------------Index Scan using test_value_idx on users (cost=0.00..8.27 rows=1 width=182) Index Cond: (value @> '"name"=>"Ivan"'::hstore)

вторник, 18 декабря 12 г.

Page 21: Нетрадиционное использование Ruby и PostgreSQL

Arrays

• В PostgreSQL есть массивы однотипных элементов

• Поддержка массивов pg появилась в rails 4

• Есть бэкпорт в rails 3

• https://github.com/tlconnor/activerecord-postgres-array

вторник, 18 декабря 12 г.

Page 22: Нетрадиционное использование Ruby и PostgreSQL

class CreateBooks < ActiveRecord::Migration def change create_table :books do |t| t.text :name t.text_array :authors t.timestamps end endend

вторник, 18 декабря 12 г.

Page 23: Нетрадиционное использование Ruby и PostgreSQL

create index on books using gin(authors);

Book.create! :authors => ["Ivan Evtukhovich", "Ivan Samsonov"]

Book.where("authors @> ARRAY['Ivan Samsonov']")

вторник, 18 декабря 12 г.

Page 24: Нетрадиционное использование Ruby и PostgreSQL

explain select * from books where authors @> ARRAY['Ivan Samsonov']; QUERY PLAN---------------------------------- Bitmap Heap Scan on books (cost=8.03..16.49 rows=4 width=84) Recheck Cond: (authors @> '{"Ivan Samsonov"}'::text[]) -> Bitmap Index Scan on books_authors_idx (cost=0.00..8.03 rows=4 width=0) Index Cond: (authors @> '{"Ivan Samsonov"}'::text[])вторник, 18 декабря 12 г.

Page 25: Нетрадиционное использование Ruby и PostgreSQL

Хипстерское хранилище

• документоориентированное• schemaless

• быстрый поиск• быстрая запись• без join-ов

• web scale

вторник, 18 декабря 12 г.

Page 26: Нетрадиционное использование Ruby и PostgreSQL

Имя?

• rake

• rdebug

• rmagick

• rdoc

вторник, 18 декабря 12 г.

Page 27: Нетрадиционное использование Ruby и PostgreSQL

Имя?

• cruisecontrol.rb

• perftools.rb

• gdb.rb

вторник, 18 декабря 12 г.

Page 28: Нетрадиционное использование Ruby и PostgreSQL

r_____.rb

вторник, 18 декабря 12 г.

Page 29: Нетрадиционное использование Ruby и PostgreSQL

rmongo.rb

вторник, 18 декабря 12 г.

Page 30: Нетрадиционное использование Ruby и PostgreSQL

Прообраз

• http://docs.mongodb.org/manual/tutorial/getting-started/

• early pre alfa version

• продукт не будет развиваться

вторник, 18 декабря 12 г.

Page 31: Нетрадиционное использование Ruby и PostgreSQL

вторник, 18 декабря 12 г.

Page 32: Нетрадиционное использование Ruby и PostgreSQL

Реализовано

• find

• insert

• count

• ensureIndex

вторник, 18 декабря 12 г.

Page 33: Нетрадиционное использование Ruby и PostgreSQL

Live Demo

вторник, 18 декабря 12 г.

Page 34: Нетрадиционное использование Ruby и PostgreSQL

Формат документа?

вторник, 18 декабря 12 г.

Page 35: Нетрадиционное использование Ruby и PostgreSQL

YAML

вторник, 18 декабря 12 г.

Page 36: Нетрадиционное использование Ruby и PostgreSQL

Как и обещал

• документоориентированное √• schemaless √

• быстрый поиск √• быстрая запись √• без join-ов √

• web scale √

вторник, 18 декабря 12 г.

Page 37: Нетрадиционное использование Ruby и PostgreSQL

Что внутри?

вторник, 18 декабря 12 г.

Page 38: Нетрадиционное использование Ruby и PostgreSQL

pl/ruby

• https://github.com/globegit/postgresql-plruby

• хрен поставишь• только ruby 1.8.x

• не завелся на PostgreSQL 9.2

• добровольцы?

вторник, 18 декабря 12 г.

Page 39: Нетрадиционное использование Ruby и PostgreSQL

Table "public.things"

Column | Type | --------+---------+ id | integer | value | text |

вторник, 18 декабря 12 г.

Page 40: Нетрадиционное использование Ruby и PostgreSQL

• Со вставкой все понятно

• А с поиском?

вторник, 18 декабря 12 г.

Page 41: Нетрадиционное использование Ruby и PostgreSQL

db.things.find("title" => "Книга")

SELECT * FROM things WHERE rmongorb_get_key('title'::text, value) = 'Книга'

CREATE OR REPLACE FUNCTION rmongorb_get_key(key text, value text) RETURNS text AS ' require "yaml" obj = YAML.load(value) obj[key]' LANGUAGE 'plruby' IMMUTABLE;

вторник, 18 декабря 12 г.

Page 42: Нетрадиционное использование Ruby и PostgreSQL

• функциональные индексы в PostgreSQL

• http://www.postgresql.org/docs/9.2/static/indexes-expressional.html

Быстрый поиск

вторник, 18 декабря 12 г.

Page 43: Нетрадиционное использование Ruby и PostgreSQL

db.things.ensureIndex( {"last_name" => 1})

CREATE INDEX ON things (rmongorb_get_key( 'last_name'::text, value))

вторник, 18 декабря 12 г.

Page 44: Нетрадиционное использование Ruby и PostgreSQL

EXPLAIN SELECT * FROM things WHERErmongorb_get_key('last_name'::text, value) = 'Сидоров' ; QUERY PLAN------------------------------------- Index Scan using things_rmongorb_get_key_idx2 on things (cost=0.25..20.53 rows=4 width=222) Index Cond: (rmongorb_get_key('last_name'::text, value) = 'Сидоров'::text)

вторник, 18 декабря 12 г.

Page 45: Нетрадиционное использование Ruby и PostgreSQL

Быстрая запись

• synchronous_commit = on

• http://www.postgresql.org/docs/9.2/static/wal-async-commit.html

вторник, 18 декабря 12 г.

Page 46: Нетрадиционное использование Ruby и PostgreSQL

Что еще можно сделать?

• вложенные ключи• join на самом деле есть :-)

• sharding

• http://ssql-railsconf.herokuapp.com/

вторник, 18 декабря 12 г.

Page 47: Нетрадиционное использование Ruby и PostgreSQL

Спасибо!

@rubynoname

@evtuhovich

[email protected]

http://blog.evtuhovich.ru/

вторник, 18 декабря 12 г.