$30 off During Our Annual Pro Sale. View Details »

操作履歴/時点指定アクセスの実現 - BiTemporal Data Model の実践 / ...

f440
March 23, 2019

操作履歴/時点指定アクセスの実現 - BiTemporal Data Model の実践 / Implementing command history and temporal access

この資料で説明している ActiveRecord::BiTemporal は https://github.com/kufu/activerecord-bitemporal よりアクセスできます。

以下、セッション説明:

データはWebアプリケーションの中心であり、最も重要なものです。私の勤めるSmartHRでも、人事情報を軸とするWebサービスを展開する事業者として最大限の注意を払って運用を行っています。

データは活動によって刻々と変わっていくものですが、通常のWebアプリケーションでは最新の情報しか表現できていません。そのため、いつ・どのような変更を加えたのかを知りたい、あるいはある時点の情報にアクセスしたいといった要望には応えることができませんでした。SmartHRでは入退社や被扶養者の追加など多様なライフイベントに応じてデータの変更が発生するため、その変遷も表現したいというニーズがかねてよりありました。

この問題を解決するために、私達はBiTemporal Data Modelというデータ構造を導入しています。これにより、時間を指定したアクセスや変更の変遷なども表現できるようになりました。

本セッションではBiTemporal Data Modelとはなにかといった基本的なことから、実戦投入してみて気づいた点、苦労話などを話します。

f440

March 23, 2019
Tweet

Other Decks in Programming

