Slide 1

Slide 1 text

ෳ਺%#ͱ3BJMT ,PIFJ4V[VLJ !FBHMFUNU $PPLQBE*OD 1

Slide 2

Slide 2 text

Ξ΢τϥΠϯ ෳ਺%#Λ3BJMT͔Βѻ͏ %#෼ׂ SXTQMJUUJOH ෳ਺%#τϥϒϧ ࠷ۙͷ೰Έ !2

Slide 3

Slide 3 text

ෳ਺%# 3BJMTͷόʔδϣϯΞοϓ Λ୲౰ͨ͠ ಛʹ"DUJWF3FDPSEͷมߋʹରԠ͍ͯͨ͠Β3BJMT ʹ͓͚Δෳ਺%#ͱ޲͖߹͏͜ͱʹʜʜ !3

Slide 4

Slide 4 text

ෳ਺%#ͷछྨ ͍͔ͭ͘छྨ͕͋Δ ୯ʹςʔϒϧ͕ผͷ%#ʹଘࡏ͍ͯ͠Δ %#෼ׂ NBTUFSTMBWFߏ੒ͰSXTQMJUUJOH͍ͯ͠Δ γϟʔσΟϯά γϟʔσΟϯά͸෼͔Βͳ͍ͷͰɺ্ͭʹ͍ͭͯ !4

Slide 5

Slide 5 text

%#෼ׂ FTUBCMJTI@DPOOFDUJPOͰ઀ଓઌΛม͑Δ class Db1Model1 < ActiveRecord::Base establish_connection :"#{Rails.env}_db1" end ! class Db1Model2 < ActiveRecord::Base establish_connection :"#{Rails.env}_db1" end !5

Slide 6

Slide 6 text

%#෼ׂ ͜ΕͰ΋Ͱ͖Δ͚ͲɺίωΫγϣϯ਺͕ٸ૿͢Δ BQQ͸େৎ෉Ͱ΋%#͕଱͑ΒΕͳ͍ !6

Slide 7

Slide 7 text

"3ͷίωΫγϣϯ .PEFMDPOOFDUJPO͸ɺΫϥε֊૚Λ্Γͳ͕Β FTUBCMJTI@DPOOFDUJPO͍ͯ͠Δ࠷ॳͷϞσϧΫϥε ͷίωΫγϣϯϓʔϧΛ࢖͏ ୯Ұ%#ͷͱ͖͸"DUJWF3FDPSE#BTFͷΈ ͢΂ͯͷϞσϧ͕"DUJWF3FDPSE#BTFͷίωΫ γϣϯϓʔϧΛ࢖͏ !7

Slide 8

Slide 8 text

"3ͷίωΫγϣϯ ֤ϞσϧͰͦΕͧΕFTUBCMJTI@DPOOFDUJPO͢Δͱɺ Ϟσϧͷ਺ʹൺྫͨ͠ίωΫγϣϯ͕࡞ΒΕΔ ਺ඦͷϞσϧ͕͋Δͱݱ࣮తͰ͸ͳ͍ !8

Slide 9

Slide 9 text

ίωΫγϣϯڞ༗ FTUBCMJTI@DPOOFDUJPO͢Δ͚ͩͷந৅ΫϥεΛఆٛ ͢Δ class Db1Base < ActiveRecord::Base self.abstract_class = true establish_connection :"#{Rails.env}_db1" end !9

Slide 10

Slide 10 text

ίωΫγϣϯڞ༗ ECʹ͋Δςʔϒϧ Ϟσϧ ͸%C#BTFΛܧঝ͢ ΔΑ͏ʹ͢Δ class Db1Model1 < Db1Base end ! class Db1Model2 < Db1Base end !10

Slide 11

Slide 11 text

ίωΫγϣϯڞ༗ ίωΫγϣϯϓʔϧͷͨΊʹجఈΫϥε%C#BTFΛ ༻ҙ͢Δ ܧঝͨ͠%C.PEFM %C.PEFM͸%C#BTFͷ ίωΫγϣϯϓʔϧΛ࢖͏ !11

