2015-10-19 18 views
5

Załóżmy, że piszesz aplikację w OCaml/F #/SML/Haskell i chcesz zachować dane w relacyjnej bazie danych. Łatwo jest odwzorować typy produktów (rekordy i krotki) na relacje, ale jak odwzorować typy wariantów na relacje?Modelowanie algebraicznych typów danych przy użyciu relacyjnej bazy danych

Aby być konkretnym, w jaki sposób utrzymasz typ podobny do poniższego w relacyjnej bazie danych?

(* OCaml *) 
type t = 
    | Foo 
    | Bar of string 
    | Baz of int * int * int 
+0

Czy możesz podać przykład prawdziwych danych, które możesz chcieć przechowywać? – Shnugo

+0

Moim pierwszym pomysłem będzie XML. Możesz przechowywać każdy rodzaj hierarchicznie uporządkowanych danych wraz z opisowymi metadanymi (atrybutami). Ale będziesz potrzebował dużej logiki, aby zinterpretować to ... – Shnugo

+0

@shnugo Jak już wspomniałem, interesuję się relacyjnymi bazami danych. – Halst

Odpowiedz

2

Wydaje się nudne, ale chciałbym utworzyć tabelę dla każdego produktu w sumie.

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); 

Prawdopodobnie chcesz przechowywać niektóre metadane wraz z zapisami każdego typu:

CREATE TABLE envelope (id uuid PRIMARY KEY, 
         t timestamptz NOT NULL DEFAULT now(), 
         by text NOT NULL DEFAULT sessions_user); 

A to sugeruje ograniczenie klucza obcego:

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); 

A jeśli są jeszcze surowsze cię można sobie wyobrazić przechowywanie kolumny ty z nazwą typu i użycie jej do skonstruowania złożonego klucza obcego. (Jako opisany pod "Where Not to Use Table Inheritance" na blogu LedgerSMB.)

+0

Niedawno myślałem o tym więcej i mam schemat obejmujący stół pośredni, który służy jako kluczowy cel zagraniczny. Przykładowy kod można znaleźć tutaj: https://github.com/solidsnack/pg-sql-variants – solidsnack

+0

Jak zapisać odniesienie do 't'? – nafg

+0

Zapisz odniesienie do koperty. – solidsnack

Powiązane problemy