Dans un premier temps, on part du principe que l'utilisateur travaille en local, i.e. gère des bases de données (BDDs) locales sur une machine où il a tout contrôle. Les points à adapter dans le cas d'une base de donnée distante, ou d'une utilisation sans droits d'admin, sont traités dans la section correspondante.
La doc de PostgreSQL, admirablement bien faite, lisible et accessible : https://www.postgresql.org/docs/current/static/tutorial.html
## Les bases
On décrit dans cette section les quelques notions indispensables pour ne pas raconter n'importe quoi, et comprendre comment on peut gérer une BDD locale.
Tout d'abord, installer postgresql (version 9.5 ou 10 en 2018-10), via apt/pacman/brew/le package manager de votre choix.
```
sudo apt install postgresql
```
Cela fait des choses un peu bizarres, c'est normal ; voir la section sur l'utilisateur "postgres".
### Clients et serveurs PostgreSQL
On peut voir PostgreSQL comme un protocole, un peu comme HTTP dans le sens suivant : un client envoie une *requête PostgreSQL* à un serveur, et celui-ci répond en envoyant une *réponse PostgreSQL*. (La différence avec HTTP est qu'il y a une connection persistante : avant de pouvoir échanger des requêtes et des réponses, le client doit d'abord se connecter.)
En installant postgresql, on installe à la fois un serveur PostgreSQL, et un client minimaliste, `psql`.
#### Clients
Toutes les applications permettant de se connecter à un serveur, d'envoyer des requêtes et de recevoir des réponses sont appelées des clients, notamment `psql`. Il existe d'autres types de client, par exemple pgAdmin, une application avec GUI (interface graphique). Concrètement, pgAdmin et psql ont le même rôle malgré des apparences très différentes : envoyer des requêtes, recevoir des réponses.
#### Serveurs
Ce qu'on appelle le *serveur PostgreSQL*, dans le cas où on travaille en local, est le process "postgres" (avec son pid, son path etc.) (voir `ps aux | grep sql`). Donc par exemple, `sudo service postgres restart`, c'est littéralement dire à System V "redémarre le serveur PostgreSQL". C'est le serveur qui exécute et répond aux requêtes.
#### Base de données
Un serveur est un gestionnaire de base de données. C'est pourquoi, par exemple, quand on utilise un client PostgreSQL, il faut préciser à quelle base de donnée on souhaite se connecter.
### L'utilisateur postgres
Constater (si tout s'est bien passé) que l'installation a eu l'effet suivant :
- Au cours de l'installation, un utilisateur Unix "postgres" devrait avoir été créé.
- C'est cet utilisateur qui aura tous les droits sur tout : administration des droits des autres utilisateurs sur les BDD, droits admin sur toutes les BDD...
- En fait, c'est le *rôle* "postgres" associé à l'utilisateur Unix "postgres" qui aura les droits sur tout -- voir section suivante.
- Si cet utilisateur n'a pas été créé... regarder sur internet.
#### "Utilisateur Unix" vs "rôles PostgreSQL"
D'après la doc de postgresql.org :
> Database roles are conceptually completely separate from operating system users. In practice it might be convenient to maintain a correspondence, but this is not required
> Every connection to the database server is made using the name of some particular role, and this role determines the initial access privileges for commands issued in that connection. The role name to use for a particular database connection is indicated by the client that is initiating the connection request in an application-specific fashion. For example, the psql program uses the -U command line option to indicate the role to connect as.
> Many applications assume the name of the current operating system user by default (including createuser and psql). Therefore it is often convenient to maintain a naming correspondence between roles and operating system users.
### Administrer et manipuler des BDDs avec psql
On distingue deux types de console : la console usuelle Unix (bash par exemple), et le terminal de postgresql.
- Le terminal de postgresql s'appelle "psql", on peut le lancer depuis la console Unix par la commande `psql`. Il sert à faire tout : des SELECT, des INSERT etc., mais aussi CREATE ROLE, ALTER ROLE... Il attend en input des commandes SQL, mais interprète aussi des commandes de la forme `\l`, `\dt`, `\c`... pour faire des choses particulières : "list all databases", "list tables", "connect to this database"...
- En plus de `psql`, il existe d'autres commandes bash concernant PostgreSQl, comme `createuser`, `createdb` etc. On peut les voir comme des wraparounds de psql, qui permettent simplement d'éviter d'avoir à se connecter à un terminal psql pour faire certaines opérations communes.
#### Connection au serveur avec psql
Pour se connecter à un terminal "psql" en tant que le *rôle* "postgres", plusieurs possibilités, selon le mode d'authentification choisi :
- si on utilise "md5 authentication" : `psql -U postgres` puis rentrer le mot de passe du *rôle* "postgres". Ceci fonctionne quel que soit l'utilisateur Unix exécutant la commande.
- si on utilise "peer authentication" : il faut être connecté en tant que *l'utilisateur Unix* "postgres" (par exemple, `sudo -u postgres -s` pour ouvrir un shell en tant que "postgres"), puis tout simplement `psql`. C'est le système d'exploitation qui vous authentifie auprès du serveur PostgreSQL.
- C'est le mode par défaut (probablement, en tout cas pour moi ce l'était).
On choisit le mode d'authentification de psql en modifiant `pg_hba.conf`[(voir solution ici)](https://stackoverflow.com/questions/14588212/resetting-password-of-postgresql-on-ubuntu).
Quelques petites remarques :
- sur MD5 : cette méthode de hashage est complètement cassée (en 2018-10) donc l'utiliser n'est pas du tout sécurisé ! A ne pas (plus) utiliser dans des applis en production !
- sur "peer authentication" : dans ce scénario, c'est votre système d'exploitation (OS) qui garantit votre authentification auprès du serveur PostgreSQL. Bien sûr, ceci ne marche que si le serveur peut faire confiance à votre OS, donc que si vous utilisez un serveur stocké sur votre propre machine.
- pour plus d'information, voir la [section "authentification" de la doc](https://www.postgresql.org/docs/current/static/auth-methods.html).
#### Exemples de connection psql
Pour se connecter à une BDD avec psql et accéder au terminal psql :
- Scénario basique :
```bash
john@pc-de-john:~$ psql ma_bdd
# se connecter à la BDD "ma_bdd" en tant que le rôle PostgreSQL "john"
```
- Se connecter en tant qu'une *rôle* différent de son identité en tant qu'*utilisateur Unix* :
```bash
john@pc-de-john:~$ psql ma_bdd -U postgres
# -U: se connecter à la BDD "ma_bdd" en tant que le rôle PostgreSQL "postgres"
john@pc-de-john:~$ psql ma_bdd -U pika
# ... en tant que le rôle PostgreSQL "pika"
```
- Si on utilise "peer authentication" (il faut l'avoir spécifié dans le `pg_hba.conf` !) :
```bash
john@pc-de-john:~$ sudo-u postgres -s
# -u: se connecter en tant que *l'utilisateur Unix* "postgres"
# -s: ouvrir un shell (interactif, non-login)
# Entrer le mdp de john
postgres@pc-de-john:~$ psql ma_bdd
# Si tout s'est bien passé, vous êtes maintenant dans un terminal psql, connecté à ma_bdd en tant que le *rôle* postgres :)
john@pc-de-john:~$ sudo-u pika -s
sudo: unknown user: pika
sudo: unable to initialize policy plugin
# bien sûr, pour les *rôles* ne correspondant pas à des *utilisateurs Unix*, il ne faut pas essayer de se connecter avec le mode "peer authentication"...
```
- Petit piège à éviter : quand on ne spécifie pas la BDD cible, `psql` essaie de se connecter à une BDD du même nom que le *rôle*
```bash
john@pc-de-john:~$ psql -U pika
# pas de BDD spécifiée: se connecter à la BDD "pika" en tant que le rôle PostgreSQL "pika"
psql: FATAL: database "pika" does not exist
```
```
# réussite :D
Password for user pika:
psql (9.5.14)
Type "help" for help.
ma_bdd=>
```
#### Commandes utiles pour psql
Pour sortir de psql, entrer `\q`. (^D marche aussi.)
Commandes utiles de psql (voir aussi ce [cheat sheet postgresql](https://gist.github.com/Kartones/dd3ff5ec5ea238d4c546) pas trop mal) (sinon il y en a plein d'autres sur internet).
) :
-`\q`: Quit/Exit
-`\c __database__`: Connect to a database
-`\d __table__`: Show table definition including triggers
-`\dt *.*`: List tables from all schemas (if `*.*` is omitted will only show SEARCH_PATH ones)
-`\l`: List databases
-`\dn`: List schemas
-`\x`: Pretty-format query results instead of the not-so-useful ASCII tables
User Related:
-`\du`: List users
-`\du __username__`: List a username if present.
### Créer un nouvel rôle
Il est utile de s'habituer à travailler "en tant que" un utilisateur (en l'ocurrence un rôle) qui n'a pas tous les droits sur tout, parce que c'est ce qui se passe dans la vraie vie.
Il est donc recommandé de faire soit un `createuser` (la commande bash, avec les options qui vont bien), soit un `CREATE ROLE rolename LOGIN PASSWORD 'rolepw';` dans un terminal psql, avant de créer des BDDs. Bien penser à donner les permissions idoines à ce nouveau rôle (typiquement, se connecter au serveur avec un mot de passe, créer des bases de données...).
Une fois un nouveau rôle créé, il suffit de faire comme quand on est connecté en tant que postgres.
Petite subtilité : à moins que vous vouliez travailler avec un rôle qui matche exactement votre identité en tant qu'utilisateur Unix, il ne faut pas utiliser le mode d'authentification "peer". Il faut donc potentiellement modifier `pg_hba.conf` pour spécifier au serveur PostgreSQL quel sera le mode d'authentification utilisé.
## La suite
Vous êtes prêt à lire le chapitre 1 de la documentation :
A noter qu'en fait, seul le chapitre 1 (Tutorial) est vraiment à lire. Les autres chapitres sont présents pour référence (c'est une documentation après tout).
[Table des matières](https://www.postgresql.org/docs/10/static/index.html) de la documentation:
> Preface
> I. Tutorial
> 1. Getting Started
> 2. The SQL Language
> 3. Advanced Features
> II. The SQL Language
> III. Server Administration
> IV. Client Interfaces
> V. Server Programming
> VI. Reference
> VII. Internals
> VIII. Appendixes
> Bibliography
> Index
## Et si on travaille sur une BDD distante ?
Exactement le même principe, sauf qu'on n'a plus la possibilité de se connecter en tant que (rôle de) l'administrateur principal postgres. On doit travailler en tant qu'un rôle spécifique au projet concerné (ce qu'il est recommandé de faire même en travaillant en local d'ailleurs).
De plus, le choix du mode d'authentification (pg_hba.conf, sur le serveur distant) doit être par mot de passe.