[英]Modelling algebraic data types using relational database
Say you are writing an app in OCaml/F#/SML/Haskell and want to persist data in a relational database.假设您正在使用 OCaml/F#/SML/Haskell 编写应用程序,并希望将数据保存在关系数据库中。 It is easy to map product types (records and tuples) to relations, but how do you map variant types to relations?
将产品类型(记录和元组)映射到关系很容易,但是如何将变体类型映射到关系呢?
To be concrete, how would you persist a type like the following, in a relational database?具体来说,您将如何在关系数据库中持久化如下所示的类型?
(* OCaml *)
type t =
| Foo
| Bar of string
| Baz of int * int * int
It seems tedious but I would create a table for each product in the sum.这看起来很乏味,但我会为总和中的每个产品创建一个表格。
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);
You probably want to store some metadata along with records of each type:您可能希望存储一些元数据以及每种类型的记录:
CREATE TABLE envelope (id uuid PRIMARY KEY,
t timestamptz NOT NULL DEFAULT now(),
by text NOT NULL DEFAULT sessions_user);
And this suggests a foreign key constraint:这暗示了一个外键约束:
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);
And if you are even stricter you could imagine storing a ty
column with the name of the type and using it to construct a composite foreign key.如果您更严格,您可以想象存储带有类型名称的
ty
列并使用它来构造复合外键。 (As described under "Where Not to Use Table Inheritance" in the LedgerSMB blog.) (如 LedgerSMB 博客中“不应该使用表继承的地方”所述。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.