- 投稿日:2020-10-20T18:11:53+09:00
RDSにORM使ったけどモヤモヤが止まらないのでぜんぶ吐き出す!!!
転職活動でバックエンドも出来るぜ!アピールとしてポートフェリオぽいの作った方が良いかもね・・?という事で、こんなリポジトリ作ってたわけなんですけど、コード書いてて気づいた事つらつらと書きます。
何時もの奔放な個人開発じゃなく、気づき、ハマりのQiitaらしいアウトプットってことで。ちゃんと調べて書けーって怒られそうな気もするけどw
ORMの仕様とか親切で大惨事になるかも・・?
今回Goの代表的なORMであるgormを使いましたが、Delete投げる時に消す情報を先に取得しないまま、動かすとテーブル内のレコードすべてが消えるのが仕様らしいんです!
jsonData.Id = Ids DBMS.First(&jsonData) // この行無いと滅亡です! DBMS.Delete(&jsonData)今回一番作ってて?となったとこ。ありえん。
RDS?ORM?どっちが悪いでしょーか
RDSが一時的に不調っぽい時に動かすとダンマリでタイムアウトせず・・
DB, err := gorm.Open(DBTYPE, CONNECT) // ずーーっと接続中 if err != nil { fmt.Println("RDS access error!") panic(err.Error()) }せめてエラー応答して欲しかったなと。
Model定義の順番で構造が崩れる!?
type test struct { gorm.Model Number int `gorm:"primary_key"` }みたいに先にgorm.Modelを書いて、DB側のテーブルの最初にNumberが居るとgorm.Modelから取得した値がNumberに浸食してきます。
type test struct { Number int `gorm:"primary_key"` gorm.Model }こんなふうにDBスキーマにもよるけど最後に書いた方が無難。
残るモヤ
と、まあ学びを通じて残るモヤがまだまだありました。。
API書く練習して一通りORMからCRUDはまでは出来たけど、サービスがスケールする前提ってどうコードにするんだろ。APIサーバって"歩"のイメージで自身でスケール考慮しないような気がするが、、
— いもいもくん (@ma_anago) October 11, 2020手前にLBやKong入れる、バックエンドはマネージドでスケールするイメージなんすよね。
— いもいもくん (@ma_anago) October 11, 2020
API間でマルチキャストぽい通信して経路断も防ぐ、とかさあ。APIサーバー自身もマネージドサービスの方が良くね?という疑問
ORMの利点勉強しててやっぱ分からなかった。自動マイグレとか既に居るサービスには効果無いし。柔軟にDBからひっぱるなら、やっぱ生SQL流して変数に取り込んだ方が分かりやすくないー?って。むずいなチーム開発経験無いと変にズレてく気がして怖いわ
— いもいもくん (@ma_anago) October 11, 2020インジェクション食らうリスクは一旦おいといて、ORM無しと生SQLの処理速度って差があるんだろうか?
— いもいもくん (@ma_anago) October 11, 2020
Goみたいな軽量級でそこそこ差が出るならORMのメリットあんまないよねーにはなるようなORM以前からDB叩いてきたバックエンドエンジニアにはどう映ってるの?という疑問
gitのprivateリポジトリって草生えんのか!
— いもいもくん (@ma_anago) October 17, 2020
習慣的にコード書いてコミットしてるんでいつも通り生えて欲しいんです。昨日進めたっけな?とかわからんよな一行レベルでcommitし直ししたくて、git reset --hard HEAD~すると前回commitに戻ったうえにVSCodeが自動でホットリロードするの結構な嫌がらせ感ある。
— いもいもくん (@ma_anago) October 18, 2020VSCodeとかエコシステムが逆に足引っ張ってねーかい?という疑問
こういうアンチナレッジが残る事自体が学びなんでしょうけど、技術的な選定して舵を取るという意味でテックリードって大事なんやなと改めて思った。むしろテックリード不在の組織ってこういうのどうオトしてんだろ??
- 投稿日:2020-10-20T10:03:22+09:00
Goでbit全探索
Donutsプロコンチャレンジ
B - Tokyo 7th シスターズ
https://atcoder.jp/contests/donuts-2015/tasks/donuts_2015_2package main import( "fmt" "bufio" "os" "strconv" "strings" "go/types" "go/token" ) var rdr=bufio.NewReaderSize(os.Stdin,10000000) func readLine()string{ l,_,_:=rdr.ReadLine() return string(l) } func readInts()[]int{ s:=strings.Split(readLine()," ") res:=[]int{} for i:=0;i<len(s);i++{ i,_:=strconv.Atoi(s[i]) res=append(res,i) } return res } func chmax(x,y int)int{if x>=y{return x}else{return y}} func contains(x int,sl []int)bool{ res:=false for i:=0;i<len(sl);i++{ if sl[i]==x{ res=true break } } return res } func main(){ tmp:=readInts() n,m:=tmp[0],tmp[1] A:=readInts() B:=[]int{} I:=[][]int{} for i:=0;i<m;i++{ tmp:=readInts() B=append(B,tmp[0]) I=append(I,tmp[2:]) for j:=0;j<tmp[1];j++{ I[i][j]-- } } //fmt.Println(n,A) //fmt.Println(B) //fmt.Println(I) ans:=0 for bits:=0;bits<(1<<uint64(n));bits++{ score:=0 combo:=[]int{} for i:=0;i<n;i++{ if (bits>>uint64(i))&1==1{ score+=A[i] //本人の得点 combo=append(combo,i) } } if len(combo)>9{ continue } cnt:=0 //bonus:=0 for i:=0;i<m;i++{ cnt=0 for j:=0;j<len(combo);j++{ if contains(combo[j],I[i]){ cnt++ } } if cnt>=3{ score+=B[i] //bonus+=B[i] } } //if score==6100{fmt.Println("score",score,"combo",combo,"cnt",cnt,"B[i]",bonus)} ans=chmax(ans,score) } fmt.Println(ans) }