On this page:
5.1 Tables
Account
Account?
Checkout
Checkout?
Copy
Copy?
Customer
Customer?
District
District?
Employee
Employee?
Genre
Genre?
Item
Item?
Item  Type
Item  Type?
Item  Genre
Item  Genre?
Rental
Rental?
Store
Store?
5.2 Singular Relationships
Account-of/  s
Checkout-of/  s
Copy-of/  s
Customer-of/  s
Item-of/  s
Item-of
5.3 Plural Relationships
Checkouts-of/  p
Copies-of/  p
Genres-of/  p
Genres-of
Item  Genres-of/  p
Store-of/  s
5.4 Grouped Relationships
Copies-of/  g
Rentals-of/  g
grouped-Rentals-of
5.5 Fields
Address
Checkout  Time
Copy  Id
Customer  Birth  Date
Customer  Id
Item  Id
Item  Type  Id
Release  Date
Rental  Id
Store  Id
7.7

5 Video Rental Example Schema

 (require plisqin/examples/video-rental-schema)
  package: plisqin

This section documents an example database schema that models a brick-and-mortar video rental store. Each table has an explanation of what it means. Joins and fields typically just show the code.

This diagram shows the database model.

5.1 Tables

procedure

(Account alias)  source?

  alias : string?

procedure

(Account? x)  boolean?

  x : any/c

(table Account "Account" "_account")

An account is a collection of 1 or more Customers. They probably share a household, but we don’t care.

procedure

(Checkout alias)  source?

  alias : string?

procedure

(Checkout? x)  boolean?

  x : any/c

(table Checkout "Checkout" "_checkout")

A Checkout is a point-of-sale transaction.

procedure

(Copy alias)  source?

  alias : string?

procedure

(Copy? x)  boolean?

  x : any/c

(table Copy "Copy" "_copy")

A Copy is an instance of an Item. Each Copy has a barcode that is unique throughout the whole company. A Rental points to a specific Copy. Obviously, a Copy can be rented multiple times.

procedure

(Customer alias)  source?

  alias : string?

procedure

(Customer? x)  boolean?

  x : any/c

(table Customer "Customer" "_customer")

A Customer is a person who has an Account.

procedure

(District alias)  source?

  alias : string?

procedure

(District? x)  boolean?

  x : any/c

(table District "District" "_district")

A District is a collection of Stores.

procedure

(Employee alias)  source?

  alias : string?

procedure

(Employee? x)  boolean?

  x : any/c

(table Employee "Employee" "_employee")

An Employee has 1 primary Store, even though they may work at other Stores if needed.

procedure

(Genre alias)  source?

  alias : string?

procedure

(Genre? x)  boolean?

  x : any/c

(table Genre "Genre" "_genre")

For example, "Action" and "Comedy" are genres. Every Item can have multiple genres.

procedure

(Item alias)  source?

  alias : string?

procedure

(Item? x)  boolean?

  x : any/c

(table Item "Item" "_item")

An Item is the definition something that can be rented or sold, typically a movie. A Copy is an instance of an Item. For example, "Role Models / DVD / 2009" would be an Item, and there would be multiple copies available to rent, each with their own barcode.

procedure

(ItemType alias)  source?

  alias : string?

procedure

(ItemType? x)  boolean?

  x : any/c

(table ItemType "ItemType" "_itemType")

An ItemType is a property of an Item. Examples might be "DVD", "BluRay", and "PS2 game".

procedure

(ItemGenre alias)  source?

  alias : string?

procedure

(ItemGenre? x)  boolean?

  x : any/c

(table ItemGenre "ItemGenre" "_itemGenre")

This is just the mapping table for the many:many relationship of Item:Genre.

procedure

(Rental alias)  source?

  alias : string?

procedure

(Rental? x)  boolean?

  x : any/c

(table Rental "Rental" "_rental")

A Rental is a line item of a Checkout. It has exactly 1 Copy that is being rented. It also has exactly 1 Checkout.

procedure

(Store alias)  source?

  alias : string?

procedure

(Store? x)  boolean?

  x : any/c

(table Store "Store" "_store")

A Store is a physical location that rents stuff.

5.2 Singular Relationships

procedure

(Account-of/s x)  Account?

  x : any/c
(field-cases (Account-of/s x)
             [(Customer? x)
              (join a (Account)
                    (join-on a".AccountId = "x".AccountId"))]
             [(Checkout? x)
              (Account-of/s (Customer-of/s x))]
             [(Rental? x)
              (Account-of/s (Checkout-of/s x))]
             [(Account? x) x])

procedure

(Checkout-of/s x)  Checkout?

  x : any/c
(field-cases (Checkout-of/s x)
             [(Checkout? x) x]
             [(Rental? x)
              (join c (Checkout)
                    (join-on c".CheckoutId = "x".CheckoutId"))])

procedure

(Copy-of/s x)  Copy?

  x : any/c
(field-cases (Copy-of/s x)
             [(Rental? x)
              (join c (Copy)
                    (join-on c".CopyId = "x".CopyId"))]
             [(Copy? x) x])

procedure

(Customer-of/s x)  Customer?

  x : any/c
(field-cases (Customer-of/s x)
             [(Customer? x) x]
             [(Rental? x) (Customer-of/s (Checkout-of/s x))]
             [(Checkout? x)
              (join c (Customer)
                    (join-on c".CustomerId = "x".CustomerId"))])

procedure

(Item-of/s x)  Item?

  x : any/c
(field-cases (Item-of/s x)
             [(Copy? x)
              (join i (Item)
                    (join-on i".ItemId = "x".ItemId"))]
             [(Rental? x)
              (Item-of/s (Copy-of/s x))]
             [(Item? x) x])