Slide 12

Slide 12 text

SXTQMJUUJOH ઀ଓઌΛ੾Γସ͍͑ͨͱ͖ʹFTUBCMJTI@DPOOFDUJPO͢Δ ϝϦοτ 3BJMTඪ४ͷػೳ͚ͩͰͰ͖Δ σϝϦοτ FTUBCMJTI@DPOOFDUJPOͷ౓ʹ઀ଓ͠௚͢͜ͱʹͳΔ සൟͳ੾Γସ͑ʹ͸޲͔ͳ͍ !12

Slide 13

Slide 13 text

SXTQMJUUJOH !13 class SummaryBase < ActiveRecord::Base self.abstract_class = true establish_connection :"#{Rails.env}_summary" ! def self.with_master establish_connection :"#{Rails.env} _summary_writable" yield ensure establish_connection :"#{Rails.env}_summary" end end ! ! !

Slide 14

Slide 14 text

SXTQMJUUJOH ίωΫγϣϯΛҡ࣋ͭͭ͠ɺසൟʹ੾Γସ͍͑ͨ Ϟσϧ͕ίωΫγϣϯϓʔϧΛछྨ͔࣋ͯ͠ͳ͍ͷ ͰɺϨʔϧ͔Β֎Εͳ͚Ε͹ͳΒͳ͍ Ͱ͖Δ͚ͩඪ४తͳํ๏Ͱ࣮ݱ͢ΔͨΊʹ TXJUDI@QPJOUͱ͍͏HFNΛ࡞੒ͯ͠Ҡߦ IUUQTHJUIVCDPNFBHMFUNUTXJUDI@QPJOU !14

Slide 15

Slide 15 text

SXTQMJUUJOH !15 SwitchPoint.configure do |config| config.define_switch_point :main, readonly: :"#{Rails.env}_slave" ! config.define_switch_point :bargain, readonly: :"#{Rails.env}_bargain_slave", writable: :"#{Rails.env}_bargain" ! … end

Slide 16

Slide 16 text

SXTQMJUUJOH !16 class MainBase < ActiveRecord::Base self.abstract_class = true use_switch_point :main end ! class BargainBase < ActiveRecord::Base self.abstract_class = true use_switch_point :bargain end ! class User < MainBase; end class Recipe < MainBase; end ! class Bargain::Shop < BargainBase; end class Bargain::Leaflet < BargainBase; end

Slide 17

Slide 17 text

SXTQMJUUJOH !17 User.with_readonly { User.find(id) } ! ! Recipe.with_writable do Recipe.create(recipe_params) end

Slide 18

Slide 18 text

ෳ਺%#τϥϒϧ

Slide 19

Slide 19 text

%#Λލ͙+0*/ Ϟσϧ"ɺ#͕ผͷ%#ʹ͋Δ "ͱ#͸+0*/Ͱ͖ͳ͍ ͔͠͠ɺJODMVEFTΛ࢖ͬͨͱ͖ʹಛఆͷঢ়گԼͰ͸ "DUJWF3FDPSEʹΑͬͯ+0*/͕࢖ΘΕͯ͠·͏ !19

Slide 20

Slide 20 text

%#Λލ͙+0*/ !20 class A < ActiveRecord::Base end ! class B < ActiveRecord::Base belongs_to :a end irb(main):001:0> B.includes(:a).pluck(:id) (0.2ms) SELECT `bs`.`id` FROM `bs` LEFT OUTER JOIN `as` ON `as`.`id` = `bs`.`a_id`

Slide 21

Slide 21 text

%#Λލ͙+0*/ !21 class A < ActiveRecord::Base end ! class B < ActiveRecord::Base belongs_to :a end irb(main):001:0> B.preload(:a).pluck(:id) (0.2ms) SELECT `bs`.`id` FROM `bs`

Slide 22

Slide 22 text

EBUBCBTF@SFXJOEFS EBUBCBTF@DMFBOFSʹ୅ΘΔHFN !BNBUTVEB͞Μ͕࡞ͬͨ This strategy was originally devised and implemented by Shingo Morita (@eudoxa) at COOKPAD Inc. IUUQTHJUIVCDPNBNBUTVEBEBUBCBTF@SFXJOEFSDSFEJU !22

