Add missing ERD/SQL tabs and fix some requests

This commit is contained in:
Laurence Isla
2023-08-10 08:49:55 -05:00
committed by Steve Chavez
parent 637165ba5b
commit 3f112553b0
16 changed files with 173 additions and 64 deletions
+2
View File
@@ -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 ./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 ## 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. The schema structure diagram is done with LaTeX. You can use a GUI like https://www.mathcha.io/editor to create the .tex file.
+15
View File
@@ -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
+5
View File
@@ -1,3 +1,8 @@
# Build using: -e ortho
entity {font: "FreeSans"}
relationship {font: "FreeMono"}
[Employees] [Employees]
*id *id
first_name first_name
+11
View File
@@ -1,3 +1,6 @@
entity {font: "FreeSans"}
relationship {font: "FreeSerif"}
[Films] [Films]
*id *id
+director_id +director_id
@@ -31,6 +34,12 @@ year
*+film_id *+film_id
rank rank
[Technical_Specs]
*+film_id
runtime
camera
sound
Roles *--1 Actors Roles *--1 Actors
Roles *--1 Films Roles *--1 Films
@@ -38,3 +47,5 @@ Nominations *--1 Competitions
Nominations *--1 Films Nominations *--1 Films
Films *--1 Directors Films *--1 Directors
Films 1--1 Technical_Specs
+5
View File
@@ -1,3 +1,8 @@
# Build using: -e ortho
entity {font: "FreeSans"}
relationship {font: "FreeMono"}
[Addresses] [Addresses]
*id *id
name name
+16
View File
@@ -0,0 +1,16 @@
entity {font: "FreeSans"}
relationship {font: "FreeMono"}
[Premieres]
*id
location
date
+film_id
[Films]
*id
+director_id
title
`...`
Premieres *--1 Films
+5
View File
@@ -1,3 +1,8 @@
# Build using: -e ortho
entity {font: "FreeSans"}
relationship {font: "FreeMono"}
[Presidents] [Presidents]
*id *id
first_name first_name
+5
View File
@@ -1,3 +1,8 @@
# Build using: -e ortho
entity {font: "FreeSans"}
relationship {font: "FreeMono"}
[Users] [Users]
*id *id
first_name first_name
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 56 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 16 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 15 KiB

+109 -64
View File
@@ -24,7 +24,56 @@ Relationships
For example, consider a database of films and their awards: 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: .. _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. 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: Thus, it can detect the join table ``roles`` between ``films`` and ``actors``:
.. 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)
);
.. tabs:: .. 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:
One-to-one relationships One-to-one relationships
@@ -184,38 +228,27 @@ One-to-one relationships
One-to-one relationships are detected in two ways. 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 <erd_film>`.
- When the foreign key has a unique constraint. - When the foreign key has a unique constraint.
.. code-block:: postgresql .. code-block:: postgresql
CREATE TABLE technical_specs( CREATE TABLE technical_specs(
film_id INT REFERENCES films UNIQUE, film_id INT REFERENCES films UNIQUE,
runtime TIME, runtime TIME,
camera TEXT, camera TEXT,
sound 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
);
.. tabs:: .. tabs::
.. code-tab:: http .. 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 .. 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 .. 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``. Assuming there's a foreign table ``premieres`` that we want to relate to ``films``.
.. code-block:: postgres .. tabs::
create foreign table premieres ( .. group-tab:: ERD
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 $$ .. image:: ../../_static/premieres.png
select * from films where id = $1.film_id
$$ stable language sql;
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: The name of the function ``film`` is arbitrary and can be used to do the embedding:
.. tabs:: .. tabs::
@@ -698,24 +737,30 @@ Foreign Key joins can also be done between `partitioned tables <https://www.post
For example, let's create the ``box_office`` partitioned table that has the gross daily revenue of a film: For example, let's create the ``box_office`` partitioned table that has the gross daily revenue of a film:
.. code-block:: postgres .. tabs::
CREATE TABLE box_office ( .. group-tab:: ERD
bo_date DATE NOT NULL,
film_id INT REFERENCES test.films NOT NULL,
gross_revenue DECIMAL(12,2) NOT NULL,
PRIMARY KEY (bo_date, film_id)
) PARTITION BY RANGE (bo_date);
-- Let's also create partitions for each month of 2021 .. image:: ../../_static/boxoffice.png
CREATE TABLE box_office_2021_01 PARTITION OF test.box_office .. code-tab:: postgresql SQL
FOR VALUES FROM ('2021-01-01') TO ('2021-01-31');
CREATE TABLE box_office_2021_02 PARTITION OF test.box_office CREATE TABLE box_office (
FOR VALUES FROM ('2021-02-01') TO ('2021-02-28'); bo_date DATE NOT NULL,
film_id INT REFERENCES films NOT NULL,
gross_revenue DECIMAL(12,2) NOT NULL,
PRIMARY KEY (bo_date, film_id)
) PARTITION BY RANGE (bo_date);
-- and so until december 2021 -- Let's also create partitions for each month of 2021
CREATE TABLE box_office_2021_01 PARTITION OF box_office
FOR VALUES FROM ('2021-01-01') TO ('2021-01-31');
CREATE TABLE box_office_2021_02 PARTITION OF box_office
FOR VALUES FROM ('2021-02-01') TO ('2021-02-28');
-- and so until december 2021
Since it contains the ``films_id`` foreign key, it is possible to join ``box_office`` and ``films``: Since it contains the ``films_id`` foreign key, it is possible to join ``box_office`` and ``films``: