# Implémentation du modèle ## 1. Les titulaires (holder) Une énumération (souvent appelée enum) est un type de données qui permet de définir un ensemble limité et nommé de valeurs possibles. Une énumération sert à représenter une liste finie de choix clairement définis. ```sql create type holder_type as enum ('BANK', 'PERSON', 'COMPANY'); ``` Création de la table `holder`. C'est une table commune à tous les titulaires qu'ils soient des individus ou des sociétés. Elle sert à donner un identifiant unique et défini le type de titulaire. ```sql create table holder ( "id" bigint primary key generated always as identity, "type" holder_type not null, "created_at" timestamp not null default current_timestamp ); ``` - `bigint` : entier sur 64 bits - `primary key` : clé primaire, identification unique de l'enregristrement - `generated always as identity` : incrémentation automatique (1, 2, 3, 4, ...) - Le type est forcé aux 3 valeurs de l'énumération `holder_type` créé précédemment - `not null` : Il est obligatoire de spécifier une valeur. - `default` défini une valeur par défaut - `current_timestamp` date **et** heure courante. Il est possible d'utiliser l'ancienne fonction `now()` ### 1.1 La banque (bank) La banque est aussi un titulaire. Elle doit savoir ce qu'elle a en caisse, ce qui sort et ce qui rentre. ```sql create table bank ( "id" bigint primary key references holder(id), "name" text not null ); ``` - `references holder(id)` : lien sur le champ `id` de table `holder`. Cette liaison interdit de supprimer le titulaire pour eviter que l'enregistrement banque se retrouve _orphelin_ de son titulaire. ### 1.2 Les individus (person) Création de la table `person`. ```sql create table person ( "id" bigint primary key references holder(id) on delete cascade, "firstname" text not null, "lastname" text not null, "birthdate" date not null check (birthdate <= current_date - interval '15 years') ); ``` - `on delete cascade` : Permet de supprimer le titulaire (`holder`) et **en même temps** l'individu (`person`). - `check` : Permet de spécifier une règle de validation. - `interval` : Simplifie le calcul sur les dates - `current_date` : date du jour seule sans les heures (contrairement à `current_timestamp` ou `now()`) ### 1.3 les sociétés (company) ```sql create table company ( "id" bigint primary key references holder(id) on delete cascade, "name" text not null, "registration_number" text unique, "creation_date" date not null ); ``` - `unique` : La valeur doit être unique (si elle est renseignée). Contrairement à une clé primaire la valeur peut être null. ## 2. Les devises ```sql create table currency ( "code" text primary key ); ``` ```sql create table exchange_rate ( "currency_code" text references currency(code) on delete cascade, "date" date , "rate" decimal not null, primary key (currency_code, date) ); ``` - La clé primaire est la combinaison de deux colonnes `currency_code` et `date`. Il ne peut y avoir qu'une ligne par devise et par jour. Il peut y avoir plusieurs devise par jour et une devise est côtée plusieurs jours. ## 3. Les comptes ```sql create table account ( "id" bigint primary key generated always as identity, "opened_at" date not null default current_date, "balance" decimal not null default 0 check (balance >= 0), "currency_code" text not null references currency (code) ); ``` Les liasons (refrences) ne sont pas obligatoirement des entiers. ```sql create table account_holder ( "account_id" int not null references account(id) on delete cascade, "holder_id" int not null references holder(id) on delete cascade, "share" decimal(4,3) not null default 1 check (share > 0 and share <= 1), primary key (account_id, holder_id) ); ``` C'est une table dite pivot. Elle possède deux liaisons de part et d'autre vers les comptes (`account`) et les titulaires (`holder`). La clé primaire est la combinaison des deux. ## 4. Les transactions ```sql create table transaction ( "id" bigint primary key generated always as identity, "transaction_date" timestamp not null default current_timestamp, amount decimal not null check (amount > 0) ); ``` ```sql create table operation ( "id" bigint primary key generated always as identity, "transaction_id" bigint not null references transaction(id), "account_id" bigint not null references account(id), amount decimal not null check (amount > 0), direction text not null check (direction in ('DEBIT', 'CREDIT')) ); ``` Il n'est pas nécessaire d'utiliser une énumération pour contraindre les deux valeurs de direction. Une contrainte check est suffisante.