DbCharmer commit:b02576644d982f895365e796ba75b825f7104210 æç¹ã® README.rdoc ã®ãã£ããèªã¿ä¸ã
"DbCharmer" ã¯ãã·ã³ãã«ã§ãã¯ãã«ãª ActiveRecord ã®ãã©ã°ã¤ã³ã§ããActiveRecord ãè¤æ°ã®ãã¼ã¿ãã¼ã¹ãè¤æ°ã®ãã¼ã¿ãã¼ã¹ãµã¼ãã§åä½ã§ããããæ¡å¼µãã¾ãã
ãã®ã©ã¤ãã©ãªã ActiveRecord ã«è¿½å ãã主ãªæ©è½ã¯ä»¥ä¸ã®ã¨ãã:
- AR model ã®ã³ãã¯ã·ã§ã³ãã·ã³ãã«ã«ç®¡ç (switch_connection_to ã¡ã½ãã)
- AR model ããã¼ã¿ãã¼ã¹ãåå²ããã³ãã¯ã·ã§ã³ã«
- ã¯ã¨ãªãã©ãã«ããããããç°¡åã«é¸ã¹ãæ©è½ (
Model.on_*
ã¡ã½ãã群) - èªåã§ãã¹ã¿ã»ã¹ã¬ã¼ãã«ã¯ã¨ãªãããããã (åç §ã¯ã¹ã¬ã¼ãã«ãæ´æ°ã¯ãã¹ã¿ã§)
- è¤æ°ã®ãã¼ã¿ãã¼ã¹ã®ãã¤ã°ã¬ã¼ã·ã§ã³ããã¬ãã·ãã«ã«
- è¤æ°ã®ã·ã£ã¼ãã£ã³ã°æ¹æ³ã§ã·ã³ãã«ãªã·ã£ã¼ãã£ã³ã°æ©è½ãå©ç¨ã§ãã (value, range, mapping table)
詳細ã¯ã http://dbcharmer.net ãè¦ã¦ãã ããã
å°å ¥
DbCharmer ã®å°å ¥ã«ã¯2ã¤ã®ã¢ããã¼ããããã¾ã:
- gem ãã¤ãã (ãªã¹ã¹ã¡ãRails 3.2以éã§ã¯ãã®æ¹æ³ã§ãã使ãã¾ãã)
- Rails plugin ã¨ãã¦å ¥ãã (Rails 2.x ã§ã®ã¿ä½¿ãã¾ã)
gem ã¨ãã¦å°å ¥ãããªããGemfile ã«ä»¥ä¸ã追å ãã¦ãã ãã:
gem 'db-charmer', :require => 'db_charmer'
Rails ã®ãã©ã°ã¤ã³ã¨ãã¦å°å ¥ãããªã以ä¸ã®ã³ãã³ãã§:
./script/plugin install git://github.com/kovyrin/db-charmer.git
注æ: DbCharmer ã Rails ãããªãããã¸ã§ã¯ãã§ä½¿ããªããã³ãã¯ã·ã§ã³ã管çããã¡ã½ããã使ãåã«ãDbCharmer.env
ã«é©åãªå¤ãè¨å®ããå¿
è¦ãããã¾ããé©åãªå¤ã¯ãdatabase.yml
ã®ãããã¬ãã«ã®ã»ã¯ã·ã§ã³åã§ãã
ç°¡å㪠ActiveRecord ã®ã³ãã¯ã·ã§ã³ã®ç®¡ç
ãã®ãã©ã°ã¤ã³ã§è¿½å ãããæ©è½ã¨ã㦠switch_connection_to
ã¨ããã¡ã½ãããããã¾ãããããã¯ããããªç¨®é¡ã® DB ã³ãã¯ã·ã§ã³ã®æå®ãåãä»ããã¢ãã«ã§ãã®æå®ã使ãã¾ãã以ä¸ããµãã¼ããã¦ãã¾ã:
- æååã¨ã·ã³ãã«: database.yml ã«ããæ¥ç¶è¨å®ã®ãããã¯ãæå®
- ActiveRecord ã®ã¢ãã« (ã¢ãã«ã«å¯¾ãã¦ã³ãã¯ã·ã§ã³ãè¨å®ãã)
- ãã¼ããã¼ã¹ã®ã³ãã¯ã·ã§ã³ (
Model.connection
) - nil: ããã©ã«ãã®ã³ãã¯ã·ã§ã³ã«ãªã»ãããã
ãµã³ãã«ã³ã¼ã:
class Foo < ActiveRecord::Model; end Foo.switch_connection_to(:blah) Foo.switch_connection_to('foo') Foo.switch_connection_to(Bar) Foo.switch_connection_to(Baz.connection) Foo.switch_connection_to(nil)
ãµã³ãã«ã® database.yml
ã®è¨å®:
production: blah: adapter: mysql username: blah host: blah.local database: blah foo: adapter: mysql username: foo host: foo.local database: foo
switch_connection_to
ã¡ã½ããã¯ç¬¬äºå¼æ°ã«ãªãã·ã§ã³å¼æ°ã¨ã㦠should_exist = true
ãªå¼æ°ãã¨ãã¾ãããã®ãªãã·ã§ã³ã¯æååã¾ãã¯ã·ã³ãã«ãå¼æ°ã«ã¡ã½ãããå¼ã°ããã¨ãããã®ã³ãã¯ã·ã§ã³ã®è¨å®ã database.yml
ã«ãããã©ããè¦ã¾ãããã® should_exist ã true ãªãã°ãä¾å¤ããããããfalse ãªãã°ã¨ã©ã¼ã¯ç¡è¦ãããã³ãã¯ã·ã§ã³ã®å¤æ´ã¯èµ·ãã¾ããã
ããã¯ãdevelopment ã¢ã¼ãããã¹ãã®ã¨ãã«ãè¤æ°ã®ãã¼ã¿ãã¼ã¹ããã¼ã«ã«ã«ä½ããããªããã²ã¨ã¤ã®ãã¼ã¿ãã¼ã¹ã«å ¨é¨ãã¼ãã«ãä½ããããã¨ãããã¨ãã«ã¤ããã¾ãã
è¦å: å
¨ã¦ã®ã³ãã¯ã·ã§ã³ã®ã¹ã¤ããã®å¼ã³åºãã¯ãå¼ãã ã¯ã©ã¹ã ãã§ã³ãã¯ã·ã§ã³ãã¹ã¤ãããã¾ããswitch_connection_to
ã®å¼ã³åºãã¨ãã³ãã¯ã·ã§ã³ã®ã¹ã¤ãããç¶æ¿å
ã®ã¯ã©ã¹ã§ãã£ã¦ã¯ããã¾ãã (ãã¨ãã° ActiveRecord::Base ã¯ã©ã¹ã®ã³ãã¯ã·ã§ã³ãã¹ã¤ããããã¨ãå
¨ã¦ã®ã¢ãã«ãæ°ããã³ãã¯ã·ã§ã³ã«ãªã£ã¦ãã¾ãã¾ãããããããã¨ããããã¨ãã«ã¯ãæ®éã« establish_connection
ã使ãã¾ããã)ã
è¤æ°ãã¼ã¿ãã¼ã¹ã®ãã¤ã°ã¬ã¼ã·ã§ã³
è¤æ°ã®ãã¼ã¿ãã¼ã¹ã使ãã¢ããªã±ã¼ã·ã§ã³ã§ãã便å©ãªã¹ãã¼ããã¤ã°ã¬ã¼ã·ã§ã³ã®ä»çµã¿ãå¿
è¦ã§ãããã
Rails ã¦ã¼ã¶ã®ã¿ãªããã¯æ¢ã« Rails ã® migration ã¨ããä»çµã¿ãæã£ã¦ãã¾ããDbCharmer ã§ããRails ã® migration ã§å¯è½ãªãããã·ã¼ã ã¬ã¹ã«è¤æ°ãã¼ã¿ãã¼ã¹ãæ±ããããã«ãã¦ãã¾ãã
è¤æ°ã®ãã¼ã¿ãã¼ã¹ãæä½ããã®ã«ã以ä¸ã®2ã¤ã®æ¹æ³ã使ãã¾ã:
- ãã¤ã°ã¬ã¼ã·ã§ã³ãã¡ã¤ã«å ¨ä½ã§ã³ãã¯ã·ã§ã³ãå¤æ´ããæ¹æ³: ãã¤ã°ã¬ã¼ã·ã§ã³å ¨ä½ãæå®ã®ãã¼ã¿ãã¼ã¹ã«ã¹ã¤ãããã
- ãããã¯ã§ã³ãã¯ã·ã§ã³ãå¤æ´ããæ¹æ³: ãã¤ã°ã¬ã¼ã·ã§ã³ã®ä¸é¨ãæå®ã®ãã¼ã¿ãã¼ã¹ã«ã¹ã¤ãããã
ãã¤ã°ã¬ã¼ã·ã§ã³ãã¡ã¤ã«ã®ä¾(å ¨ä½ã§ã³ãã¯ã·ã§ã³ãå¤æ´ããå ´å):
class MultiDbTest < ActiveRecord::Migration db_magic :connection => :second_db def self.up create_table :test_table, :force => true do |t| t.string :test_string t.timestamps end end def self.down drop_table :test_table end end
ãã¤ã°ã¬ã¼ã·ã§ã³ãã¡ã¤ã«ã®ä¾(ãããã¯ã§ã³ãã¯ã·ã§ã³ãå¤æ´ããå ´å):
class MultiDbTest < ActiveRecord::Migration def self.up on_db :second_db do create_table :test_table, :force => true do |t| t.string :test_string t.timestamps end end end def self.down on_db :second_db { drop_table :test_table } end end
ãã¤ã°ã¬ã¼ã·ã§ã³ãã¡ã¤ã«ã®ä¾(å
¨ä½ã§ã³ãã¯ã·ã§ã³ãå¤æ´ããåããã¼ãã«ã®æä½ãè¤æ°ã³ãã¯ã·ã§ã³ã«):
(注: :connection 㨠:connections ã¯ãã³ãã¯ã·ã§ã³ã®é
åãæå®ãããã¨ãã§ãã)
class MultiDbTest < ActiveRecord::Migration db_magic :connections => [:second_db, :default] def self.up create_table :test_table, :force => true do |t| t.string :test_string t.timestamps end end def self.down drop_table :test_table end end
ããã©ã«ãã®ãã¤ã°ã¬ã¼ã·ã§ã³ã®ã³ãã¯ã·ã§ã³ã«ã¤ãã¦
DbCharmer 1.6.10 以éã§ã¯ãActiveRecord::Migration.db_magic
ã®å¼ã³åºãã¨ããã¤ã°ã¬ã¼ã·ã§ã³ã§ã®ããã©ã«ãã®ã³ãã¯ã·ã§ã³ã®è¨å®(ç¹å®ã®ã³ãã¯ã·ã§ã³ã®å¤æ´ããªãéãããã使ããã)ãã§ããããã«ãªãã¾ããããã¤ã°ã¬ã¼ã·ã§ã³ã§ããã©ã«ãã® ActiveRecord ã®ã³ãã¯ã·ã§ã³ã使ãããå ´å㯠db_magic :connection => :default
ã使ã£ã¦ãã ããã
ä¸æ£ãªã³ãã¯ã·ã§ã³åã®æ±ãã«ã¤ãã¦
ã©ã®ç°å¢ã§ãããã©ã«ãã§ã¯ãon_db
㨠db_magic
ã®å®£è¨ã¯æå®ããã³ãã¯ã·ã§ã³ã database.yml ã«åå¨ããªãå ´å失æãã¾ããproduction ç°å¢ä»¥å¤ã§ã²ã¨ã¤ã®ãã¼ã¿ãã¼ã¹ã使ããªã©ãã¦ããã¨ãã«ããããªãã®ãç¡è¦ããããã¨ãã§ãã¾ã(ãã¹ãã³ã¼ãç¨ã®ãã¼ã¿ãã¼ã¹ã¨ãã§ã¨ãã«ä¾¿å©ã§ã)ã
ãã®æ¯ãèãã¯ãRails ã® initializers 㧠DbCharmer.connections_should_exist
ã®è¨å®ããããã¨ã§ã§å¶å¾¡ã§ãã¾ãã
è¦å: ãããã¹ãç°å¢ã§ãã¼ã¿ãã¼ã¹ã®ã³ãã¯ã·ã§ã³ãåãã¦ãã¹ã¿ã»ã¹ã¬ã¼ãã®ãµãã¼ããããããªããtransactional fixtures ã®ãµãã¼ãããªãã«ããå¿ è¦ãããã¾ããããããªãã¨ããã¼ã¿ã使ã£ããã¹ãã§ããããåé¡ã«ééãããã¨ã«ãªãã§ãããã
ã¢ãã«ããã¹ã¿ã»ã¹ã¬ã¼ãç°å¢ã§ä½¿ã
ãã¹ã¿ã»ã¹ã¬ã¼ãã¬ããªã±ã¼ã·ã§ã³ã¯ãä»æ¥ã®ä¸è¦æ¨¡ãã大è¦æ¨¡ãªãã¼ã¿ãã¼ã¹ã¢ããªã±ã¼ã·ã§ã³ã§ã®ããã£ã¨ãããã¥ã©ã¼ãªã¹ã±ã¼ã«ã¢ã¦ãææ³ã§ããããã¤ãã® Rails ãã©ã°ã¤ã³ããã¢ãã«ã§ã¹ã¬ã¼ããµã¼ãã使ããããã«ãã¦ãã¾ããããããã¯å¤§ããªã¢ããªã±ã¼ã·ã§ã³ã§ä½¿ã£ãæãã§ã¯ãã¾ããã¬ãã·ãã«ã§ã¯ããã¾ããã
ActsAsReadonlyable ãã©ã°ã¤ã³ããã°ãã使ã£ã¦ãã¾ããããããããã®å¤æ´ãå ããªãã使ã£ã¦ãã¾ããããããããã®ãã©ã°ã¤ã³ãä½è ã«æ¾ç½®ãããã®ã§ãæã ã¯ãã¹ã¿ã»ã¹ã¬ã¼ãã®ããã®ã³ã¼ãããã©ã°ã¤ã³ã«ã¾ã¨ããªãªã¼ã¹ãããã¨ã«æ±ºãã¾ãã(Rails 2.2以éåã)ãDbCharmer ã¯ã以ä¸ã®æ©è½ã Rails ã®ã¢ãã«ã«è¿½å ãã¾ã:
å ¨ã¦ã®åç §ãã¹ã¬ã¼ã(ãã¡)ã«èªåã¹ã¤ãã
ã¢ãã«ãä½ã£ãããdb_magic :slave => :blah
ã db_magic :slaves => [ :foo, :bar ]
ã®ã³ãã³ããã¢ãã«ã§ä½¿ããã¨ãã§ãã¾ãããããããã¨ã§ãfind, count, exist ãªã©ã®åç
§ç³»ã®æä½ãã¹ã¬ã¼ã(ã¾ãã¯è¤æ°ã®ã¹ã¬ã¼ããªããããããã©ã¦ã³ãããã³)ã«åãæ¿ããã¢ã¼ãã«ãªãã¾ããä¾ã¯ä»¥ä¸ã®ã¨ãã:
class Foo < ActiveRecord::Base db_magic :slave => :slave01 end class Bar < ActiveRecord::Base db_magic :slaves => [ :slave01, :slave02 ] end
ããã©ã«ãã³ãã¯ã·ã§ã³åãæ¿ã
ãããä¸çµã®ãã¹ã¿ã»ã¹ã¬ã¼ã(ãããã¯åç´ã«ã²ã¨ã¤ããå¤ããã¼ã¿ãã¼ã¹)ãããç°å¢ãªãã°ãããã¤ãã®ã¢ãã«ã§ããã©ã«ãã®ã³ãã¯ã·ã§ã³ãå¤æ´ãããããããã¾ãããdb_magic :connection => :foo
ãã¢ãã«ã«æ¸ããã¨ã§ãããããã¨ãã§ãã¾ããä¾:
class Foo < ActiveRecord::Base db_magic :connection => :foo end
ãã¹ã¿ã»ã¹ã¬ã¼ãæ§æ (ã¤ã¾ãã¡ã¤ã³ã®ã³ãã¯ã·ã§ã³ + ã¹ã¬ã¼ãã®ã³ãã¯ã·ã§ã³) ã§åå²ããã¦ããã¢ãã«ã®ä¾:
class Bar < ActiveRecord::Base db_magic :connection => :bar, :slave => :bar_slave end
ã¯ã¨ãªãã¨ã®ã³ãã¯ã·ã§ã³ç®¡ç
ãã¹ã¿ã§ select ã®ã¯ã¨ãªãèµ°ããããã¨ããã±ã¼ã¹ãããã¨æãã¾ãããã¨ãã°ãã¡ããã©ãã¼ã¿ã追å ãã¦ããããèªã¿åºãå¿ è¦ããã£ã¦ãã§ããããã¹ã¬ã¼ãã«åæ ããããã©ããããããªããã¨ãããããªã¨ãã§ãããããããããªã¨ãã®ããã«ãè¨å®ããæ¹æ³ã ActiveRecord ã¢ãã«ã«è¿½å ãã¦ãã¾ã:
1) on_master
- ãã㯠block ã¹ã¿ã¤ã«ã¨ proxy ã¹ã¿ã¤ã«ã®2種é¡ã®æ¸ãæ¹ãããã¾ãã
block ã¹ã¿ã¤ã«ã§ã¯ãã³ã¼ããããã¯ã®ã³ãã¯ã·ã§ã³ãå¼·å¶çã«ã¹ã¤ããããããã¨ãã§ãã¾ã:
User.on_master do user = User.find_by_login('foo') user.update_attributes!(:activated => true) end
proxy ã¹ã¿ã¤ã«ã¯ãããã¯ã¨ãªããã¹ã¿ã«åãããã¨ãã§ãã¾ã:
Comment.on_master.last(:limit => 5) User.on_master.find_by_activation_code(code) User.on_master.exists?(:login => login, :password => password)
2) on_slave
- ããã¯ãã¹ã¿ãå¼·å¶çã«ä½¿ãããã«ãããã¨ãªã©ã«ãå¼·å¶çã«ã¹ã¬ã¼ãã«ä½¿ãããã«ãããã¡ã½ããã§ããã¹ã¬ã¼ããè¤æ°ããã°ãã©ã³ãã ã§ã²ã¨ã¤ãé¸ã°ãã¾ãããã®ã¡ã½ããã block 㨠proxy ã®ã¹ã¿ã¤ã«ãããã¾ãã
3) on_db(connection)
- ããã¯ååºã®2ã¤ã®ã¡ã½ãããå¯è½ã«ãããã®ã§ããããã¯ã¢ãã«ã®ã³ãã¯ã·ã§ã³ããã³ã¼ãã®ãããã¯ã1ã¤ã®æã§ããã DB ã«åãæ¿ããã®ã«ä½¿ãã¾ã(2ã¤ã®å½¢å¼ãããã¾ã)ããã㯠switch_connection_to
ã¨åãé¡ã®å¤ãåãä»ãã¾ããä¾:
Comment.on_db(:olap).count Post.on_db(:foo).find(:first)
development 㨠test ç°å¢ã®ããã©ã«ãã§ã¯ãåå¨ããªãã³ãã¯ã·ã§ã³ã on_db
ã®å¼ã³åºãã使ãã¨ãã¯ã¨ãªã¯ã²ã¨ã¤ã®ãã¼ã¿ãã¼ã¹ã«å
¨ã¦ã®ã¯ã¨ãªãéãã¾ããproduction ã® on_db
ã§ã¯ãåå¨ããªãååã¯åãä»ãã¾ããã
ãã®æ¯ãèãã¯ã DbCharmer.connections_should_exist
ã Rails ã®åæåã§è¨å®ãããã¨ã«ãã£ã¦å¶å¾¡ã§ãã¾ãã
å¼·å¶çãªã¹ã¬ã¼ãåç §
ããã¤ãã®å ´é¢ã§ãããã©ã«ãã§ãå
¨ã¦ã®åç
§ãã¹ã¬ã¼ãã«ãããã¢ã¼ãã使ãããã«ã¯é大ãããã¢ãã«ãããã¾ãããããããã¹ã¬ã¼ãã«ãããããã¢ã¼ãã«åãæ¿ãããã¨æããã¨ããã¾ã«ããã¾ãã
ãã¨ãã°ãUser
ã¢ãã«ãããã¨ãã¾ããã¦ã¼ã¶ã¯å¤ãã¢ã«ã¦ã³ãæ
å ±ãè¦ãããªãã®ã§ãã¹ã¬ã¼ãåç
§ã§ã®é
延ã¯é¿ãããã§ãããããããã±ã¼ã¹ã§ã¯(ãã¨ãã°ããã°ã¢ã¦ãç¶æ
ã§ã®ãããã£ã¼ã«ãã¼ã¸ã®è¡¨ç¤ºããªã©ãªã©)ãå
¨ã¦ã®åç
§ãã¹ã¬ã¼ãã«åããããåãæ¿ããã¨ããã®ã¯åççã§ãã
ãã®ã¦ã¼ã¹ã±ã¼ã¹ã®ããã«ãDbCharmer ã® 1.7.0 ãããå¼·å¶çã«ã¹ã¬ã¼ããåç §ããæ©è½ã追å ããã¾ãããããã¯ãããã¤ãã®å°ããªå¥ã ã®æ©è½ããæãã¾ãããçµã¿åããã«ãããã¯ãã«ãªãã®ã«ãªã£ã¦ãã¾ã:
1) ActiveRecord ã® db_magic
ã¡ã½ããã® :force_slave_reads => false
ãªãã·ã§ã³ã
ãã®ãªãã·ã§ã³ã¯ã¢ãã«ã§èªåã§ã¹ã¬ã¼ãåç
§ããã®ãç¡å¹ã«ãã¾ãããªã®ã§ãon_slave
ãããã¯ããã®ä»ã®ã¹ã¬ã¼ãåç
§ã§ããããã«ããã¡ã½ãããå¿
è¦ã«å¿ãã¦å¼ã¶å¿
è¦ãããã¾ããä¾:
class User < ActiveRecord::Base db_magic :slave => slave01, :force_slave_reads => false end
2) ActionController ã® force_slave_reads
ã¯ã©ã¹ã¡ã½ããã
ãã®ã¡ã½ããã¯ãã³ã³ããã¼ã©ãã¨(å¼æ°ãªãã§å¼ã°ããã¨ã)ããããã¯ãã¢ã¯ã·ã§ã³ã㨠(:only
㨠:except
ãã©ã¡ã¼ã¿ã渡ãã¦å¼ãã ã¨ã) ãå¼·å¶çã«ã¹ã¬ã¼ããåç
§ãã¾ãã
ããã¯ãã¹ã¬ã¼ãåç
§ã«ããã©ã°ããããã許容ã§ããã¢ã¯ã·ã§ã³ã§ãã¹ã¬ã¼ããè¨å®ããã¦ããã¢ãã«ã®åç
§å
ãã¹ã¬ã¼ãã«åããããã¨ãããããªã¨ãã«ä½¿ãã¾ããä¾:
class ProfilesController < Application force_slave_reads :except => [ :login, :logout ] ... end
3) ActionController ã® force_slave_reads! ã¨ããã¤ã³ã¹ã¿ã³ã¹ã¡ã½ããããã®ã¡ã½ããã§ãã¢ã¯ã·ã§ã³å
ããããã¯ãã³ã³ããã¼ã©ã®ãã£ã«ã¿ã§ãä¸æçã«åç
§å
ãå¼·å¶çã«ã¹ã¬ã¼ãã«åãããããã¾ãã
ãã®ã¡ã½ããã¯åãã¢ã¯ã·ã§ã³ããã°ã¤ã³ãã¦ããã¦ã¼ã¶ã¨ãã°ã¤ã³ãã¦ããªãã¦ã¼ã¶ã«å¼ã°ããã¨ãã«ä½¿ãã¾ããbefore_filter
ã§ã¦ã¼ã¶èªè¨¼ãã¦ãèªè¨¼ãã¦ããªãã¦ã¼ã¶åãã«ã¯ force_slave_reads!
ã¡ã½ãããå¼ã³ã¾ãã
class ProfilesController < Application before_filter do force_slave_reads! unless current_user end ... end
注æ: ãã®ã¡ã½ããã使ãåã«ãDbCharmer ã® ActionController ãµãã¼ããæå¹ã«ããå¿
è¦ãããã¾ãã
DbCharmer.enable_controller_magic!
ããããã¸ã§ã¯ãã®åæåã³ã¼ãã§å¼ã¶å¿
è¦ãããã¾ãã
4) DbCharmer.force_slave_reads
ã¡ã½ããã¯ããããã¯å
ã®ã³ã¼ãã§å¼·å¶çã«ã¹ã¬ã¼ãåç
§ãããã®ã«ä½¿ããã¾ããããã¯ãã¨ã¦ãç´°ããç²åº¦ã§ã®ã¹ã¬ã¼ãåç
§ãå¼·å¶ããæ©è½ã§ããä¾:
DbCharmer.force_slave_reads do ... total_users = User.count ... end
注æ: ä»ã®ã¨ããããã®æ©è½ã¯ãã¼ã¿ã§ã使ãå ´åã¯æ³¨æãå¿ è¦ã§ãããã¹ããã¦ãããã®ã®ãç¾å®ä¸çã®ã¢ããªã±ã¼ã·ã§ã³ã§ã¯æ³å®å¤ã®åé¡ãèµ·ããå¯è½æ§ãããã¾ãã
é¢é£ã®ã³ãã¯ã·ã§ã³ã®ç®¡ç
ActiveRecord ã¢ãã«ã¯ããããäºãã«é¢é£ãæã£ã¦ãã¦ãããããããã¼ã¿ãã¼ã¹ã®ã³ãã¯ã·ã§ã³ãæã£ã¦ãããããUser.posts.count
ã®ãããªã¡ã½ãããã§ã¼ã³ãªããã§ãã³ãã¯ã·ã§ã³ã®ç®¡çãããã®ãå°ãé£ããã§ãã posts ã® count ãå¥ã®ãã¼ã¿ãã¼ã¹ã§ãããããªãã°ãããã²ã¨ã¤ã®ã¯ã©ã¹ã ãã³ãã¯ã·ã§ã³ãå¤æ´ãã¦ã以ä¸ã®æ§ã«ã¡ã½ãããå¼ã³ã¾ã:
Post.on_db(:olap) { User.posts.count }
ããã¯ãã¾ãè¯ãæ¸ãæ¹ã§ã¯ãªããããªã®ã§ãé¢é£ããã¾ãæ±ããããã« on_*
ã¡ã½ãã群ãæºåãã¾ããããããªãããã§ä½¿ãã¾ã:
@user.posts.on_db(:olap).count @user.posts.on_slave.find(:title => 'Hello, world!')
注æ: ActiveRecord ã®é¢é£ã¯ãçµæã®ãªãã¸ã§ã¯ããããã¯ã³ã¬ã¯ã·ã§ã³ã®ãããã·ã¨ãã¦å®è£ ããã¦ããããããã§ã¤ã³ããã¡ã½ãã以å¤ãã³ãã¯ã·ã§ã³ã®åãæ¿ãã使ãã¾ã:
@post.user.on_slave # post ã® author ãè¿ã @photo.owner.on_slave # photo ã® owner ãè¿ã
DbCharmer ã® 1.4 以éã§ã¯ãhas_many 㨠HABTM é¢é£ã®ã³ãã¯ã·ã§ã³åãæ¿ã㧠prefix è¨æ³ã使ãã¾ã:
@user.on_db(:foo).posts @user.on_slave.posts
named scope ã®ãµãã¼ã
DbCharmer ã¦ã¼ã¶ã® named scope ã§ã®ã³ãã¯ã·ã§ã³ã®åãæ¿ããç°¡åã«ãããããã¹ã³ã¼ãã§ã on_*
ã¡ã½ããããµãã¼ãããããã«ãã¾ããã
以ä¸ã®ã¹ã³ã¼ããã§ã¼ã³ã¯å
¨é¨ãã£ã¦ããã¨ã¯åãã§ã(ã¯ã¨ãªã¯ :foo ãã¼ã¿ãã¼ã¹ã³ãã¯ã·ã§ã³ã§å®è¡ããã¾ã):
Post.on_db(:foo).published.with_comments.spam_marked.count Post.published.on_db(:foo).with_comments.spam_marked.count Post.published.with_comments.on_db(:foo).spam_marked.count Post.published.with_comments.spam_marked.on_db(:foo).count
é¢é£ã®ãµãã¼ãããã¦ããã®ã§ã以ä¸ã®ããã«ã使ãã¾ã:
@user.on_db(:archive).posts.published.all @user.posts.on_db(:olap).published.count @user.posts.published.on_db(:foo).first
ä¸æ¬ããã³ãã¯ã·ã§ã³ã®ç®¡ç
ããããã®ãã¼ãã«ã使ã£ã¦ã³ã¼ããæ¸ããããããã¦ãããããå¥ã®ãã¼ã¿ãã¼ã¹ã使ãããã«ãããã¨ããã¨ããããã¾ãã
ãããªãµãã«ã§ãã¾ã:
DbCharmer.with_remapped_databases(:logs => :big_logs_slave) { ... }
ããã©ã«ãã :logs
ã®ã©ã®ã¢ãã« (ãã¨ãã° db_charmer :connection => :logs
ãªã©ã¨æ¸ãã¦ããã¢ãã«)ãããã®ãããã¯å
ã§ã¯ã³ãã¯ã·ã§ã³ã :big_logs_slave
ã«å¤ãã¾ãã
ããã¯ãä»ã®ã©ã® DbCharmer ã®ã¡ã½ããããåªå
度ãä½ãã§ãããªã®ã§ãModel.on_db(:foo).find(...)
ãªã©ã¯ãæå®ããããã¼ã¿ãã¼ã¹ã使ãã¤ã¥ããããã§ãªããã®ã¯ãªãããããã¾ãã
ä¸åº¦ã«ãããã¤ã§ããªãããã®æå®ãã§ãã¾ããã¾ããDbCharmer ã§ã³ãã¯ã·ã§ã³ãæå®ãã¦ããªãã©ã®ã¢ãã«ã«ããããããã¼ã¿ãã¼ã¹åã¨ã㦠:master
ã使ãã¾ãã
ãã¼ã: DbCharmer 㯠ã¢ãã«ã§ alias_method_chain
ã使ã£ã¦åãã¦ãã¾ãã注æãã¦ãå¿
è¦ãªç®æã«ã ãããããã¦ãã¾ãã
ããããwith_remapped_databases
ã¨ããã©ã«ãã®ãã¼ã¿ãã¼ã¹(:master
) ã®ãªãããã使ããããªã ActiveRecord::Base
ã®å
¨ã¦ã®ãµãã¯ã©ã¹ã«ãããããããããã¾ããã
ããã¯ã²ã©ãåé¡ãã大ããªããã©ã¼ãã³ã¹ã®å½±é¿ãããããªãã¯ãã§ã(ããã§ãã¦ã)ã
ã·ã³ãã«ãªã·ã£ã¼ãã£ã³ã°ã®ãµãã¼ã
DbCharmer ã® 1.6.0 ãããActiveRecord ã®æ¡å¼µã¨ãã¦ã·ã³ãã«ãªãã¼ã¿ãã¼ã¹ã·ã£ã¼ãã£ã³ã°ããµãã¼ããã¦ãã¾ãã
ãã®æ©è½ã¯æ¬çªç°å¢ã§ããã¹ãããã¦ããã¨ã¯ããããã®æ©è½ã®åºæ¬ãã¡ããã¨ç解ããã«ã¢ããªã±ã¼ã·ã§ã³ã§ä½¿ãã®ã¯ãªã¹ã¹ã¡ãã¾ããã
ç¾æç¹ã§ã¯4ã¤ã®ã·ã£ã¼ãã£ã³ã°æ¹æ³ããµãã¼ããã¦ãã¾ã:
1) "range" - ã¨ã¦ãã·ã³ãã«ãªã·ã£ã¼ãã£ã³ã°æ¹æ³ã§ãäºåã«å®ç¾©ãããã©ã¤ããªãã¼ã®ç¯å²ã§ãã¼ãã«åå²ãè¡ãããã®å°ããåå²ãããã¼ãã«ãå¥ã®ãã¼ã¿ãã¼ã¹ããã¼ã¿ãã¼ã¹ãµã¼ãã«é
ç½®ãããã¨ãã§ãã¾ãã
ãããªã¨ã便å©: é常ã«å¤§ãããã¼ãã«ãã ãã ã大ãããªã£ã¦ãããããªã¨ãããã¼ãã«ãããã¤ãã®ãµã¼ãã«ã®ãããã¨ã§è¤éãªã·ã£ã¼ãã£ã³ã°ã®ä»çµã¿ãªãã§ã·ã³ãã«ããä¿ã¡ããã¨ãã
2) "hash_map" - ãã£ããã·ã³ãã«ãªã·ã£ã¼ãã£ã³ã°æ¹æ³ã§ãäºåã«å®ç¾©ãã¦ãããããã¤ãã®ãã¼ã§ãã¼ãã«åå²ãè¡ãã¾ã(ãã©ã¤ããªãã¼ã§ãªãã¦ãã)ã
ãã¨ãã°ãã©ã®å·ãã©ã®ãã¼ã¿ãã¼ã¹(ãããã¯ãã¼ã¿ãã¼ã¹ãµã¼ã)ã«ä¿åãããå®ç¾©ãã¦ããã¦ã¢ã¡ãªã«ã®ä½æã®ãªã¹ããå·ãã¨ã«ã·ã£ã¼ãã£ã³ã°ããã¨ãã§ãã¾ãã
3) "db_block_map" - ããã¯ã¨ã¦ãè¤éãªã·ã£ã¼ãã£ã³ã°æ¹æ³ã§ããã¼ãã«ãå°ããªãããã¯ã®ã»ããã«åãã¦ãããã«ãã·ã£ã¼ãã£ã³ã°ãããã¼ã¿ãã¼ã¹ãªããã¼ã¿ãã¼ã¹ãµã¼ããªãã«ãããå²ãå½ã¦ã¾ãã
ãããã¯ã追å ãããã¨ãã¯ãã¤ã§ãããããã¯ã¯èªåãã¤ã·ã£ã¼ãã£ã³ã°éã§ãã©ã³ã¹ãã¨ã£ã¦ãã¼ã¿ãã¼ã¹ã«å²ãå½ã¦ããã¾ãã
ãã®æ¹æ³ã¯ã1000ä¸ãã10åã¬ã³ã¼ãã®å·¨å¤§ãªãã¼ãã«ãã¹ã±ã¼ã«ããã®ã«ä½¿ããæ¯è¼çç°¡åã«ã·ã£ã¼ãã£ã³ã°ããªãããä¸çªããæ¹æ³ã§ãã
4) "db_block_group_map" - ãã㯠"db_block_map" ã¨ããä¼¼ãæ¹æ³ã§ãä¸ç¹ã ããç°ãªãã¾ããããã¯ããã®æ¹æ³ã¯
ãã¼ã¿ãã¼ã¹ã®ã»ãã(ãã¼ãã«ã®ã°ã«ã¼ã)ãåãµã¼ãã«æã¦ã¦ãåã°ã«ã¼ããã·ã£ã¼ãã£ã³ã°ã¨ãã¦æ±ãããã¨ããã§ãã
ãã®ã¢ããã¼ãã¯ã¢ããªã±ã¼ã·ã§ã³ãã¹ã±ã¼ã«ããã¾ãã«äºåã«ã·ã£ã¼ãã£ã³ã°ãã¦ããã®ã«ä½¿ãã¾ãã
ã²ã¨ã¤ã®ãµã¼ãããç°¡åã«ã¯ããããã¾ãã10, 20, 50 ã«åå²ãããã¼ã¿ãã¼ã¹ãæã£ã¦ãããã²ã¨ã¤ã®ãã·ã³ã§å¯¾å¿ã§ããªããªã£ããããããã®ãã¼ã¿ãã¼ã¹ãå¥ã®ãµã¼ãã«ç§»ãã¾ãã
ã©ããã£ã¦ã·ã£ã¼ãã£ã³ã°ããããããï¼
ã·ã£ã¼ãã£ã³ã°ã®æ¡å¼µãæå¹ã«ããã«ã¯ããããæºåãå¿ è¦ã§ã:
1) ã·ã£ã¼ãã£ã³ã°ã®ã³ãã¯ã·ã§ã³ãå®ç¾©ãã Rails ã®ã¤ãã·ã£ã©ã¤ã¶ãä½ã (ã¹ã¯ãªãããã¢ããªã±ã¼ã·ã§ã³ã®åæåã®ã¨ãã®ã³ã¼ã)ãããããã®ã³ãã¯ã·ã§ã³ã«ååã¨ãã·ã£ã¼ãã£ã³ã°æ¹æ³ã¨ãåæåã®ããã®ãã®ãªãã·ã§ã³ãæå®ãã¾ãã
2) ã·ã£ã¼ãã£ã³ã°ã使ãããã¢ãã«ã«ã·ã£ã¼ãã£ã³ã°ã®ã³ãã¯ã·ã§ã³ãæ示ãã
3) ã·ã£ã¼ãã£ã³ã°ãããã¢ãã«ãæä½ããåã«ã·ã£ã¼ãã£ã³ã°ãæ示ãã
ãã詳細ã¯ã以ä¸ã®ããã¥ã¡ã³ããã覧ãã ããã
ã·ã£ã¼ãã£ã³ã°(åå²)ã³ãã¯ã·ã§ã³
ã·ã£ã¼ãã£ã³ã°ã³ãã¯ã·ã§ã³ã¯ã·ã³ãã«ãªæ½è±¡åã§ãã¯ã©ã¹ã¿ã®ããã®ã·ã£ã¼ãã£ã³ã°ãã©ã¡ã¼ã¿ãä¸ç®æã§æå®ãããã®ã²ã¨ã¨ããã§è¨å®ãããã®ãã¢ãã«ã§ä½¿ããããã«ãããã¨ãã§ãã¾ãã
ããã¤ãã®ã·ã£ã¼ãã£ã³ã°ã®ã³ãã¯ã·ã§ã³ã®åæåã®ä¾ã¯ä»¥ä¸ã®ã¨ããã§ã:
1) range ãã¼ã¹ã®ã·ã£ã¼ãã£ã³ã°ã³ãã¯ã·ã§ã³ã®ä¾:
TEXTS_SHARDING_RANGES = { 0...100 => :shard1, 100..200 => :shard2, :default => :shard3 } DbCharmer::Sharding.register_connection( :name => :texts, :method => :range, :ranges => TEXTS_SHARDING_RANGES )
2) ããã·ã¥ãããã®ã·ã£ã¼ãã£ã³ã°ã³ãã¯ã·ã§ã³ã®ä¾:
SHARDING_MAP = { 'US' => :us_users, 'CA' => :ca_users, :default => :other_users } DbCharmer::Sharding.register_connection( :name => :users, :method => :hash_map, :map => SHARDING_MAP )
3) ãã¼ã¿ãã¼ã¹ãããã¯ãããã®ã·ã£ã¼ãã£ã³ã°ã³ãã¯ã·ã§ã³ã®ä¾:
DbCharmer::Sharding.register_connection( :name => :social, :method => :db_block_map, :block_size => 10000, # ãããã¯ãã¨ã®ãã¼ã®æ° :map_table => :event_shards_map, # ã·ã£ã¼ãã£ã³ã°ãããã¯ãããããããã¼ãã« :shards_table => :event_shards_info, # ã·ã£ã¼ãã£ã³ã°ã³ãã¯ã·ã§ã³æ å ±ã®ãã¼ãã« :connection => :social_shard_info # ãããã§ã©ã®ã³ãã¯ã·ã§ã³ã使ãã )
ã·ã£ã¼ãã£ã³ã°ã³ãã¯ã·ã§ã³ã®å®ç¾©ãããããã¢ãã«ã§ããã使ããããã«ãªãã¾ã:
class Text < ActiveRecord::Base db_magic :sharded => { :key => :id, :sharded_connection => :texts } end class Event < ActiveRecord::Base set_table_name :timeline_events db_magic :sharded => { :key => :to_uid, :sharded_connection => :social } end
ã·ã£ã¼ãã£ã³ã°ããã¢ãã«ã§ã®ã³ãã¯ã·ã§ã³ã®åãæ¿ãã«ã¤ãã¦
ã·ã£ã¼ãã£ã³ã°ããã¢ãã«ãæä½ããã¨ããå¿
è¦ãããã°ãã¤ã§ããã©ã®åå²å
ã使ããæå®ãããã¨ãã§ãã¾ãã
ã·ã£ã¼ãã£ã³ã°ãã¦ããªãç°å¢ã§ã® DbCharmer ã®ã¤ããããã¨ä¼¼ãæ¹æ³ã§ãã¯ã¨ãªãã¨ã«æ¥ç¶ã管çã§ããã¡ã½ãããç¨æãã¦ãã¾ã:
Event.shard_for(10).find(:conditions => { :to_uid => 123 }, :limit => 5) Text.shard_for(123).find_by_id(123)
ãã®ä»ã«ãrange 㨠hash_map ã®ã·ã£ã¼ãã£ã³ã°ã®æ¹æ³ã§ãããã©ã«ãã®åå²å ã«åãæ¿ãããã¨ãã§ããã¡ã½ãããããã¾ã:
Text.on_default_shard.create(:body => 'hello', :user_id => 123)
ããã¦æå¾ã«ãã·ã¹ãã å ã®åã·ã£ã¼ãã£ã³ã°ã§ãã³ã¼ããå®è¡ããã¡ã½ãããããã¾ã(ç¾å¨ã®ã¨ãããdb_block_map 㨠db_block_group_map ã§ã®ã¿ãµãã¼ãããã¦ãã¾ã):
Event.on_each_shard { |event| event.delete_all }
èªåã®ã·ã£ã¼ãã£ã³ã°æ¹æ³ã®å®ç¾©
DbCharmer ã¯ãã¦ã¼ã¶å®ç¾©ã®ã·ã£ã¼ãã£ã³ã°æ¹æ³ãå¯è½ã§ããèªåã®ã·ã£ã¼ãã£ã³ã°æ¡ãå®è£ ããã«ã¯ãããã¤ããããã¨ãããã¾ã:
1) DbCharmer::Sharding::Method::YourOwnName
ã¨ããååãã¤ãã¦ã¯ã©ã¹ãã¤ãã
2) æä½ã§ããã³ã³ã¹ãã©ã¯ã¿ initialize(config)
ã¨ãå¤å¥ããããã®ã¤ã³ã¹ã¿ã³ã¹ã¡ã½ãã shard_for_key(key)
ããã㯠database.yml
ãã¡ã¤ã«ããrails connection ã¢ããã¿ã®ã³ãã¯ã·ã§ã³ãã©ã¡ã¼ã¿ã®ããã·ã¥ããã³ãã¯ã·ã§ã³åãè¿ããããªã¡ã½ããã«ãªãã§ãããã
3) 以ä¸ã®ããã«ãã¦ãããªãã®ã·ã£ã¼ãã£ã³ã°ã³ãã¯ã·ã§ã³ãç»é²ãã¾ã:
DbCharmer::Sharding.register_connection( :name => :some_name, :method => :your_own_name, # ããªãã®å®ç¾©ããã·ã£ã¼ãã£ã³ã°æ¹æ³ãå°æåã«ããã·ã³ãã«ã§æ¸¡ãã¾ã ... ã»ãã«ãã©ã¡ã¼ã¿ãå¿ è¦ãªãããã ... )
4) ä»ã®æ¨æºã®ã·ã£ã¼ãã£ã³ã°ã³ãã¯ã·ã§ã³ã¨åæ§ã«ãããªãã®å®ç¾©ããã·ã£ã¼ãã£ã³ã°ã³ãã¯ã·ã§ã³ã使ãã¾ã
èªåã§å®ç¾©ããã·ã£ã¼ãã£ã³ã°ã§ãããã©ã«ãã®åå²å ããµãã¼ãããæ¹æ³
ãããon_default_shard
ã¡ã½ãããèªåã®å®ç¾©ããã·ã£ã¼ãã£ã³ã°ã¢ãã«ã§ä½¿ããããªãã2ã¤ãããã¨ãããã¾ã:
1) support_default_shard?
ã¨ããã¤ã³ã¹ã¿ã³ã¹ã¡ã½ãããã·ã£ã¼ãã£ã³ã°ã¯ã©ã¹ã«å®è£
ãã¾ããããã¯ãããã©ã«ãåå²å
ã®æå®ããµãã¼ããããªã true ããããã§ãªããªã false ãè¿ãã¾ãã
2) shard_for_key
ã¡ã½ããã§ã:default
ã®ã·ã³ãã«ããã¼ã¨ãã¦ãµãã¼ãããããå®è£
ãã¾ãã
èªåã§å®ç¾©ããã·ã£ã¼ãã£ã³ã°æ¹æ³ã§ãã·ã£ã¼ãã£ã³ã°åæããµãã¼ãããã«ã¯
ã·ã£ã¼ãã£ã³ã°åæãèªåã§å®ç¾©ããã·ã£ã¼ãã£ã³ã°ã®ã¢ãã«ã§ãµãã¼ãããã«ã¯ãshard_connections
ã¨ããã¤ã³ã¹ã¿ã³ã¹ã¡ã½ããã追å ããå¿
è¦ãããã¾ãããã®ã¡ã½ããã¯ãã·ã£ã¼ãã£ã³ã°ã³ãã¯ã·ã§ã³åããã³ãã¯ã·ã§ã³ã®æ¥ç¶ã§ä½¿ãããè¨å®ã®é
åãè¿ãå¿
è¦ãããã¾ãã
ããã¥ã¡ã³ãã¨è³ªåã«ã¤ãã¦
ãã®ã©ã¤ãã©ãªã«ã¤ãã¦ã®ããããããæ å ±ã«ã¤ãã¦ã¯ãããããã®ãµã¤ã http://dbcharmer.net ãåç §ãã¦ãã ãããDbCharmer ã®å é¨ã®è©³ç´°ã«ã¤ãã¦ç¥ãããã¨ãã¯ãã½ã¼ã¹ã³ã¼ãããã§ãã¯ã¢ã¦ããã¦ãã ããããã©ã°ã¤ã³ã®ã³ã¼ãã¯ãã ããã100%ã®ã«ãã¬ãã¸ãããã¾ããtest-project ãã£ã¬ã¯ããªã«å ¨ã¦ã®ã¦ããããã¹ãã¨ãå®éã«ä½¿ãã¨ãã®ãã¹ããå ¥ã£ã¦ãã¾ãã
ãã®ããã¸ã§ã¯ãã«ã¤ãã¦ä½ã質åãããã¨ãã¯ãä½è ã使ã£ã¦ãã DbCharmer ã¦ã¼ã¶ã¼ãºã°ã«ã¼ãã®ã¡ã¼ãªã³ã°ãªã¹ãã«ã³ã³ã¿ã¯ããããã¨ãã§ãã¾ã:
- ã°ã«ã¼ãæ å ±: http://groups.google.com/group/db-charmer
- ãã®ãã¼ã¸ãè³¼èªãããã[email protected] ã¾ã§ã¡ã¼ã«ãã¦ãã ãã
åä½ãã Ruby 㨠Rails ã«ã¤ãã¦
ãã® gem ã©ã¤ãã©ãªã¯ãããã¤ãã® Ruby ã®ãã¼ã¸ã§ã³ã¨ãRails 2.3, 3.0, 3.1, 3.2 㧠CI ãã¦ãã¾ãã
CI 㯠TravisCI.org (https://travis-ci.org/kovyrin/db-charmer) ã§ã¾ããã¦ãã¾ãã
ãã«ãã¹ãã¼ã¿ã¹ã¯ https://travis-ci.org/kovyrin/db-charmer ãè¦ã¦ãã ãã(åæã§ã¯ç¾å¨ã®ã¹ãã¼ã¿ã¹ã«ã¤ãã¦ã®ããã¸ã¿ãããªç»åã表示ããã¦ãã¾ã)
ä»ã以ä¸ã®çµã¿åããã§ãã«ããã¦ãã¾ã:
ãããã¦ããã® gem 㯠Scribd.com ã®æ¬çªã§ã使ããã¦ãã¾ã (ä¸çã§æã大è¦æ¨¡ãª Rails ã§ä½ããããµã¤ãã®ã²ã¨ã¤ã§ã)ã REE + Rails 2.2, 2.3 ããã㯠Sinatra 㨠Rack ã¢ããªã±ã¼ã·ã§ã³ã§ä½¿ããã¦ãã¾ãã
1.8.0 ããã3.2.8 ã«å¯¾å¿ãã¾ãããã3.2.4 ã¯ãªãã£ã·ã£ã«ã«ãµãã¼ããã¦ãªãã®ã§æ³¨æãã¦ãã ããããã¶ãåãã¨æãã¾ããã対å¿ãã¦ããªããã¼ã¸ã§ã³ã«ã¤ãã¦ãã°ã¬ãã¼ãã¯ããã¤ãã¾ããã
ä½è ã«ã¤ãã¦
ãã®ãã©ã°ã¤ã³ã¯ Scribd.com 社å ã§ä½¿ãããã«ä½ãããããã«ãã以å¤ã®ã¿ãªããã«ä½¿ã£ã¦ãããããã«å ¬éããã¾ãããã³ã¼ãã®ã»ã¨ãã©ã¯ Oleksiy Kovyrin ã«ãã£ã¦æ¸ãããMIT ã©ã¤ã»ã³ã¹ã§å ¬éããã¦ãã¾ãã詳細ã«ã¤ãã¦ã¯ LICENSE ãã¡ã¤ã«ãåç §ãã¦ãã ããã
ãã®ä»ã®ã³ã³ããªãã¥ã¼ã¿ã¯ä»¥ä¸ã®ã¨ããã§ã(ã¢ã«ãã¡ãããé ):
- Allen Madsen
- Andrew Geweke
- Ashley Martens
- Cauê Guerra
- David Dai
- Dmytro Shteflyuk
- Eric Lindvall
- Eugene Pimenov
- Jonathan Viney
- Gregory Man
- Michael Birk
- Tyler McMullen
ä»è¨
- åæ㯠https://github.com/kovyrin/db-charmer/blob/73b72bf1aeb9e7f04bf982830050de861e4f291c/README.rdoc ã§ã
- ç´è¨³ã§ããã«ãããµãªãã£ã¦ãããã解éã誤ã£ã¦ããç®æãããããããã¨æãã¾ã(ææãã¦ããã親åãªããããããããããã§ã)
- Sharding ã¾ãããã¨ãã«ãããã
- ææ¥ã¯ Octopus ã® README èªãäºå®