Vla*_*hev 9 sql orm variant relational-database algebraic-data-types
假设您正在OCaml/F#/ SML/Haskell中编写应用程序,并希望将数据保存在关系数据库中.将产品类型(记录和元组)映射到关系很容易,但是如何将变体类型映射到关系?
具体来说,如何在关系数据库中保留类似下面的类型?
(* OCaml *)
type t =
| Foo
| Bar of string
| Baz of int * int * int
Run Code Online (Sandbox Code Playgroud)
这看起来很乏味,但我会为总和中的每个产品创建一个表格。
CREATE TABLE foo (id uuid PRIMARY KEY);
CREATE TABLE bar (id uuid PRIMARY KEY,
s text NOT NULL);
CREATE TABLE baz (id uuid PRIMARY KEY,
a integer NOT NULL,
b integer NOT NULL,
c integer NOT NULL);
Run Code Online (Sandbox Code Playgroud)
您可能希望存储一些元数据以及每种类型的记录:
CREATE TABLE envelope (id uuid PRIMARY KEY,
t timestamptz NOT NULL DEFAULT now(),
by text NOT NULL DEFAULT sessions_user);
Run Code Online (Sandbox Code Playgroud)
这暗示了一个外键约束:
CREATE TABLE foo (id uuid PRIMARY KEY REFERENCES envelope);
CREATE TABLE bar (id uuid PRIMARY KEY REFERENCES envelope,
s text NOT NULL);
CREATE TABLE baz (id uuid PRIMARY KEY REFERENCES envelope,
a integer NOT NULL,
b integer NOT NULL,
c integer NOT NULL);
Run Code Online (Sandbox Code Playgroud)
如果您更严格,您可以想象存储ty带有类型名称的列并使用它来构造复合外键。(如LedgerSMB 博客中“不应该使用表继承的地方”所述。)