Transcript

  1. ࣾձอݥ౳ͷॻྨΛ ࣗಈ࡞੒ ैۀһ৘ใΛ σʔλϕʔεԽ ໾ॴ΁γʔϜϨεʹ ΦϯϥΠϯਃ੥ ਓࣄ৘ใΛ Χϯλϯʹऩू ˔˔˔˔ ˔˔˔˔˔˔˔˔

    ˔˔˔˔˔˔˔˔ ˔˔˔˔ ˔˔˔˔˔˔˔˔ ˔˔˔˔ ˔˔˔˔˔˔˔˔ ˔˔˔˔ ˔˔˔˔˔˔˔˔ ˔˔˔˔ ˔˔˔˔˔˔˔˔ ˔˔˔˔ ˔˔˔˔˔˔˔˔ ˔˔˔˔ ˔˔˔˔˔˔˔˔ ˔˔˔˔ ˔˔˔˔˔˔˔˔ ˔˔˔˔ ˔˔˔˔˔˔˔˔ ˔˔˔˔ ˔˔˔˔˔˔˔˔ 4NBSU)3͸ɺਓࣄɾ࿑຿ʹؔ͢Δखଓ͖ͷ ࣗಈԽΛ໨ࢦ͢Ϋϥ΢υܕιϑτ΢ΣΞͰ͢ɻ
  2. ࠓޙͷํ਑ ݱࡏ ਓࣄ޲͚ 4BB4 ސ٬ج൫ ʢਓࣄɾैۀһʣ ਓࣄ%# ʢձࣾɾݸਓʣ ஷ·Δࢿ࢈ কདྷ

    Ξοϓηϧ ϓϩμΫτ ϓϥοτ ϑΥʔϜԽ ۚ༥঎඼ ʢ'JO5FDIʣ কདྷ
  3. ࠓޙͷํ਑ ݱࡏ ਓࣄ޲͚ 4BB4 ސ٬ج൫ ʢਓࣄɾैۀһʣ ਓࣄ%# ʢձࣾɾݸਓʣ ஷ·Δࢿ࢈ কདྷ

    Ξοϓηϧ ϓϩμΫτ ϓϥοτ ϑΥʔϜԽ ۚ༥঎඼ ʢ'JO5FDIʣ কདྷ ຊ೔ͷ࿩୊
  4. # db/migrate/*.rb class CreateUsers < ActiveRecord::Migration[5.2] def change create_table :users

    do |t| t.string :name t.string :email t.timestamps end end end 3VCZPO3BJMTσϑΥϧτ
  5. # db/schema.rb
 create_table "users", force: :cascade do |t| t.string "name"

    t.string "email" t.datetime "created_at", null: false t.datetime "updated_at", null: false end 3VCZPO3BJMTσϑΥϧτ
  6. VOJUFNQPSBMEBUBNPEFM *% ໾৬ ։࢝ ऴྃ    ˠ 

    ෦௕   ʮdͷظؒ͸ʰ܎௕ʱͩͬͨʯ͜ͱ͕ൃ֮
  7. VOJUFNQPSBMEBUBNPEFM *% ໾৬ ։࢝ ऴྃ    ˠ 

    ܎௕    ෦௕   ʮdͷظؒ͸ʰ܎௕ʱͩͬͨʯ͜ͱ͕ൃ֮
  8. VOJUFNQPSBMEBUBNPEFM *% ໾৬ ։࢝ ऴྃ    ˠ 

    ܎௕    ෦௕   ʮdͷظؒ͸ʰ܎௕ʱͩͬͨʯ͜ͱ͕ൃ֮ ͱ͍͏৘ใ͕Ͳ͜ʹ΋ͳ͍ʂ
  9. *% ໾৬ ։࢝ ऴྃ ௥Ճ ࡟আ    㱣

     㱣 ೖࣾ ༗ޮظؒ γεςϜతͳظؒ CJUFNQPSBMEBUBNPEFM
  10. *% ໾৬ ։࢝ ऴྃ ௥Ճ ࡟আ    㱣

     㱣ˠ ෦௕ʹঢ֨ CJUFNQPSBMEBUBNPEFM
  11. *% ໾৬ ։࢝ ऴྃ ௥Ճ ࡟আ    㱣

     㱣ˠ      㱣  ෦௕  㱣  㱣 ෦௕ʹঢ֨ CJUFNQPSBMEBUBNPEFM
  12. *% ໾৬ ։࢝ ऴྃ ௥Ճ ࡟আ    㱣

           㱣  ෦௕  㱣  㱣ˠ ୀࣾ CJUFNQPSBMEBUBNPEFM
  13. *% ໾৬ ։࢝ ऴྃ ௥Ճ ࡟আ    㱣

           㱣  ෦௕  㱣  㱣ˠ  ෦௕    㱣 ୀࣾ CJUFNQPSBMEBUBNPEFM
  14. *% ໾৬ ։࢝ ऴྃ ௥Ճ ࡟আ    㱣

           㱣ˠ  ෦௕  㱣    ෦௕    㱣 ʮdͷظؒ͸ʰ܎௕ʱͩͬͨʯ͜ͱ͕ൃ֮ CJUFNQPSBMEBUBNPEFM
  15. *% ໾৬ ։࢝ ऴྃ ௥Ճ ࡟আ    㱣

           㱣ˠ      㱣  ՝௕    㱣  ෦௕  㱣    ෦௕    㱣 ʮdͷظؒ͸ʰ܎௕ʱͩͬͨʯ͜ͱ͕ൃ֮ CJUFNQPSBMEBUBNPEFM
  16. ࢓૊Έ *% ໾৬ ։࢝ ऴྃ ௥Ճ ࡟আ   

    㱣        㱣  ෦௕  㱣  㱣 JE CJUFNQPSBM@JE QPTJUJPO WBMJE@GSPN WBMJE@UP DSFBUFE@BU EFMFUFE@BU     㱣         㱣   ෦௕  㱣  㱣 σʔλϕʔεͰදݱ
  17. ࢓૊Έ JE CJUFNQPSBM@JE QPTJUJPO WBMJE@GSPN WBMJE@UP DSFBUFE@BU EFMFUFE@BU  

      㱣   JEʜ3BJMTඪ४ CJUFNQPSBM@JE
 ʜૢ࡞ର৅ΛҰҙʹ͢ΔͨΊͷ*%
  18. ࢓૊Έ JE CJUFNQPSBM@JE QPTJUJPO WBMJE@GSPN WBMJE@UP DSFBUFE@BU EFMFUFE@BU  

      㱣   WBMJE@GSPN WBMJE@UPʜ༗ޮظؒ DSFBUFE@BU EFMFUFE@BUʜγεςϜظؒ
  19. Ϟσϧʹ"3#J5FNQPSBM༻Λ༻ҙ 
 ./bin/rails generate model User \ name:string \ bitemporal_id:integer

    \ valid_from:datetime \ valid_to:datetime \ deleted_at:datetime ར༻ํ๏
  20. ࢓૊Έ irb(main):002:0> User.find(1) User Load (0.8ms) SELECT "users".* FROM "users"

    
 WHERE "users"."deleted_at" IS NULL 
 AND "users"."valid_from" <= '2019-03-10 07:40:32.238952' 
 AND "users"."valid_to" > '2019-03-10 07:40:32.238952'
 AND "users"."bitemporal_id" = $1 
 LIMIT $2 
 [["bitemporal_id", 1], ["LIMIT", 1]] ҎԼΛࣗಈతʹ࣮ࢪ
 ɾ࡟আ͞Ε͍ͯͳ͍͔ͷ൑ఆ ɾ༗ޮ͔Ͳ͏͔ͷ൑ఆ
 ɾJEΛCJUFNQPSBM@JEʹಡΈସ͑
  21. ˰%#ϨϕϧͰ੔߹ੑΛ୲อͨ͠΄͏͕͍͍ ͭΒ͍ϙΠϯτʢʣϢχʔΫ੍໿ -- ॏͳΓνΣοΫ (PostgreSQL) ALTER TABLE users ADD EXCLUDE

    USING GIST (bitemporal_id WITH =, tsrange(valid_from, valid_to) WITH &&, COALESCE(deleted_at, '9999-12-31 00:00:00')WITH =);
  22. ɾ#JUFNQPSBM%BUB5IFPSZBOE1SBDUJDF 5PN+PIOTUPO  ɹ*4#/ ɾཤྺςʔϒϧ ɹIUUQTVTFSpSTUJLZVDPKQFOUSZIJTUPSZUBCMF ɾ5FNQPSBMEBUBCBTF8JLJQFEJB ɹIUUQTFOXJLJQFEJBPSHXJLJ5FNQPSBM@EBUBCBTF#JUFNQPSBM@SFMBUJPOT ɾ5FNQPSBM%BUB5JNF5SBWFMJO1PTUHSF42- ɹIUUQTXJLJQPTUHSFTRMPSHJNBHFT'PTEFN1PTUHSFTRM5FNQPSBMQEG

    ɾσʔλཤྺ؅ཧͷͨΊͷςϯϙϥϧσʔλϞσϧͱ3FMBEPNPͷ঺հ ɹIUUQTXXXTMJEFTIBSFOFUJUPIJSPKKVHDDDTQSJOHCJUFNQPSBMEBUBNPEFMJOHBOESFMBEPNP ɾ1BQFS5SBJM͸Ͳ͏΍ͬͯ"DUJWF3FDPSEͷόʔδϣϯ؅ཧΛ͍ͯ͠Δ͔ ɹIUUQTRJJUBDPNZVLV@UJUFNTDFFDCB ࢀߟࢿྉ