Types complexes

De plus en plus on est amené à stocker des types plus compliqués dans nos bases. Dans ce chapitre, on explore l'utilisation de quelques-uns de ses types.

Dates

Une date est à la fois une donnée composée (année, mois, jour, heure, minute, secondes) à la fois une donnée simple (le nombre de secondes depuis 01/01/1970).

Pour les raisons de lisibilitĂ©, on prĂ©fĂšre le format complexe. Mais, pour les raisons d’utilisation (trier, par exemple, ou bien les opĂ©rations du genre supĂ©rieur Ă  ou infĂ©rieur Ă ) le format simple est prĂ©fĂ©rable.

Par exemple, en France, on présente une date avec le format jj/mm/aaa.

Ce formant n'est pas trÚs pratique pour trier ! Si on a un ensemble de dates de plusieurs années, comment on peut trier les dates en ordre croissant ?

Un format plus pratique serait pour trier sera : aaaa/mm/jj (l’unitĂ© le plus grande vers l’unitĂ© le moins grande).

Mais, le format est plutÎt précisé par la culture, pas par son cÎté pratique. Aux Etats Unis, c'est encore pire : mm/jj/aaaa !

En SQL, il y a des types Date, Time, DateTime, TimeStamp et Year qui stocke la date et/ou l’heure dans un format normalisĂ© et indĂ©pendant de la culture. Lorsqu’on rĂ©cupĂšre cette donnĂ©e cotĂ© client, c'est Ă  nous de le traduire dans le format local pour l'affichage.

Attention au fuseau horaire !

Imaginons, votre appli est internationale. Mais, les serveurs se trouvent en France (GMT+2). Vous calez des rendez-vous de vos salariĂ©s partout dans le monde. L’appli doit envoyer un e-mail 10 minutes avant le rendez-vous.

Une personne en Australie cale un rendez-vous Ă  10h00 le matin.

  • Nous stockons quelle heure dans la base de donnĂ©es ?

  • Quelle est l’heure sur le serveur (avec le SGBDR) ?

Son gĂ©rant, aux Etats Unis, veut voir l’heure de son rendez-vous :

  • Elle va voir l’heure locale australienne ?

  • Ou elle va voir l’heure locale Ă  New York ?

Aurez-vous une stratégie pour régler tous ces problÚmes ?

UTC au secours !

Coordinated Universal Time

Nous convertissons toujours vers l’heure Ă  GMT-0 avant de le stocker dans la base de donnĂ©es.

Donc 10h00 en Australie (GMT+11) = 23h00 de la veille (GMT-0).

Donc le rdv du 2022-02-14 à 10h en Australie est stocké comme 2022-02-13 à 23h dans la base de données.

Ensuite, l’affichage et/ou raisonnement sur cette date dĂ©pend d’un point-de-vue, c’est-Ă -dire, il faut prĂ©ciser le fuseau horaire de notre point de vue, afin de faire la conversion :

  • Dans l’heure australienne, ajouter 11 heures : donc 2022-02-13 Ă  23h + 11 heures = 2022-02-14 Ă  10h

  • Dans l’heure de New York, soustraire 5h: donc 2022-02-13 Ă  23h – 5 heures = 2022-02-13 Ă  18h

Blob

Un blob permet de stocker des grandes quantitĂ©s de donnĂ©es (des fichiers/images/
) comme sĂ©quence d’octets : https://mariadb.com/kb/en/blob/

Mais, est-ce que c'est une bonne pratique ?

Avantages :

  • Facile Ă  accĂ©der, via son ID ou dans un join avec d’autres tables

  • On peut sauvegarder la base et tous les fichiers en une seule action

  • Les rĂšgles d’accĂšs de la SGBDR sont applicables aussi aux fichiers

DĂ©savantages :

  • Il faut ĂȘtre fastidieux dans les clauses where : on risque de transfĂ©rer les fichiers entiers dans nos - requĂȘtes !

  • Sauvegarde de la base de donnĂ©es trĂšs lourde et longue

  • Pas trĂšs optimisĂ© : notre SGBDR doit passer beaucoup de temps Ă  accĂ©der au disque et transfĂ©rer des donnĂ©es, alors d’autres systĂšmes existe (CDN par exemple) qui optimise le stockage et transfert des fichiers

N’oubliez pas qu’un fichier ou image est souvent statique et ne change pas souvent, donc son stockage et diffusion peut-ĂȘtre optimisĂ©e en dehors de notre SGBDR.

Personnellement, j'ai eu des trÚs mauvaises expériences avec le stockage des fichiers directement dans la base de données. Atteint une lourdeur de 70Go, avec 99% de cet espace pris par des photos.

Les sauvegardes sont devenues trĂšs compliquĂ©es, voire impossibles. Des mauvaises formulations des requĂȘtes (des clauses where trop ouvertes, le manque de pagination, etc) rendaient la plateforme instable et difficile Ă  gĂ©rer.

Aujourd'hui, dans l'ùge du cloud, je préfÚre stocker des images dans une solution de stockage (type CDN), et seulement stocker une référence qui pointe vers l'image dans le SGBDR.

JSON

On peut stocker des colonnes qui contiennent du JSON, et valider que le JSON est bien formaté :

create table livre (
  id int not null auto_increment,
  page JSON CHECK (JSON_VALID(page)),
  primary key (id)
);


insert into livre (page) values 
('{"number": 1, "text": "Lorem ipsum", "chapter": "And then there was one"}');

Il existe de nombreuses fonctions qui permettent de travailler avec le format JSON dans MariaDB : https://mariadb.com/kb/en/json-functions/.

Stocker du JSON dans un SGBDR casse la logique de normalisation (pas en 1NF – donnĂ©e composĂ©e).

Donc il n'y a pas de garantie de non-redondance ni intégrité.

Créer une colonne de type JSON paraßt simple, facile à implémenter, et facile à faire évoluer - surtout face à un domaine qu'on ne maßtrise pas.

Mais, Ă  terme, cela pourrait ĂȘtre un piĂšge :

  • il n'y a pas de validation des contraintes sur les sous-informations stockĂ©es dans le JSON

  • il serait impossible de raisonner sur les donnĂ©es stockĂ©es dans une colonne type JSON (faire des select dessus)

  • on ne peut pas assurer l'intĂ©gritĂ© des donnĂ©es en format JSON.

Les bases de données type NoSQL offrent quelques solutions limitées à ces problÚmes. Par exemple, MongoDB stocke un format quasi identique à JSON (qui s'appelle BSON), et permet d'imposer un schéma de validation sur les données. En revanche, il n'y a aucune notion d'intégrité référentielle entre les collections (dans une base NoSQL, cette intégrité est plutÎt implicite via la relation hiérarchique d'un document et ses sous-documents.)

DerniĂšre mise Ă  jour