diff --git a/diagrams/README.md b/diagrams/README.md index 67009dc31..fa4a1e7fe 100644 --- a/diagrams/README.md +++ b/diagrams/README.md @@ -8,6 +8,8 @@ You can go download erd from https://github.com/BurntSushi/erd/releases and then ./erd_static-x86-64 -i diagrams/film.er -o docs/_static/film.png ``` +The fonts used belong to the GNU FreeFont family. You can download them here: http://ftp.gnu.org/gnu/freefont/ + ## LaTeX The schema structure diagram is done with LaTeX. You can use a GUI like https://www.mathcha.io/editor to create the .tex file. diff --git a/diagrams/boxoffice.er b/diagrams/boxoffice.er new file mode 100644 index 000000000..7d6b0a1c7 --- /dev/null +++ b/diagrams/boxoffice.er @@ -0,0 +1,15 @@ +entity {font: "FreeSans"} +relationship {font: "FreeMono"} + +[Box_Office] +*bo_date +*+film_id +gross_revenue + +[Films] +*id ++director_id +title +`...` + +Box_Office +--1 Films diff --git a/diagrams/employees.er b/diagrams/employees.er index 7010a670e..4632f5bac 100644 --- a/diagrams/employees.er +++ b/diagrams/employees.er @@ -1,3 +1,8 @@ +# Build using: -e ortho + +entity {font: "FreeSans"} +relationship {font: "FreeMono"} + [Employees] *id first_name diff --git a/diagrams/film.er b/diagrams/film.er index d19fdf61b..cc54c4800 100644 --- a/diagrams/film.er +++ b/diagrams/film.er @@ -1,3 +1,6 @@ +entity {font: "FreeSans"} +relationship {font: "FreeSerif"} + [Films] *id +director_id @@ -31,6 +34,12 @@ year *+film_id rank +[Technical_Specs] +*+film_id +runtime +camera +sound + Roles *--1 Actors Roles *--1 Films @@ -38,3 +47,5 @@ Nominations *--1 Competitions Nominations *--1 Films Films *--1 Directors + +Films 1--1 Technical_Specs diff --git a/diagrams/orders.er b/diagrams/orders.er index bdd93de2e..86f0805e9 100644 --- a/diagrams/orders.er +++ b/diagrams/orders.er @@ -1,3 +1,8 @@ +# Build using: -e ortho + +entity {font: "FreeSans"} +relationship {font: "FreeMono"} + [Addresses] *id name diff --git a/diagrams/premieres.er b/diagrams/premieres.er new file mode 100644 index 000000000..6099e74fd --- /dev/null +++ b/diagrams/premieres.er @@ -0,0 +1,16 @@ +entity {font: "FreeSans"} +relationship {font: "FreeMono"} + +[Premieres] +*id +location +date ++film_id + +[Films] +*id ++director_id +title +`...` + +Premieres *--1 Films diff --git a/diagrams/presidents.er b/diagrams/presidents.er index b49100961..ca7cf71ba 100644 --- a/diagrams/presidents.er +++ b/diagrams/presidents.er @@ -1,3 +1,8 @@ +# Build using: -e ortho + +entity {font: "FreeSans"} +relationship {font: "FreeMono"} + [Presidents] *id first_name diff --git a/diagrams/users.er b/diagrams/users.er index e42ca312f..8ec011302 100644 --- a/diagrams/users.er +++ b/diagrams/users.er @@ -1,3 +1,8 @@ +# Build using: -e ortho + +entity {font: "FreeSans"} +relationship {font: "FreeMono"} + [Users] *id first_name diff --git a/docs/_static/boxoffice.png b/docs/_static/boxoffice.png new file mode 100644 index 000000000..87249a665 Binary files /dev/null and b/docs/_static/boxoffice.png differ diff --git a/docs/_static/employees.png b/docs/_static/employees.png index 0a72df2a2..b21153cc5 100644 Binary files a/docs/_static/employees.png and b/docs/_static/employees.png differ diff --git a/docs/_static/film.png b/docs/_static/film.png index 99843b870..03b9b2b74 100644 Binary files a/docs/_static/film.png and b/docs/_static/film.png differ diff --git a/docs/_static/orders.png b/docs/_static/orders.png index db709c873..0ac19aacd 100644 Binary files a/docs/_static/orders.png and b/docs/_static/orders.png differ diff --git a/docs/_static/premieres.png b/docs/_static/premieres.png new file mode 100644 index 000000000..794e96767 Binary files /dev/null and b/docs/_static/premieres.png differ diff --git a/docs/_static/presidents.png b/docs/_static/presidents.png index 2164ff3de..09c4e6f79 100644 Binary files a/docs/_static/presidents.png and b/docs/_static/presidents.png differ diff --git a/docs/_static/users.png b/docs/_static/users.png index f8b57fee7..d94f097fc 100644 Binary files a/docs/_static/users.png and b/docs/_static/users.png differ diff --git a/docs/references/api/resource_embedding.rst b/docs/references/api/resource_embedding.rst index 18c1076bf..63dda347e 100644 --- a/docs/references/api/resource_embedding.rst +++ b/docs/references/api/resource_embedding.rst @@ -24,7 +24,56 @@ Relationships For example, consider a database of films and their awards: -.. image:: ../../_static/film.png +.. _erd_film: + +.. tabs:: + + .. group-tab:: ERD + + .. image:: ../../_static/film.png + + .. code-tab:: postgresql SQL + + create table actors( + id int primary key generated always as identity, + first_name text, + last_name text + ); + + create table directors( + id int primary key generated always as identity, + first_name text, + last_name text + ); + + create table films( + id int primary key generated always as identity, + director_id int references directors(id), + title text, + year int, + rating numeric(3,1), + language text + ); + + create table roles( + film_id int references films(id), + actor_id int references actors(id), + character text, + primary key(film_id, actor_id) + ); + + create table competitions( + id int primary key generated always as identity, + name text, + year int + ); + + create table nominations( + competition_id int references competitions(id), + film_id int references films(id), + rank int, + primary key (competition_id, film_id) + ); .. _many-to-one: @@ -136,24 +185,7 @@ Many-to-many relationships The join table determines many-to-many relationships. It must contain foreign keys to other two tables and they must be part of its composite key. -For the many-to-many relationship between ``films`` and ``actors``, the join table ``roles`` is: - -.. code-block:: postgresql - - create table roles( - film_id int references films(id) - , actor_id int references actors(id) - , primary key(film_id, actor_id) - ); - - -- the join table can also be detected if the composite key has additional columns - - create table roles( - id int generated always as identity, - , film_id int references films(id) - , actor_id int references actors(id) - , primary key(id, film_id, actor_id) - ); +Thus, it can detect the join table ``roles`` between ``films`` and ``actors``: .. tabs:: @@ -177,6 +209,18 @@ For the many-to-many relationship between ``films`` and ``actors``, the join tab ".." ] +The join table can also be detected if the composite key has additional columns: + +.. code-block:: postgresql + + create table roles( + id int generated always as identity, + , film_id int references films(id) + , actor_id int references actors(id) + , character text, + , primary key(id, film_id, actor_id) + ); + .. _one-to-one: One-to-one relationships @@ -184,38 +228,27 @@ One-to-one relationships One-to-one relationships are detected in two ways. +- When the foreign key is a primary key as specified in the :ref:`DB structure example `. - When the foreign key has a unique constraint. -.. code-block:: postgresql + .. code-block:: postgresql - CREATE TABLE technical_specs( - film_id INT REFERENCES films UNIQUE, - runtime TIME, - camera TEXT, - sound TEXT - ); - -- When the foreign key is a primary key. - -.. code-block:: postgresql - - -- references Films using the primary key as a foreign key - CREATE TABLE technical_specs( - film_id INT PRIMARY KEY REFERENCES films, - runtime TIME, - camera TEXT, - sound TEXT - ); + CREATE TABLE technical_specs( + film_id INT REFERENCES films UNIQUE, + runtime TIME, + camera TEXT, + sound TEXT + ); .. tabs:: .. code-tab:: http - GET /films?select=title,technical_specs(runtime) HTTP/1.1 + GET /films?select=title,technical_specs(camera) HTTP/1.1 .. code-tab:: bash Curl - curl "http://localhost:3000/films?select=title,technical_specs(runtime)" + curl "http://localhost:3000/films?select=title,technical_specs(camera)" .. code-block:: json @@ -236,20 +269,26 @@ You can manually define relationships between using functions. This is useful fo Assuming there's a foreign table ``premieres`` that we want to relate to ``films``. -.. code-block:: postgres +.. tabs:: - create foreign table premieres ( - id integer, - location text, - "date" date, - film_id integer - ) server import_csv options ( filename '/tmp/directors.csv', format 'csv'); + .. group-tab:: ERD - create function film(premieres) returns setof films rows 1 as $$ - select * from films where id = $1.film_id - $$ stable language sql; + .. image:: ../../_static/premieres.png -The above function defines a relationship between ``premieres`` (the parameter) and ``films`` (the return type). Since there's a ``rows 1``, this defines a many-to-one relationship. + .. code-tab:: postgresql SQL + + create foreign table premieres ( + id integer, + location text, + "date" date, + film_id integer + ) server import_csv options ( filename '/tmp/directors.csv', format 'csv'); + + create function film(premieres) returns setof films rows 1 as $$ + select * from films where id = $1.film_id + $$ stable language sql; + +The above function (see the **SQL** tab) defines a relationship between ``premieres`` (the parameter) and ``films`` (the return type). Since there's a ``rows 1``, this defines a many-to-one relationship. The name of the function ``film`` is arbitrary and can be used to do the embedding: .. tabs:: @@ -698,24 +737,30 @@ Foreign Key joins can also be done between `partitioned tables