Format des données

Jean-Yves FOCK-HOON

Cette note technique vous démontrera combien il est important que vous stockiez vos données correctement. La commande SELECTION VERS TABLEAU a été optimisée, mais suppose, pour être efficace, que les données soient stockées dans le bon format. De plus, avoir un mauvais format de données peut potentiellement augmenter le risque de corruption des données. Restocker vos enregistrements quand beaucoup de changements ont été faits dans votre structure est loin d'être une mauvaise idée. Cette note technique vous fournit une méthode générique permettant de faire cela. ♪

- Titre : Format des données

- Auteur : Jean-Yves FOCK-HOON

- Parution : 1 octobre 2005

- Licence : Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.

Sommaire

- I. Résumé

- II. Une fonctionnalité importante de 4D

- III. Comment cela fonctionne-t-il ?

- IV. Un exemple concret

- V. Bien sûr… mais

- VI. Comment restocker tous les enregistrements ?

- VII. En conclusion

- VIII. Base exemple

I - Résumé

Cette note technique vous démontrera combien il est important que vous sauviez vos données correctement.

II - Une fonctionnalité importante de 4D

Une des forces de 4D est que vous pouvez ajouter des champs à la volée. Vous pouvez aussi changer le type d'un champ à la volée. Dans d'autres SGBD, vous devriez exporter toutes les données et les réimporter avec la nouvelle structure. Ceci est un des grands avantages de 4D ; vous n'avez pas à exporter puis importer vos 16 millions d'enregistrements si vous changez le type d'un champ.

III - Comment cela fonctionne-t-il ?

Mais comment cela fonctionne-t-il en interne ?

Une fois l'enregistrement sauvegardé, 4D ne change pas le format sans confirmation. C'est une optimisation de 4D. Dans le même temps, cela vous permet de revenir à l'état précédent des données si vous avez fait une erreur. Par exemple, si vous avez un champ texte avec des valeurs et que vous retypiez le champ en NUMERIQUE, sauvegarder tous les enregistrements devrait convertir vos valeurs chaîne en valeurs numériques. Et si vous avez changé le type par erreur et souhaitez revenir au type TEXTE, il sera trop tard. Vous retrouverez vos valeurs numériques, mais en chaîne : adieu mots, phrases, paragraphes…

Mais ce n'est pas ce que fait 4D automatiquement. Vous perdrez les phrases si vous avez modifié le contenu du champ en question. Mais sauvegarder l'enregistrement sans modifier le champ ne va pas le reformater.

C'est pourquoi lorsque vous changez le type d'un champ, restocker un enregistrement existant en modifiant un autre champ, vous pouvez toujours retrouver la valeur du champ si vous le retyper dans l'ancien format.

IV - Un exemple concret

Pour illustrer cela, passons en Mode Structure et Mode Utilisation dans notre base démo. Nous pouvons regarder la Table [Table1] et voir qu'elle contient deux champs alphanumériques. En Mode Utilisation, le champ2 de cette table contient la même valeur, « Valeur texte ».

Revenez en Mode Structure et changez le type du [Table1]Champ2 en Numérique. En Mode Utilisation vous verrez que votre « Valeur texte » a été remplacée par 0 (Num(« Valeur texte »)=0).

Cela ne veut pas dire que 4D a converti les valeurs dans les enregistrements. Cela signifie que 4D les a converties pour l'affichage simplement. À la lecture de l'enregistrement, 4D voit que la valeur est une chaîne, alors il essaie de traiter la valeur avec le type courant.

Si maintenant vous lancez une Méthode projet qui modifie et sauvegarde tous les enregistrements en modifiant seulement le champ1, vous pourrez constater que les valeurs sont à 0 dans le champ2. Les enregistrements ont bien été sauvegardés, mais seulement le champ1 a été modifié et pas le champ2.

Nous pouvons retyper le champ 2 de numérique à alphanumérique. Repassons en Mode Utilisation et nous verrons que nous avons retrouvé notre valeur alphanumérique « Valeur texte ».

Ainsi, 4D ne modifie pas le contenu des champs si ce n'est pas nécessaire. Ceci a deux avantages :

- c'est une sécurité, car cela vous permet de retrouver les valeurs d'origine si vous changez le type de champ ;

- c'est une optimisation de 4D ; si vous restockez un gros enregistrement, 4D ne sauvegardera que ce qui est nécessaire et vous n'aurez pas besoin de reformater et de resauvegarder l'ensemble de l'enregistrement, ce qui serait une perte de temps.

V - Bien sûr… mais

Cette fonctionnalité a un coût caché. Comme nous l'avons vu, 4D essaie de convertir la valeur courante de façon à ce qu'elle convienne avec le type courant, mais il ne restocke pas le champ tant qu'une modification de son contenu n'est pas faite.

Pour illustrer ceci, nous allons exécuter la Méthode projet M_Selection2Tableau en Mode Utilisation ou Mode Menus Créés (Menu Démonstration, Ligne Sélection vers Tableau). Cette méthode effectue une sélection vers un tableau pour chaque champ. Le premier SELECTION VERS TABLEAU « ne compte pas ». Il est simplement fait pour charger les enregistrements en mémoire. Nous allons calculer le temps nécessaire à un SELECTION VERS TABLEAU pour les deux champs. La taille du cache est conséquente et les enregistrements sont très petits. Ceci a été fait dans le but de minimiser toute influence extérieure pour ce test.

Comme vous pouvez le constatez, le SELECTION VERS TABLEAU sur le deuxième champ est plus lent que sur le premier. C'est parce que le champ 2 a été stocké avec différents formats. Certains enregistrements contiennent dans ce champ une valeur chaîne, d'autres contiennent une valeur numérique. À l'exécution du SELECTION VERS TABLEAU, 4D détecte que tous les champs n'ont pas le même format et au lieu d'une méthode interne optimisée 4D lancera une méthode traditionnelle qui exécutera la conversion.

Nous pouvons maintenant restocker tous les enregistrements en modifiant tous les champs, en exécutant les Méthodes M_ToutStocker1 ou M_ToutStocker2 en Mode Utilisation (ou en Menu Créés Lignes Tout stocker 1 et Tout stocker 2), puis re-exécutons notre SELECTION VERS TABLEAU. Nous pouvons constater alors que le temps est presque le même. Restocker nos enregistrements à permis d'améliorer les performances.

Si vous utilisez des bases créées avec des anciennes versions comme des versions 5, mises à jour en version 6 puis 2003 et 2004, il y a certainement encore des enregistrements créés avec ces anciennes versions, il est alors possible que ces enregistrements ne correspondent plus à la description courante de l'enregistrement. 4D fera son possible pour afficher les informations, mais il peut aussi arriver que ces enregistrements n'aient pas tous les champs requis, ou que les champs que vous avez ajoutés au fil des années n'aient pas été restockés.

À ce stade, ceci peut causer quelques problèmes dans votre code, ou causer un ralentissement, comme décrit précédemment. C'est pourquoi vous devez tout restocker avec la description appropriée de l'enregistrement.

VI - Comment restocker tous les enregistrements ?

Comme nous l'avons vu, vous pouvez exécuter la Méthode M_ToutStocker1 par exemple.

Cette technique est très simple. Nous bouclons sur toutes les tables. Nous pouvons déterminer notre Table en utilisant les fonctions Table et Nom de la table. Nous connaissons le nombre de Tables en utilisant la fonction Nombre de tables. Pour chaque Table, nous pouvons charger et sauvegarder nos enregistrements. Pour chaque Table, nous connaissons le nombre de champs en utilisant la fonction Nombre de champs. Nous pouvons maintenant charger tous les enregistrements et modifier tous les champs avec la Méthode M_MàJChamps.

NbTables:=Nombre de tables

Boucle (iTable;1;NbTables)
pTable:=Table(iTable)
NbFields:=Nombre de champs(iTable)
TOUT SELECTIONNER(pTable->)
Tant que (Non(Fin de selection(pTable->)))
M_MàJChamps
STOCKER ENREGISTREMENT(pTable->)
ENREGISTREMENT SUIVANT(pTable->)
Fin tant que

Fin de boucle   ` iTable

La Méthode projet M_MàJChamps boucle sur tous les champs. Nous pouvons utiliser la fonction Champ pour récupérer un pointeur sur le champ et LIRE PROPRIETES CHAMP pour retrouver toutes les informations en fonction du type du champ. Nous utilisons également la fonction Type pour les champs de la sous-table.

Cette méthode est presque simple. Nous avons un large Au cas où. Nous savons que le champ ne sera pas réécrit si ce n'est pas nécessaire. Alors si nous voulons que le champ soit restocké, nous devons forcer un calcul sur ce champ.

Par exemple, pour un champ texte ou alphanumérique, nous pouvons ajouter une chaîne vide. Dans notre Au cas où, nous avons deux étapes. Comme nous sauvegardons tous les champs, pourquoi ne pas en profiter pour vérifier nos données aussi ? Filtrer nos chaînes, supprimer les caractères indésirables, vérifier la longueur de la chaîne… Nous pouvons avoir sauvegardé une chaîne de 30 caractères et remanier le champ avec 5 caractères seulement. Tous les nouveaux enregistrements auront une longueur de 5 caractères, mais les anciens enregistrements auront toujours une valeur de 30 caractères. Dans ce cas, nous allons simplement tronquer la chaîne si nécessaire.

Pour les valeurs numériques, nous pouvons ajouter 0 à nos valeurs ou utiliser les fonctions Chaine ou Num pour éliminer les valeurs NaN (ex. : MonChamp:=Num(Chaine(MonChamp))). Dans notre exemple, nous utilisons les fonctions Num et Chaine.

Les dates et les heures sont en fait, dans 4D, des valeurs numériques. Nous pouvons ajouter 0 à ces valeurs. Si vous avez un champ BLOb et le convertissez en Date ou Heure, ajoutez 0 est suffisant pour restocker le champ avec les valeurs nulles correspondantes (00:00:00 ou 00/00/00). Mais on peut aussi utiliser d'autres commandes comme Ajouter a date, Date, Num, Chaine et Chaine heure si nécesssaire.

Il est très difficile de vérifier les BLOb. Ils peuvent être petits ou grands. Personne ne connaît mieux que vous leur taille et ce qu'ils contiennent. Dans notre exemple, nous réassignons simplement le contenu en utilisant une autre variable BLOb.

Vous ne pouvez pas simplement ajouter une chaîne vide ou 0 à une image. Vous pouvez utiliser la même technique que pour les BLOb, mais les opérateurs peuvent être utilisés pour les images. On pourrait ajouter une image, mais ce n'est pas recommandé, ou simplement multiplié notre image par 1. Cette multiplication nous semble la solution la plus astucieuse.

Les valeurs booléennes sont simples. Si vous voulez retrouver les mêmes résultats, vous devez utiliser un OU FAUX (| Faux) :

Vrai | Faux est Vrai
Faux | Faux est Faux.

Le dernier type de champ est la sous-table. Nous pourrions aussi vouloir restocker des sous-enregistrements. Comment faire cela ?

Il y a une fonctionnalité non documentée dans 4D 2004. Vous pouvez utiliser la commande LIRE TITRE CHAMPS et la fonction Champ pour obtenir la liste de tous les champs de la sous-table et un pointeur sur ceux-ci.

LIRE TITRES CHAMPS(pField->;SubfieldTitles;SubfieldNums)

pSubField:=Champ(iTable;iField;SubfieldNums{$i_SubField})

LIRE TITRE CHAMPS retourne le nom du sous-champ et son numéro pour une sous-table indiquée en premier paramètre. Nous devons juste utiliser la fonction Champ pour récupérer le numéro de la Table, le numéro de la sous-table et le numéro du sous-champ dans la sous-table. Cette fonctionnalité n'est pas documentée et donc non supportée, mais elle fonctionne en 4D 2004.

Ne basez pas toute votre base de données sur cette fonctionnalité, car elle pourra disparaître un jour et considérer qu'elle n'est pas supportée par 4D.

Nous avons un pointeur sur le sous-champ, nous pouvons maintenant déterminer son type et utiliser la même technique que pour les champs de la table principale. La commande LIRE PROPRIETES CHAMP ne fonctionnerait pas avec ce style de pointeur. Vous ne retrouveriez pas la longueur d'un sous-champ alphanumérique. De plus, ça ne fonctionnerait avec des sous-tables dans des sous-tables, qui ne sont plus supportées par 4D.

VII - En conclusion

Beaucoup de code 4D a été optimisé. Ce n'est pas spécifique à la commande SELECTION VERS TABLEAU. Obtenir des résultats optimisés suppose que les données soient stockées dans le bon format. Si le format ne correspond pas, 4D reviendra à la façon traditionnelle, à « l'ancienne mode ». Ceci limitera considérablement les performances. De plus, avoir un mauvais format de données peut potentiellement augmenter le risque de corruption des données. 4D Tool peut récupérer vos données, mais ne peut pas restocker les valeurs définies dans les champs, c'est pourquoi restocker vos enregistrements quand beaucoup de changements ont été faits dans votre structure est loin d'être une mauvaise idée.

VIII - Base exemple

Téléchargez la base exemple : base exemple