Exemple : ORDBMS
ORDBMS: Object-Relational DBMS
Contacts normalisés
contacts1 Schéma relationnel
uid | username | firstname | lastname | emergency_contact | |
|---|---|---|---|---|---|
1 | denis | denis.rinfret@example.com | None | None | help@example.com |
2 | minh | minh@example.com | None | None | contact@example.com |
Que devons-nous faire pour permettre à un utilisateur d'avoir plus d'un contact ?
Si le nombre de contacts est fixe, disons
ncontacts, alors nous pourrions avoirncolonnes de contacts, tant quenest petit.Mais si
nn'est pas petit ou sinest inconnu, alors nous devons avoir une autre table, une table contacts, pour préserver la première forme normale.La première forme normale stipule que chaque valeur de colonne doit être atomique.
contacts2 Schéma relationnel
uid | username | firstname | lastname | |
|---|---|---|---|---|
1 | denis | denis.rinfret@example.com | None | None |
2 | minh | minh@example.com | None | None |
cid | uid | |
|---|---|---|
1 | help@example.com | 1 |
2 | minh@example.com | 1 |
3 | contact@example.com | 2 |
4 | ha@example.com | 2 |
Jointure nécessaire pour obtenir toutes les données
uid | username | firstname | lastname | cid | email_1 | uid_1 | |
|---|---|---|---|---|---|---|---|
1 | denis | denis.rinfret@example.com | None | None | 1 | help@example.com | 1 |
1 | denis | denis.rinfret@example.com | None | None | 2 | minh@example.com | 1 |
2 | minh | minh@example.com | None | None | 3 | contact@example.com | 2 |
2 | minh | minh@example.com | None | None | 4 | ha@example.com | 2 |
Les jointures peuvent être lentes.
Mais sans normalisation, les données peuvent être redondantes et des anomalies peuvent apparaître.
Une SGDB
object-relationalle(SGBDOR, ou ORDBMS) peut aider.
Contacts dénormalisés
contacts3 Schéma objet-relationnel
uid | emergency_contacts |
|---|---|
1 | ["help@example.com", "minh@example.com"] |
2 | ["contact@example.com", "ha@example.com"] |
uid | username | firstname | lastname | unnest | |
|---|---|---|---|---|---|
1 | denis | denis.rinfret@example.com | None | None | help@example.com |
1 | denis | denis.rinfret@example.com | None | None | minh@example.com |
2 | minh | minh@example.com | None | None | contact@example.com |
2 | minh | minh@example.com | None | None | ha@example.com |
Trouver les utilisateurs avec un courriel spécifique comme premier contact d'urgence
uid | username | |
|---|---|---|
1 | denis | denis.rinfret@example.com |
Trouver un utilisateur avec un courriel spécifique comme contact d'urgence (n'importe quelle position)
uid | username | |
|---|---|---|
2 | minh | minh@example.com |
Trouver les utilisateurs qui sont listés comme contact d'urgence d'autres utilisateurs
uid | username | |
|---|---|---|
2 | minh | minh@example.com |
uid | username | |
|---|---|---|
2 | minh | minh@example.com |
Sans unnest ni sous-requêtes
uid | username | |
|---|---|---|
2 | minh | minh@example.com |
Types définis par les utilisateurs
User-Defined Types (UDT)
contacts4 Schéma objet-relationnel
uid | contacts |
|---|---|
1 | {"(help@example.com,emergency)","(minh@example.com,friend)"} |
2 | {"(contact@example.com,family)","(ha@example.com,colleague)"} |
uid | username | email_1 | type | |
|---|---|---|---|---|
1 | denis | denis.rinfret@example.com | help@example.com | emergency |
1 | denis | denis.rinfret@example.com | minh@example.com | friend |
2 | minh | minh@example.com | contact@example.com | family |
2 | minh | minh@example.com | ha@example.com | colleague |
uid | username | contact_email | contact_type | |
|---|---|---|---|---|
1 | denis | denis.rinfret@example.com | help@example.com | emergency |
1 | denis | denis.rinfret@example.com | minh@example.com | friend |
2 | minh | minh@example.com | contact@example.com | family |
2 | minh | minh@example.com | ha@example.com | colleague |
Trouver tous les contacts d'urgence d'un utilisateur
uid | username | contact_email | contact_type | |
|---|---|---|---|---|
1 | denis | denis.rinfret@example.com | help@example.com | emergency |
Trouver les utilisateurs sans contacts d'urgence
uid | username | |
|---|---|---|
2 | minh | minh@example.com |
uid | username | |
|---|---|---|
2 | minh | minh@example.com |
JSONB à la place de tableaux
contacts5 Schéma objet-relationnel
uid | contacts |
|---|---|
1 | {"friend": "minh@example.com", "emergency": "help@example.com"} |
2 | {"family": "contact@example.com", "colleague": "ha@example.com"} |
Trouver les utilisateurs avec au moins un contact d'urgence
uid | username | |
|---|---|---|
1 | denis | denis.rinfret@example.com |
uid | username | |
|---|---|---|
1 | denis | denis.rinfret@example.com |
uid | username | emergency | |
|---|---|---|---|
1 | denis | denis.rinfret@example.com | help@example.com |
Trouver les utilisateurs sans contacts d'urgence
uid | username | |
|---|---|---|
2 | minh | minh@example.com |
Schéma relationnel avec les types de contact
contacts6 Relational Schema
uid | username | firstname | lastname | |
|---|---|---|---|---|
1 | denis | denis.rinfret@example.com | None | None |
2 | minh | minh@example.com | None | None |
cid | type | uid | |
|---|---|---|---|
1 | help@example.com | emergency | 1 |
2 | minh@example.com | friend | 1 |
3 | contact@example.com | colleague | 2 |
4 | ha@example.com | family | 2 |
uid | username | firstname | lastname | cid | email_1 | type | uid_1 | |
|---|---|---|---|---|---|---|---|---|
1 | denis | denis.rinfret@example.com | None | None | 1 | help@example.com | emergency | 1 |
1 | denis | denis.rinfret@example.com | None | None | 2 | minh@example.com | friend | 1 |
2 | minh | minh@example.com | None | None | 3 | contact@example.com | colleague | 2 |
2 | minh | minh@example.com | None | None | 4 | ha@example.com | family | 2 |
Trouver les utilisateurs sans contacts d'urgence
uid | username | |
|---|---|---|
2 | minh | minh@example.com |
uid | username | |
|---|---|---|
2 | minh | minh@example.com |
Comment traitons-nous les relations plusieurs à plusieurs ?
Dans une base de données relationnelle, nous avons besoin d'une table supplémentaire entre les 2 tables.
Par exemple, nous avons besoin d'une table entre "Users" et "Contacts", contenant des clés étrangères pour les ID d'utilisateur et les ID de contact.
Comment récupérons-nous toutes les données ?
Avec 2 jointures.
Qu'en est-il des autres modèles de données ?
Avec des tableaux ?
Avec JSONB ?
Il n'y a pas de solutions miracles pour les relations plusieurs à plusieurs