简体   繁体   English

使用关系数据库为代数数据类型建模

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM