(Caveat : Ce billet à haute teneur informatique tente de s’adresser aussi aux non-informateux.)

Extrait datant de 2002 et traduction de l’excellent site de questions-réponses sur Oracle AskTom :

Question d’un utilisateur d’Oracle au gourou :

« J’ai une table avec un champ de type BLOB (un champ destiné à contenir du binaire en vrac — NDT) , du genre de :

Create table trx (
trxId Number(18),
trxType Varchar2(20),
objValue Blob,
...
)

Le BLOB contient un objet Java sérialisé (sauvegardé dans un fichier ou une base) en fait différents objets qui implémentent tous la même interface.

Nous accédons toujours à l’objet via le conteneur J2EE
(par programme, quoi), ça marche bien jusque ici.
Maintenant les utilisateurs veulent créer des rapports avec Sqlplus
(un requêteur SQL en ligne de commande), Crystal Reports (un requêteur et créateur de jolis rapports), etc. Donc il faudrait une solution à ce problème de BLOB. »

Pour ceux qui n’ont pas sauté d’effroi à la lecture, je résume :

Le programme du monsieur manipule des objets Java (par exemple des objets « Livraison » ou « Employé » ou « Mouvement budgétaire » ou « Nuitée » selon que le logiciel traite de logistique, de paye, de finance ou d’hôtellerie). Ces objets sont constitués de code exécutable (en gros, immuable) et de variables parfois nombreuses (dans les exemples précédents : la quantité, les articles, l’adresse de livraison, le nom du destinataire final, la date ; le salaire, l’adresse, le CV ; l’imputation, le montant, la date, le type ; le numéro du client, celui de la chambre, un drapeau « petit déjeuner oui/non », le numéro de carte bleue de réservation...).

La mémoire de l’ordinateur étant volatile et finie, il faut sauvegarder ces données : typiquement dans un fichier sur le disque dur ou, de manière plus efficace et ordonnée, dans une base de données (Oracle, MySQL, ce que l’on veut).

De nos jours, une base de données est généralement ordonnée autour de « tables » dans lesquelles les données (chiffres, dates, libellés...) sont triées en colonnes (ou « champs »). L’intérêt de ce formalisme réside dans 1) un cadre propre où ranger d’entrée toute nouvelle donnée que l’on voudrait stocker, et 2) permettre à plusieurs applications de traiter des mêmes données sans se donner trop de mal à comprendre sous quel format les autres applications les ont stockées. Une date va dans un champ DATE, un libellé dans un champ CHAR ou une variante, un nombre dans un champ de type NUMBER, etc. , et notamment des gros morceaux de binaire, comme des images, dans des champs pour binaire de type BLOB sous Oracle.

Ce que fait le naïf questionneur consiste à passer totalement outre ces deux points. Il stocke tout son objet (code binaire exécutable et données) ensemble dans un BLOB. Aucun autre logiciel n’a aucune chance de comprendre comment les données sont organisées, sauf si on le programme lui aussi explicitement pour cela, et ce ne sera pas le cas des outils extérieurs à l’entreprise comme le Crystal Report évoqué.

Équivalent

J’ai du mal à trouver un équivalent réel de cette aberration.

C’est pire que de rédiger ses documents dans une langue que personne ne connaît (exemple de Tom Kyte dans sa réponse). Sans traduction explicite, longue et difficile, personne ne pourra les utiliser. Et encore, une langue suit en général une tradition, mais l’informatique se base sur des standards, de fait ou reconnus qui n’ont aucun rapport avec l’identité culturelle et que l’on se doit d’adopter. Les langues cependant sont à peu près équivalentes, la prédominance du latin, du français, de l’anglais n’étant que contingence historique, alors que dans le cas présent on descend d’un degré dans la flexibilité d’utilisation.

C’est pire que de recréer de zéro une nomenclature. Une nomenclature peut être plus ou moins bancale, et meilleure ou moins bonne qu’une autre, le but final est le même : désigner des objets.

