Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
はじめてのB2B SaaSデータモデリング in 吉祥寺.pm#18
Search
sasaki nobuya
May 17, 2019
Programming
6
11k
はじめてのB2B SaaSデータモデリング in 吉祥寺.pm#18
sasaki nobuya
May 17, 2019
Tweet
Share
More Decks by sasaki nobuya
See All by sasaki nobuya
エンジニアがプロダクトに向き合える組織づくり / Improve Product Development
mnc
6
4.3k
エンジニアがプロダクトに向き合うための意思決定カイゼン
mnc
4
2.3k
はじめてのB2B SaaSデータモデリング in Builderscon 2019
mnc
9
4.3k
AWSインフラ設計とDB設計からわかるB2B SaaSのおもしろさ
mnc
2
1.3k
B2B SaaS開発 Configurabilityとマルチテナントをがんばる α版編
mnc
2
650
本番データを安全に利用する
mnc
0
2.8k
Other Decks in Programming
See All in Programming
Serverless Rust: Your Low-Risk Entry Point to Rust in Production (and the benefits are huge)
lmammino
1
150
『GO』アプリ バックエンドサーバのコスト削減
mot_techtalk
0
160
2025.2.14_Developers Summit 2025_登壇資料
0101unite
0
160
PEPCは何を変えようとしていたのか
ken7253
2
140
パスキーのすべて ── 導入・UX設計・実装の紹介 / 20250213 パスキー開発者の集い
kuralab
3
880
Jasprが凄い話
hyshu
0
110
Ruby on cygwin 2025-02
fd0
0
180
Formの複雑さに立ち向かう
bmthd
1
920
XStateを用いた堅牢なReact Components設計~複雑なClient Stateをシンプルに~ @React Tokyo ミートアップ #2
kfurusho
1
970
生成AIで加速するテスト実装 - ロリポップ for Gamersの事例と 生成AIエディタの活用
kinosuke01
0
100
Honoのおもしろいミドルウェアをみてみよう
yusukebe
1
220
なぜイベント駆動が必要なのか - CQRS/ESで解く複雑系システムの課題 -
j5ik2o
14
4.6k
Featured
See All Featured
GraphQLとの向き合い方2022年版
quramy
44
14k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
356
29k
Producing Creativity
orderedlist
PRO
344
40k
Building an army of robots
kneath
303
45k
How to Ace a Technical Interview
jacobian
276
23k
Building Adaptive Systems
keathley
40
2.4k
Fireside Chat
paigeccino
34
3.2k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
233
17k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
251
21k
The Cult of Friendly URLs
andyhume
78
6.2k
Java REST API Framework Comparison - PWX 2021
mraible
29
8.4k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
49k
Transcript
͡Ίͯͷ B2B SaaS σʔλϞσϦϯά A1Aגࣜձࣾ ࠤʑ Ԇ @__mnc90
Name ࠤʑ Ԇ Company A1Aגࣜձࣾ (ΤʔϫϯΤʔ) Career ৯ϩά → Speee
→ A1AΛڞಉۀ URL twitter.com/__mnc90 manchose.hatenablog.jp About ٕज़ͷऀͱͯ͠RFQΫϥυͷσʔλ ϕʔεઃܭͱΠϯϑϥߏஙɺ৫ͮ͘Γͳ ͲΛ୲
B2BͷऔҾΛϫϯϥϯΫ্ʹ Vision
B2BͷऔҾΛϫϯϥϯΫ্ʹ Vision A1A
ͬͨ΄͏͕Α͍͜ͱͳΜͯ ΄ͱΜͲͰ͖ͳ͍ͱ֮ޛ͢Δ ͬͨ΄͏͕Α͍͜ͱͷ5% ͘Β͍͔͠Ͱ͖ͳ͍ͱߟ͑Δ ελʔτΞοϓͷγεςϜ։ൃ
ͦΕͰఘΊͨΒμϝͳ෦ʹͷΈूத͢Δ ελʔτΞοϓͷγεςϜ։ൃ
Horizontal SaaSΑΓɺ͞Βʹਂ͍υϝΠϯ͕ࣝඞཁ Vertical SaaS
Vertical SaaS ۀքಛԽܕͷSaaSɻoctͳͲʢݐઃϓϩδΣΫτཧSaaSʣ Horizontal SaaS ৬छɾػೳʹಛԽͨ͠SaaSɻSalesforceSmartHRͳͲ Vertical SaaSͱHorizontal SaaS
“DBͷण໋ΞϓϦέʔγϣϯΑΓ͍” @soudai1025 ͞Μ DBͷॏཁੑ
ͬͨ΄͏͕ྑͦ͞͏ͳ͜ͱ TDD IaC GraphQL React TypeScript Serverless Kubernetes GitOps Apex
Atomic Design DDD σʔλ ϞσϦϯά
TDD IaC GraphQL React TypeScript Serverless Kubernetes GitOps Apex Atomic
Design DDD σʔλ ϞσϦϯά ͬͨ΄͏͕ྑͦ͞͏ͳ͜ͱ
͡ΊͯͷB2B SaaSͷσʔλϞσϦϯά
ۀߪങ෦͚ݟੵࠪఆͷSaaS RFQΫϥυ Product
None
1 Multi Tenancyͳςʔϒϧઃܭ 2 جຊNullΛڐՄ͠ͳ͍ 3 Πϕϯτͷநग़ൣғΛυϝΠϯͷத৺ʹߜΔ 4 ֎෦Ωʔͷ࣋ͪํ͔ΒσʔλͷϥΠϑαΠΫϧΛߟ͑Δ
1. Multi Tenancyͳςʔϒϧઃܭ
“ಉ͡γεςϜαʔϏεΛෳͷޓ͍ʹແؔͳར༻ ऀ͕ؒڞಉͰར༻͢ΔํࣜͰɺͦΕͧΕͷར༻ऀΞ Χϯτ໊ͳͲͷࢿ֨ใΛݩʹ۠ผ͞ΕɺͦΕͧΕ γεςϜ্ʹઐ༻ͷྖҬઃఆͳͲ͕༩͑ΒΕΔɻ” Multi Tenancy ग़ల e-words.jp/w/Ϛϧνςφϯτ.html
Ϣʔβʔاۀ͔Β͢Δͱ͕ࣗγεςϜΛಠར༻͍ͯ͠ΔΑ͏ʹݟ͑Δ ࣮ମSingle Source ෳͷςφϯτ͕1ͭͷγεςϜʹ૬Γ
Multi Tenancyͷํ๏ 1 ςφϯτຖʹDatabase or SchemaΛ 2 શςʔϒϧʹtenant_idΧϥϜΛ༻ҙ
Multi Tenancyͷํ๏ 1 ςφϯτຖʹDatabase or SchemaΛ 2 શςʔϒϧʹtenant_idΧϥϜΛ༻ҙ migration࣌ؒͷര૿ͳͲεέʔϥϏϦςΟʹ͋Γ
اۀؒऔҾܕSaaSͷMulti Tenancy ςφϯτΛͲͷ୯ҐͰ࡞͢Δ͔
αϓϥΠϠʔόΠϠʔͷςφϯτʹॴଐ͢Δ όΠϠʔA όΠϠʔB όΠϠʔC αϓϥΠϠD αϓϥΠϠE αϓϥΠϠD αϓϥΠϠG αϓϥΠϠF αϓϥΠϠF
αϓϥΠϠH tenant_id: 1 tenant_id: 2 tenant_id: 3
αϓϥΠϠʔόΠϠʔผςφϯτʹ͢Δ όΠϠʔA όΠϠʔB όΠϠʔC αϓϥΠϠF tenant_id: 1 tenant_id: 2 tenant_id:
3 tenant_id: 4 tenant_id: 5 tenant_id: 6 αϓϥΠϠD αϓϥΠϠE
σʔλͷॴ༗ऀ͔Βςφϯτͷ୯ҐΛߟ͑Δ
Α͋͘Δཁ ୀձޙͷσʔλͷཧআ
αϓϥΠϠʔ͕ड৴ͨ͠ݟੵใόΠϠʔͷୀձޙʹআ͞ΕΔ͖ʁ ϝʔϧΛϝλϑΝʔͱͯ͠ߟ͑Δ
ୀձޙαϓϥΠϠʔ͕ड৴ͨ͠σʔλΔ͖
ςφϯτͷ୯Ґ 1 αϓϥΠϠʔόΠϠʔͷςφϯτʹॴଐ͢Δ 2 αϓϥΠϠʔόΠϠʔผςφϯτʹ͢Δ
ςφϯτͷ୯Ґ 1 αϓϥΠϠʔόΠϠʔͷςφϯτʹॴଐ͢Δ 2 αϓϥΠϠʔόΠϠʔผςφϯτʹ͢Δ
1 όΠϠʔͷୀձޙͷσʔλআ͕όΠϠʔςφϯτ୯ҐͰ আ͢Δ͚ͩͰରԠ͕ྃ͢Δ 2 اۀຖʹݸผͷΞΧϯτཧϙϦγʔΛద༻Ͱ͖Δ ※اۀຖʹϙϦγʔ͕ҟͳΔ͜ͱ͕ଟ͍ 3 αϓϥΠϠʔςφϯτ͕ॏෳ͠ͳ͍ͨΊαϓϥΠϠʔʹͱ ͬͯσʔλͷҰݩཧ͕Ͱ͖Δͱ͍͏ϝϦοτΛఏڙͰ ͖Δ
ϝϦοτ
Example ݟੵґཔ(request_for_quotations)ʹରͯ͠ ݟੵճ(quotations)Λߦ͏߹
request_for_quotations ID produce_number 1 300 2 60 3 1200 ID
unit_price request_for_quotation_id 1 100 1 2 90 2 quotations ૉͳઃܭ
request_for_quotations ID produce_number 1 300 2 60 3 1200 ID
unit_price received_request_for_quotation_id 1 100 1 2 90 2 quotations σʔλͷॴ༗ऀΛߟ͑ͨઃܭ ID produce_number 1 300 2 60 3 1200 received_request_for_quotations ID unit_price request_for_quotation_id 1 100 1 2 90 2 received_quotations
2. جຊNULLΛڐՄ͠ͳ͍
NullableͳΧϥϜ͕͋Δ߹ ϥΠϑαΠΫϧͷҟͳΔσʔλ͕ ಉ͡ςʔϒϧʹೖ͍ͬͯΔ͜ͱ͕ଟ͍ NULLΛڐՄ͠ͳ͍ཧ༝
Example
materials ID name code 1 ϒϥέοτ 391001 2 εϥΠυϘοΫε ϒϥέοτ
NULL 3 ݻఆۚ۩ 369221
materials ID name 1 ϒϥέοτ 2 εϥΠυϘοΫε ϒϥέοτ 3 ݻఆۚ۩
ID material_id code 1 1 391001 2 3 369221 material_codes ͱΓ͋͑ͣNULLແ͘ͳͬͨʂ Ͱɺ͜ΕͰ͍͍ͷ͔ʁ
ͳͥNULLؚ͕·ΕΔͷͩΖ͏
1 material_codeΛͦͦཧ͍ͯ͠ͳ͍اۀ͕͋Δ 2 ࢼ࡞ͷஈ֊Ͱmaterial_codeΛൃ൪ͤͣʹݟੵґཔ Λߦ͍ɺίετͷ֓ࢉΛ֬ೝ͔ͯ͠ΒcodeΛൃ൪͢Δͱ ͍͏ۀϑϩʔ͕͋Δ
1 material_codeΛͦͦཧ͍ͯ͠ͳ͍اۀ͕͋Δ 2 ࢼ࡞ͷஈ֊Ͱmaterial_codeΛൃ൪ͤͣʹݟੵґཔ Λߦ͍ɺίετͷ֓ࢉΛ֬ೝ͔ͯ͠ΒcodeΛൃ൪͢Δͱ ͍͏ۀϑϩʔ͕͋Δ ࢼ࡞ͷݟੵґཔۀͱ͍͏Ϣʔεέʔε͕ͬͦ͝Γൈ͚͍ͯΔ
materials ID name 1 ϒϥέοτ 2 εϥΠυϘοΫε ϒϥέοτ 3 ݻఆۚ۩
ID material_id code 1 1 391001 2 3 369221 production_materials prototype_materials ID material_id 1 2
ϦιʔεͱΠϕϯτΛ۠ผ͢Δɻ ΠϕϯτۀͷهͰ͋Γɺ B2B SaaSͷத৺తଘࡏɻ 3. Πϕϯτͷநग़ൣғΛυϝΠϯͷத৺ʹߜΔ
͔͠͠ɺ͋ΒΏΔϦιʔεʹର͢Δߋ৽ΛΠϕ ϯτͱͯ͠ϞσϦϯάͯ͠͠·͏ͱ࣮ίετ ͕ߴ͘ͳͬͯ͠·͏ɻ ͦͷͨΊɺղܾ͍ͨ͠υϝΠϯͷத৺ʹҐஔ͢ ΔۀͷΈΠϕϯτͱͯ͠ϞσϦϯά͢Δɻ 3. Πϕϯτͷநग़ൣғΛυϝΠϯͷத৺ʹߜΔ ※ @kawasima͞ΜͷൃදͰֶͼ·ͨ͠
Example (materials)ͷߋ৽ʹ͍ͭͯߟ͑Δ
materials ID name updated_at 1 ϒϥέοτA 2019-05-16 09:10:11 2 ۩
2019-05-17 12:51:02 materialsςʔϒϧΛ ߋ৽͢Δ߹
ID name created_at material_id 1 ϒϥέοτA 2019-05-16 09:10:11 1 2
ϒϥέοτB 2019-05-26 11:42:11 1 materials ID name 1 ϒϥέοτ 2 ۩ material_updates ߋ৽Πϕϯτͷςʔϒϧ material_updatesΛ༻ҙ
ID name created_at material_id 1 ϒϥέοτA 2019-05-16 09:10:11 1 2
ϒϥέοτB 2019-05-26 11:42:11 1 materials ID name 1 ϒϥέοτ 2 ۩ material_updates Ռͨͯ͠ɺmaterialsͷߋ৽ۀ RFQΫϥυͷղܾ͢ΔυϝΠ ϯͷத৺ͳͷ͔ʁ
ID name created_at material_id 1 ϒϥέοτA 2019-05-16 09:10:11 1 2
ϒϥέοτB 2019-05-26 11:42:11 1 materials ID name 1 ϒϥέοτ 2 ۩ material_updates ҧ͏ͣɻ ͋͘·Ͱmaterialsͷߋ৽ཤྺͷཧجװγε ςϜ(ERP)Ͱߦ͍ͬͯΔɻ ͳΒɺmaterialsΛߋ৽ͯ͠͠·ͬͯྑ͍ɻ ͠CS༻ʹཤྺ͕΄͔ͬͨ͠߹ผͷσʔλ ετΞʹೖΕΔͳΓ͢ΕΑ͍ɻ
֎෦ΩʔΛ࣋ͭͱ͍͏͜ͱࢀরઌ ͷσʔλ͕ొ͞Εͳ͍ݶΓɺࢀরݩ ͷσʔλΛొͰ͖ͳ͍ͱ͍͏͜ͱɻ 4. ֎෦Ωʔͷ࣋ͪํ͔ΒσʔλͷϥΠϑαΠΫϧΛߟ͑Δ
֎෦Ωʔͷ࣋ͪํΛؒҧ͑ΔͱΞϓϦέʔγϣ ϯ͔Βͷσʔλొॲཧ͕ෳࡶʹͳͬͨΓɺ Ϣʔβʔͷۀʹଇ͞ͳ͍ػೳʹͳΔ͜ͱͰ ϢʔβϏϦςΟͷԼΛট͘͜ͱʹͳΔɻ ֎෦Ωʔͷ࣋ͪํͷॏཁੑ
Example ݟੵґཔ(request_for_quotations)ʹਤ໘ (diagram_images)Λఴͯ͠ૹ৴͢Δɻ
diagram_images ID name path request_for_quotation_id 1 ਤ໘_ver1 /images/xxxx/sample.jpeg 1 2
ਤ໘_ver2 /images/xxxx/sample2.jpeg 1 3 ਤ໘_ver3 /images/xxxx/sample3.jpeg 2 request_for_quotations ID produce_number 1 300 2 60
diagram_images ID name path request_for_quotation_id 1 ਤ໘_ver1 /images/xxxx/sample.jpeg 1 2
ਤ໘_ver2 /images/xxxx/sample2.jpeg 1 3 ਤ໘_ver3 /images/xxxx/sample3.jpeg 2 request_for_quotations ID produce_number 1 300 2 60 diagram_iamgesඞͣ request_for_quotationsͷ࡞ ޙʹొ͢Δʁ
ۀΛߟ͑Δ 1 ݟੵґཔ࡞લʹઃܭ෦͔Βਤ໘ϑΝΠϧ͚ͩڞ༗͞Ε Δͱ͍͏Ϣʔεέʔε 2 ਤ໘ϑΝΠϧΛΞοϓϩʔυͤͣʹϚελʔͱͯ͠ొ ͓͖ͯ͠ɺݟੵґཔ࣌ʹͦΕΛࢀরར༻͢Δͱ͍͏Ϣ ʔεέʔε
ۀΛߟ͑Δ 1 ݟੵґཔ࡞લʹઃܭ෦͔Βਤ໘ϑΝΠϧ͚ͩڞ༗͞Ε Δͱ͍͏Ϣʔεέʔε 2 ਤ໘ϑΝΠϧΛΞοϓϩʔυͤͣʹϚελʔͱͯ͠ొ ͓͖ͯ͠ɺݟੵґཔ࣌ʹͦΕΛࢀরར༻͢Δͱ͍͏Ϣ ʔεέʔε ඞͣ͠ݟੵґཔ࡞ޙʹਤ໘Λొ͢Δͱ͍͏Θ͚Ͱͳ͍
diagram_images ID name path 1 ਤ໘_ver1 /images/xxxx/sample.jpeg 2 ਤ໘_ver2 /images/xxxx/sample2.jpeg
3 ਤ໘_ver3 /images/xxxx/sample3.jpeg request_for_quotations ID produce_number 1 300 2 60 ID diagram_image_id request_for_quotation_id 1 1 1 2 2 1 3 3 2 attached_diagram_images diagram_imagesͱ request_for_quotationsͷ σʔλొॱෆಉʹͳͬͨ
υϝΠϯΤΩεύʔτ͔ΒͷใͷҾ͖ग़͠ํ ൪֎ฤ
1 ୟ͖ͱͳΔERDΛ࡞Δ 2 ERDͷؔ࿈͝ͱʹυϝΠϯʹదͨ͠ྫΛ༻͍ͳ͕Β࣮ମΛ өͰ͖͍ͯΔ͔υϝΠϯΤΩεύʔτʹ֬ೝ͢Δ
Example ֎෦Ωʔͷ࣋ͪํɺNULLͷՄೳੑɺςʔϒϧ ͷؔ࿈(1:n/1:1/n:n)ʹ͍ͭͯ1ͭͣͭྫΛग़ ͠ͳ͕Βʮ◦◦͕ෳʹͳΔ͜ͱͬͯ͋Γ·͢ ͔ʁʯͱ࣭͍ͯ͘͠ɻ
Example diagram_images ID path request_for_quotation_id 1 /images/xxxx/sample.jpeg 1 2 /images/xxxx/sample2.jpeg
1 3 /images/xxxx/sample3.jpeg 2 request_for_quotations ID produce_number 1 300 2 60
Example diagram_images ID path request_for_quotation_id 1 /images/xxxx/sample.jpeg 1 2 /images/xxxx/sample2.jpeg
1 3 /images/xxxx/sample3.jpeg 2 request_for_quotations ID produce_number 1 300 2 60 ਤ໘ϑΝΠϧͬͯݟੵґཔʹରͯ͠ෳ ఴ͢Δ͜ͱ͋Γ·͔͢ʁ me
Example diagram_images ID path request_for_quotation_id 1 /images/xxxx/sample.jpeg 1 2 /images/xxxx/sample2.jpeg
1 3 /images/xxxx/sample3.jpeg 2 request_for_quotations ID produce_number 1 300 2 60 ݟੵґཔΛ࡞͢Δલʹਤ໘ϑΝΠϧ͚ͩ ଞ෦͔Βڞ༗͞ΕΔ͜ͱ͋Γ·͔͢ʁ me
υϝΠϯΤΩεύʔτͷґཔͷํ υϝΠϯΤΩεύʔτ͔Β͢ΔͱɺʮͳΜͰͦ ΜͳʹΤοδέʔε·Ͱؾʹ͢ΔΜʁʯͱ͍͏ ؾ࣋ͪʹͳΓ͍͢ɻ ͔ͩΒɺʮؾ͍ͯͳ͍Τοδέʔε·Ͱؾͮ ͚Δ͜ͱ͕ࠓޙͷγεςϜ։ൃͷεϐʔυΛ ͘͢Δʯͱ͍͏͜ͱΛ͑ͯɺ͍ΖΜͳέʔε ͷ૾ΛΒ·ͤͯΒ͏Α͏ʹ͢Δɻ
We are hiring!