procedure

(Item-of x)  Item?

  x : any/c
An alias of Item-of/s so I don’t have to interrupt my sales pitch explaining of/s.

5.3 Plural Relationships

procedure

(Checkouts-of/p x)  Checkout?

  x : any/c
(field-cases (Checkouts-of/p x)
             [(Employee? x)
              (join c (Checkout)
                    (join-on c".EmployeeId = "x".EmployeeId"))]
             [(Store? x)
              (join c (Checkout)
                    (join-on c".StoreId = "x".StoreId"))])

procedure

(Copies-of/p x)  Copy?

  x : any/c
(field-cases (Copies-of/p x)
             [(Item? x)
              (join c (Copy)
                    (join-on c".ItemId = "x".ItemId"))])

procedure

(Genres-of/p x)  Genre?

  x : any/c
(field-cases (Genres-of/p x)
             [(Item? x)
              (join g (Genre)
                    (join-on g".GenreId = "(ItemGenres-of/p x)".GenreId"))]
             [(or (Copy? x)
                  (Rental? x))
              (Genres-of/p (Item-of/s x))])

procedure

(Genres-of x)  Genre?

  x : any/c
An alias of Genres-of/p so I don’t have to interrupt my sales pitch explaining of/p.

procedure

(ItemGenres-of/p x)  ItemGenre?

  x : any/c
(field-cases (ItemGenres-of/p x)
             [(Item? x)
              (join ig (ItemGenre)
                    (join-on ig".ItemId = "x".ItemId"))]
             [(Genre? x)
              (join ig (ItemGenre)
                    (join-on ig".GenreId = "x".GenreId"))]
             [(or (Copy? x)
                  (Rental? x))
              (ItemGenres-of/p (Item-of/s x))])

procedure

(Store-of/s x)  Store?

  x : any/c
(field-cases (Store-of/s x)
             [(or (Checkout? x)
                  (Employee? x))
              (join s (Store)
                    (join-on s".StoreId = "x".StoreId"))]
             [(or (Rental? x)
                  (Copy? x))
              (Store-of/s (Checkout-of/s x))]
             [(Store? x) x])

5.4 Grouped Relationships

procedure

(Copies-of/g x)  Copy?

  x : any/c
(field-cases (Copies-of/g x)
             [(Item? x)
              (join c (Copy)
                    (group-by (ItemId c))
                    (join-on (ItemId c)" = "(ItemId x)))])

procedure

(Rentals-of/g x)  Rental?

  x : any/c
(field-cases (Rentals-of/g x)
             [(Customer? x)
              (join r (Rental)
                    (group-by (CustomerId r))
                    (join-on (CustomerId r)" = "(CustomerId x)))]
             [(Copy? x)
              (join r (Rental)
                    (group-by (CopyId r))
                    (join-on (CopyId r)" = "(CopyId x)))]
             [(Item? x)
              (join r (Rental)
                    (group-by (ItemId r))
                    (join-on (ItemId r)" = "(ItemId x)))])

procedure

(grouped-Rentals-of x)  Rental?

  x : any/c
An alias of Rentals-of/g so I don’t have to interrupt my sales pitch explaining of/g.

5.5 Fields

procedure

(Address x)  fragment?

  x : any/c
(field-cases (Address x)
             [(Store? x)
              (scalar x".Address")])

procedure

(CheckoutTime x)  fragment?

  x : any/c
(field-cases (CheckoutTime x)
             [(Checkout? x)
              (scalar x".CheckoutTime")]
             [(Rental? x)
              (CheckoutTime (Checkout-of/s x))])

procedure

(CopyId x)  fragment?

  x : any/c
(field-cases (CopyId x)
             [(or (Copy? x)
                  (Rental? x))
              (scalar x".CopyId")]
             [(Item? x)
              (CopyId (Copy-of/s x))])

procedure

(CustomerBirthDate x)  fragment?

  x : any/c
(field-cases (CustomerBirthDate x)
             [(Customer? x)
              (scalar x".CustomerBirthDate")]
             [(or (Checkout? x)
                  (Rental? x))
              (CustomerBirthDate (Customer-of/s x))])

procedure

(CustomerId x)  fragment?

  x : any/c
(field-cases (CustomerId x)
             [(or (Customer? x)
                  (Checkout? x))
              (scalar x".CustomerId")]
             [(Rental? x)
              (CustomerId (Checkout-of/s x))])

procedure

(ItemId x)  fragment?

  x : any/c
(field-cases (ItemId x)
             [(or (Item? x)
                  (Copy? x))
              (scalar x".ItemId")]
             [(Rental? x)
              (ItemId (Copy-of/s x))])

procedure

(ItemTypeId x)  fragment?

  x : any/c
(field-cases (ItemTypeId x)
             [(or (ItemType? x)
                  (Item? x))
              (scalar x".ItemTypeId")]
             [(or (Copy? x)
                  (Rental? x))
              (ItemTypeId (Item-of/s x))])

procedure

(ReleaseDate x)  fragment?

  x : any/c
(field-cases (ReleaseDate x)
             [(Item? x)
              (scalar x".ReleaseDate")]
             [(or (Copy? x)
                  (Rental? x))
              (ReleaseDate (Item-of/s x))])

procedure

(RentalId x)  fragment?

  x : any/c
(field-cases (RentalId x)
             [(Rental? x)
              (scalar x".RentalId")])

procedure

(StoreId x)  fragment?

  x : any/c
(field-cases (StoreId x)
             [(Store? x)
              (scalar x".StoreId")]
             [(or (Rental? x)
                  (Checkout? x))
              (StoreId (Store-of/s x))])