C’est pire qu’une bibliothèque où tous les livres sont soigneusement numérotés mais entassés en vrac dans les rayons. Celui qui veut un livre qu’il a eu entre les mains peut le demander ; celui qui cherche un roman d’espionnage ou un précis de séismologie comparée laissera vite tomber. Et encore : il a une chance de trouver en balayant systématiquement les étagères. (Ce dernier exemple serait donc plutôt l’équivalent d’une table non indexée que l’on doit balayer intégralement, mais où au moins les données sont reconnaissables.) Imaginons que le contenu des livres soit en sanskrit, ou que ceux-ci soient tous sous emballage opaque.

C’est peut-être équivalent à ignorer le concept même de nomenclature et de caractéristique. Imaginons qu’un ordinateur doive rechercher tous les mammifères quadrupèdes herbivores européens dans une liste des noms usuels d’animaux sans aucune autre caractéristique...

Classiquement l’informatique tente de trouver une analogie avec les voitures, et le plus proche que j’imagine ne tombe pas au même niveau : un constructeur de voitures a créé ses propres normes de signalisation, son propre code de la route, et à présent ses voitures veulent circuler au milieu des autres. Mais là encore il s’agit juste de choix différents de norme, pas du choix d’un système intrinsèquement inférieur.

Remède

Ma première pensée dans ce genre de cas est de proposer que l’on fusille celui qui a osé programmer cela. Franchement, même les non-informaticiens qui ne jurent que par Excel et Access (vade retro !) planent dix niveaux de compétence au-dessus de lui.

Comme je suis quelqu’un de trop miséricordieux, ma deuxième pensée est que cela lui a peut-être été imposé par un chef stupide, par sa simple ignorance de non-technicien pas formé au maniement des bases de données, par des objets tellement différents qu’aucun schéma ne se distinguait clairement, par un administrateur de base peu coopératif voire ouvertement hostile (à fusiller aussi) ou au contraire absent, par des contraintes en temps démentielles.

Cependant, n’importe quel concepteur après quelques semaines d’expérience sait que toute donnée doit pouvoir être récupérée ailleurs. Et tout flanquer en vrac n’est PAS une bonne idée.

À moins que ce ne soit un de ces adeptes des technologies empilées, qui considérait que l’accès au moindre objet ne devait surtout pas se faire directement dans la base (ce qui se défend), mais impérativement en passant par des web services qui attaqueraient un serveur d’application Java qui interrogerait Oracle lui-même, créerait les objets et les ferait communiquer avec toute autre application. Sauf que le monde réel ne fonctionne pas comme ça mais préfère souvent le simple et brutal : « toi causer SQL ? » (Mise à jour de 2011 : Tiens, je viens d’en rencontrer une, une appli comme ça : il faut que les développeurs préparent des vues exprès pour les accès extérieurs, sinon c’est sans espoir. Encore est-ce excusé par une flexibilité démoniaque.)

Ou encore est-ce un employé de SAP, où l’accès à la base est aussi streng verboten, mais qui offre vend des interfaces de communication avec le monde extérieur qui m’ont déjà fait hurler mais qui ont le mérite d’exister et de fonctionner.

Ma quatrième pensée replace le problème dans sa perspective historique : autrefois, au néolithique où une application ne quittait pas le mainframe où elle tournait, à l’époque où le concept de « réseau d’entreprise » relevait de la science-fiction (« mais il nous faudrait un autre ordinateur » !), les formats de données étaient propres à chaque application.

Plus tard, dans les temps protohistoriques où les PC se répandaient chez les particuliers, les applications ne communiquaient toujours pas entre elles, et le format de données était contraint par la taille du fichier et la vitesse de chargement. Et puis le verrouillage du format de fichiers est un moyen de garder des clients captifs.

À notre époque connectée et distribuée, l’utilisation d’un format totalement fermé (et ici c’est de verrouillage complet au niveau technique qu’il s’agit, même pas de secret industriel, puisque même les concepteurs ne peuvent aisément corriger le problème !) relève du blasphème.

Ma cinquième pensée est une vacherie que mon cerveau a du mal à ne pas généraliser : « tiens, c’était encore un Indien »...