Slide 23

Slide 23 text

EBUBCBTF@SFXJOEFSͱෳ਺%# ෳ਺%#؀ڥͰ࠷ॳͷ%BUBCBTF3FXJOEFSDMFBO@BMM͕͏·͘ಈ͔ ͳ͍໰୊ "DUJWF3FDPSE#BTFҎ֎ͷίωΫγϣϯΛ͏·͘ͱΕͯͳ͍ ࠷ऴతʹWͰղܾ IUUQTHJUIVCDPNBNBUTVEBEBUBCBTF@SFXJOEFSDPNQBSF WW TODO: Write documentation and specs about multiple databases. !23

Slide 24

Slide 24 text

EBUBCBTF@SFXJOEFSͱෳ਺%# ෳ਺ͷ%#͕ҟͳΔBEBQUFSΛ࢖͍ͬͯΔͱ͖ʹςʔ ϒϧ͕ফ͞Εͳ͍໰୊ .Z42-1PTUHSF42-ͳͲ !24

Slide 25

Slide 25 text

EBUBCBTF@SFXJOEFSͱෳ਺%# EBUBCBTF@SFXJOEFSͷॳظԽ࣌ʹ͸·ͩผ%#ͷ BEBQUFS͕ಡΈࠐ·Ε͍ͯͳ͍͜ͱ͕ݪҼ IUUQTHJUIVCDPNBNBUTVEBEBUBCBTF@SFXJOEFSQVMM !25

Slide 26

Slide 26 text

࠷ۙͷ೰Έ

Slide 27

Slide 27 text

ෳ਺%#ෳ਺ΞϓϦέʔγϣϯ ෳ਺ͷΞϓϦέʔγϣϯ͕ϞσϧΛڞ༗͍ͯ͠Δ DPPLQBEDPNຊମ 8FC"1*αʔό ؅ཧը໘ όον !27

Slide 28

Slide 28 text

ෳ਺%#ෳ਺ΞϓϦέʔγϣϯ ͢΂ͯͷΞϓϦέʔγϣϯ͕͢΂ͯͷ%#ʹ઀ଓ͢Δ Θ͚Ͱ͸ͳ͍ ؅ཧը໘͔Β͔͠࢖ΘΕͳ͍%# ؅ཧը໘ͱόον͔Β͔͠࢖ΘΕͳ͍%# ʜʜ !28

Slide 29

Slide 29 text

ෳ਺%#ෳ਺ΞϓϦέʔγϣϯ Ϟσϧ͸֤ΞϓϦέʔγϣϯͰڞ༗͞Ε͍ͯΔ ҰํͰɺͦͷΞϓϦέʔγϣϯ͔Β࣮ࡍʹ͸࢖ΘΕͳ ͍%#ͷ઀ଓઃఆΛEBUBCBTFZNMʹॻ͖ͨ͘ͳ͍ ྫ͑͹όον͔Β͔͠࢖ΘΕͳ͍%#Λߋ৽ͨ࣌͠ʹɺ 8FC"1*αʔόʹ΋EBUBCBTFZNMΛ഑෍͢Δඞཁ ͕͋ΔΑ͏ͳঢ়گ͸ආ͚͍ͨ !29

Slide 30

Slide 30 text

ෳ਺%#ෳ਺ΞϓϦέʔγϣϯ Ϟσϧ͕ڞ༗͞Ε͍ͯΔͷͰɺىಈ࣌ʹ EBUBCBTFZNMʹॻ͔Ε͍ͯͳ͍%#΁ͷ FTUBCMJTI@DPOOFDUJPO͕࣮ߦ͞Εͯ͠·͏ "DUJWF3FDPSE"EBQUFS/PU4QFDJpFEΛѲΓ௵͢Ϟ ϯΩʔύον ඇৗʹͭΒ͍ʜʜԿ͔ྑ͍ํ๏͕͋Ε͹ੋඇ !30