haskell-jp / questions #98 at 2021-07-20 10:54:31 +0900

persistentについて、というよりデータベースについての質問です。
直和型のデータをデータベースに保存したい場合、どのデータベースを使うのがいいのでしょうか?

persistentだとpersistValue型に直和を表すものがなく、というよりそもそもRDBでは直和型を直接サポートしていない(RDBの元となった関係モデルでは演算として直和を考慮していないと思われる)ので、Maybe型などを使って無理やり表現する以外に方法がないように思えるのですが、
RDB以外のデータベースならサポートしているのかなと。

何か意見をいただければ幸いです。
RDBのようにスキーマが明確に決まったDBで直和型を直接サポートしているDB、というと、Haskell専用になっちゃいますがacid-stateってパッケージが近いかと。全然使ったことないので全く詳しくないのですが、こちらはシリアライズできるHaskellの型ならなんにでも使える、とのことなので。
https://github.com/acid-state/acid-state
返答ありがとうございます。調べてみます。
あとは、スキーマをかっちり決めないMongoDBなりNeo4jなりであれば比較的楽に表現できるかと思います。
それと余談ですが、RDBで直和型を再現する方法はいろいろ考案されているので参考までに
https://www.parsonsmatt.org/2019/03/19/sum_types_in_sql.html
ありがとうございます。いろいろと試してみたいと思います。
追加の質問すみません、RDBで直和型を表現する方法について質問なのですが、
これって直和型のデータを削除したときに、Garbage Collectionを作らないと大量のゴミが残る感じですかね?
https://www.parsonsmatt.org/2019/03/19/sum_types_in_sql.html の「Shared Primary Key」とかのテクニックを適用した場合の話ですかね?外部キーを使うことになるので、テーブル作成時に ON DELETE CASCADE を設定しておかなければ確かに削除時に余分なレコードが残りますね
返信ありがとうございます。
なるほど、ということは、XやYを型としてZをXとYの直和型としたとき、
Shared Primary Keyの場合は、直和Zの実装としてXかYの要素のid値を保存するからZの値を削除しただけではXかYの要素を削除できなくて、
The persistent Approachの場合は、直和Zは自身のid値を中身のXかYの要素のid値をそのまま使用することで表現するから、id値で削除すれば、XかYの要素も削除できるという理解で合ってますでしょうか?
いや、Shared Primary Keyの場合であっても、Zに対してDELETE文を発行した場合は外部キー制約がないので~残ります~(実際に外部キー制約が付いている場合はそもそも削除できないはず)が、Xの方を削除するようにすれば外部キー制約からON DELETE CASCADEが使えるんじゃないかと思います。
ええとすみません、私自身、RDBの外部キー制約をちゃんと理解していないことが分かったので、勉強するために少し時間をいただけますでしょうか?
お気になさらず。私も誤解している可能性がなきにしもあらずですので :sweat_drops:
分かりました。
Shared Primary Keysの場合は、Zが親テーブルで、XやYが子テーブルになって、CASCADE設定してZを削除すると、それを参照していたXやYのデータも削除されるということですね。
The persistent Approachの場合は、XやYが親テーブルでZが子テーブルなので、子であるZのデータを削除してもXやYのデータが残ってしまうという感じですかね?