Open25

mysqlの勉強したほうがいいかも

kajirikajirikajirikajiri

typeormをやろうとしたが、mysqlを知りたくなった。
railsのactive recordは表にほとんどsqlの知識が出てこなかった。
しかし、typeormの流れとして、Entityファイルでモデルを作成。Entityファイルからmigrationファイルを作成。migrationを実行となるのだが、migrationファイルが、sqlそのまま書かれて生成される。
こんなの

CREATE TABLE `scrap_user_relation` (`userId` varchar(255) NOT NULL, `createdAt` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), `scrapId` varchar(36) NOT NULL, PRIMARY KEY (`scrapId`)) ENGINE=InnoDB

なんとなくわかるんだけど、sqlもう少しわかってないとちょっと怖い気がしてきた

kajirikajirikajirikajiri

いやー、しかし、mysqlの構文はある程度わかるしググって目的から調べた方がいいな

kajirikajirikajirikajiri

複数のユーザーが複数の本を借りることができるということは2つのテーブルで表現できるのか?
user: {id: 1, bookId: 1, name: A}
user: {id: 1, bookId: 2, name: A}
book: {id: 1, userId: 1, name: X}
book: {id: 2, userId: 1, name: Y}

こうなるのか?複合主キーならできなくはないのか。しかし、ユーザーのnameを更新するときはどうなるんだ?userIdのデータを全て更新すればいいのか。

kajirikajirikajirikajiri

いやでも中間テーブル設けたほうがいいって言ってる。理解しているかもしれない。私が理解できていないだけかもしれない。

kajirikajirikajirikajiri

中間テーブルがあればn:nが綺麗に表せる。
user: {id: 1, name: A}
book: {id: 1, name: X}
book: {id: 2, name: Y}
userBookRelation: {userId: 1, bookId: 1}
userBookRelation: {userId: 1, bookId: 2}

うん。
物理本だと再現できない。。再現できなくはないか。共同で借りましたってことにすればいいのか。
デジタル本だとありそう

kajirikajirikajirikajiri

@startuml

' hide the spot
hide circle

' avoid problems with angled crows feet
skinparam Monochrome true

' ----------
' 1ユーザーが1つの本しか持てない
' 1ユーザーが関係している本に他のユーザーは関係できない

entity "USER1" {
*id : string <<generated>>

*bookId : string <<Foreign key>>
}

entity "BOOK1" {
*id : string <<generated>>

*userId : string <<Foreign key>>
}

USER1 ||..|| BOOK1

' --------

' 1ユーザーが複数の本を持てる
' 1ユーザーが関係している本に他のユーザーは関係できない

entity "USER2" {
*id : string <<generated>>

*bookId : string <<Foreign key>>
}

entity "BOOK2" {
*id : string <<generated>>

*userId : string <<Foreign key>>
}

USER2 ||..o{ BOOK2

' --------

' 複数のユーザーが複数の本を持てる
' だがこれはおかしい。値を保存してみよう。
' AさんがXとYという本を取得した場合
' user: {id: 1, bookId: 1, name: A}, book: {id: 1, userId: 1, name: X}
' user: {id: 1, bookId: 2, name: A}, book: {id: 2, userId: 1, name: Y}
' userのidが被った。複合主キーならできなくはない。しかし、userの名前を変更しようとしたらどのユーザーのnameを更新すれば良いだろうか?
' ついでにbookのuserIdも被っている

' A,BさんがXという本を取得した場合
' user: {id: 1, bookId: 1, name: A}, book: {id: 1, userId: 1, name: X}
' user: {id: 2, bookId: 1, name: B}, book: {id: 1, userId: 2, name: X}
' bookのidが被った。

' 以上から見るに、n:nの関係性は二つのテーブルでは表現が辛い。

entity "USER3" {
*id : string <<generated>>

*bookId : string <<Foreign key>>
}

entity "BOOK3" {
*id : string <<generated>>

*userId : string <<Foreign key>>
}

USER3 }o..o{ BOOK3

@enduml

kajirikajirikajirikajiri

ということで
n:nになる可能性があるなら中間テーブルを作った方が良さそう。他は必要なさそうという結論になった

kajirikajirikajirikajiri

無限に拡張していくという可能性を考えると全てに中間テーブルが必要そう

kajirikajirikajirikajiri

The GORM Logical Delete plugin provides support for utilizing logical deletes for GORM managed entities in a Grails 3 app.
A "logical" delete (sometimes referred to as a "soft" delete) is a delete that doesn’t actually delete the relevant data but instead marks the data as deleted. Marking the data as deleted has the benefit of excluding the data from queries by default while still maintaining the ability to retrieve the data when/if necessary. Essentially the plugin offers a mechanism to "hide" domain objects from retrieval. This is useful for retaining data without having it clutter the current set of active data.

まじかよ

kajirikajirikajirikajiri

AとBのn:nはAとBの間にXを設けると、A n: 1:x:1 n: Bで表せることに気づいた

kajirikajirikajirikajiri

でも@DeleteDateColumnデコレータ使うとちゃんとnullがデフォルトになるんだよ。謎