Le fichier logique (LF) : une autre vue des mêmes données
Un LF ne contient aucune donnée : il présente autrement celles d'un ou plusieurs PF. Pourquoi les concepteurs du System/38 l'ont inventé, un autre ordre par clé, une sélection, une jointure, et ce qu'en fait SQL, démontré avec des Pokémon sur un IBM i 7.5.
En une phrase
Un fichier logique (LF) est un fichier base de données qui représente un ou plusieurs fichiers physiques : il décrit comment présenter leurs données (ordre, sélection, zones, jointure), mais n'en contient aucune. Vu de SQL, dit IBM, un LF est l'équivalent d'une vue ou d'un index.
Pourquoi les LF existent
Dès 1978, le recueil technique d'IBM sur le System/38 annonce, parmi les caractéristiques clés de ce que le système offre à ses utilisateurs, l'indépendance des programmes vis-à-vis de la structure physique des fichiers, grâce aux fichiers logiques. L'idée : les données sont rangées une fois, dans les PF ; chaque programme les voit comme il en a besoin, dans son ordre, avec ses zones, sans dupliquer les données.
Le même recueil décrit les LF comme des vues logiques et des ordres différents des données des PF, jusqu'à entremêler plusieurs PF dans un seul ordre (le LF multi-format). La documentation actuelle d'IBM ajoute un usage précieux : quand on ajoute une zone à un PF, un LF peut présenter l'ancien format aux programmes existants, qui n'ont pas besoin d'être recompilés.
Nos deux PF de départ :
A* Pokemon : un enregistrement par Pokemon, toutes generations
A R POKEMONR TEXT('Pokemon')
A NUMPOK 4S 0 COLHDG('No' 'Pokedex')
A NOM 12A COLHDG('Nom')
A TYPE1 10A COLHDG('Type')
A GEN 1S 0 COLHDG('Gen')
A K NUMPOK
A* Attaques : plusieurs par Pokemon
A R ATTAQUER TEXT('Attaque')
A NUMPOK 4S 0 COLHDG('No' 'Pokedex')
A ATTAQUE 15A COLHDG('Attaque')
A PUISS 3S 0 COLHDG('Puissance')
A K NUMPOK
A K ATTAQUE
Un autre ordre : la clé
POKEMON est trié par numéro de Pokédex. Pour les lire par type, puis par nom, un LF suffit :
A* LF : les Pokemon dans lordre du type, puis du nom
A R POKEMONR PFILE(POKEMON)
A K TYPE1
A K NOM
PFILE(POKEMON) désigne le PF. Aucune zone n'est listée : le LF reprend alors le format du
PF, et IBM impose que son nom soit le même (POKEMONR). Les deux lignes K forment la nouvelle clé. On crée le LF avec
CRTLF, comme un PF avec CRTPF :
CRTLF FILE(JOBIPOK/POKETYPE) SRCFILE(JOBIPOK/QDDSSRC)
CPC7301 Fichier POKETYPE créé dans la bibliothèque JOBIPOK.
CPC7305 Membre POKETYPE ajouté au fichier POKETYPE de JOBIPOK.
Un programme RPG qui lit ce LF par clé reçoit les Pokémon dans l'ordre voulu :
**free
// Lit le LF POKETYPE dans l'ordre de sa cle : type, puis nom.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-f poketype keyed;
read poketype;
dow not %eof(poketype);
snd-msg %trim(type1) + ' : ' + %trim(nom);
read poketype;
enddo;
*inlr = *on;
Électrik : Pichu
Électrik : Pikachu
Eau : Carapuce
Eau : Kaiminus
Feu : Héricendre
Feu : Salamèche
Plante : Bulbizarre
Plante : Germignon
Psy : Lugia
Psy : Mewtwo
« Électrik » passe avant « Eau » : la clé est triée sur les codes EBCDIC des caractères, où les
majuscules accentuées comme É viennent avant les lettres sans accent. Un SQL
ORDER BY TYPE1, NOM sur notre système rend le même ordre.
SELECT * FROM JOBIPOK.POKETYPE a rendu les Pokémon dans l'ordre du numéro, de Bulbizarre
à Lugia, pas dans celui du type. Pour SQL, le LF désigne des données, et c'est l'optimiseur qui choisit
comment les lire : seul ORDER BY garantit un ordre.
Une sélection : seulement le type Feu
Une ligne S (sélection) avec COMP ne garde que certains enregistrements :
A* LF avec selection : les Pokemon de type Feu
A R POKEMONR PFILE(POKEMON)
A K NOM
A S TYPE1 COMP(EQ 'Feu')
SELECT * FROM JOBIPOK.POKEFEU
NUMPOK NOM TYPE1 GEN
4 Salamèche Feu 1
155 Héricendre Feu 2
Un programme qui lit POKEFEU ne voit jamais les autres Pokémon : la sélection est faite par le système, pas par le programme.
La jointure : le Pokémon et ses attaques
Le LF de jointure réunit sur une même ligne des zones de plusieurs PF :
A* LF de jointure : le nom du Pokemon avec chacune de ses attaques
A R POKEJOINR JFILE(POKEMON ATTAQUE)
A J JOIN(POKEMON ATTAQUE)
A JFLD(NUMPOK NUMPOK)
A NUMPOK JREF(POKEMON)
A NOM
A ATTAQUE
A PUISS
A K NUMPOK
JFILE(POKEMON ATTAQUE): les fichiers joints. Le premier est le fichier primaire, les autres sont secondaires.- La ligne
Jdécrit une jointure :JOINdonne la paire de fichiers,JFLDles zones qui les relient (le numéro dans les deux). JREF(POKEMON): NUMPOK existe dans les deux PF, il faut dire lequel prendre.- La clé
K NUMPOKvient du fichier primaire, comme l'exige IBM.
SELECT * FROM JOBIPOK.POKEJOIN
NUMPOK NOM ATTAQUE PUISS
1 Bulbizarre Fouet Lianes 45
4 Salamèche Flammèche 40
7 Carapuce Pistolet à O 40
25 Pikachu Éclair 40
25 Pikachu Tonnerre 90
155 Héricendre Flammèche 40
Six lignes : Pikachu deux fois, et les Pokémon sans attaque (Mewtwo, Germignon, Kaiminus, Pichu,
Lugia) ont disparu. Pour les garder, le mot-clé JDFTVAL, au niveau du fichier, complète
les zones absentes par leurs valeurs par défaut, blancs et zéros :
A* LF de jointure avec JDFTVAL : aussi les Pokemon sans attaque
A JDFTVAL
A R POKEJDFTR JFILE(POKEMON ATTAQUE)
A J JOIN(POKEMON ATTAQUE)
A JFLD(NUMPOK NUMPOK)
A NUMPOK JREF(POKEMON)
A NOM
A ATTAQUE
A PUISS
A K NUMPOK
NUMPOK NOM ATTAQUE PUISS
1 Bulbizarre Fouet Lianes 45
…
150 Mewtwo 0
152 Germignon 0
155 Héricendre Flammèche 40
158 Kaiminus 0
172 Pichu 0
249 Lugia 0 (11 lignes)
Les règles du LF de jointure
- On ne peut pas modifier un PF à travers un LF de jointure : il est en lecture seule.
- DFU (donc UPDDTA) ne sait pas afficher un LF de jointure.
- Un seul format, qui ne peut pas être partagé avec un autre fichier.
- Les zones clés viennent du premier fichier de JFILE, le fichier primaire.
- Pas de contrôle de validation (commitment control).
UPDATE JOBIPOK.POKEJOIN SET PUISS = 50 WHERE NUMPOK = 4
SQL0150 Vue, index ou table POKEJOIN de JOBIPOK en lecture seule.
Pour modifier, on passe par les PF eux-mêmes.
Les équivalents SQL : index et vues
Clé, sélection, jointure : SQL fait la même chose avec deux instructions.
-- La clé de POKETYPE
CREATE INDEX JOBIPOK.POKEMON_PAR_TYPE ON JOBIPOK.POKEMON (TYPE1, NOM);
-- La sélection de POKEFEU
CREATE VIEW JOBIPOK.POKEMON_FEU AS
SELECT NUMPOK, NOM, TYPE1, GEN FROM JOBIPOK.POKEMON WHERE TYPE1 = 'Feu';
-- La jointure avec JDFTVAL : un LEFT JOIN
CREATE VIEW JOBIPOK.POKEMON_ATTAQUES AS
SELECT P.NUMPOK, P.NOM, A.ATTAQUE, A.PUISS
FROM JOBIPOK.POKEMON P
LEFT JOIN JOBIPOK.ATTAQUE A ON A.NUMPOK = P.NUMPOK;
La vue rend les 11 lignes, dont 6 avec une attaque. Et le catalogue montre que ces objets SQL sont des fichiers logiques, avec un nom système de 10 caractères fabriqué par le système :
SELECT TABLE_NAME, SYSTEM_TABLE_NAME, NATIVE_TYPE, SQL_OBJECT_TYPE, NUMBER_BASED_ON_FILES
FROM QSYS2.SYSFILES WHERE TABLE_SCHEMA = 'JOBIPOK' AND NATIVE_TYPE = 'LOGICAL'
POKEATK POKEATK LOGICAL 2
POKEFEU POKEFEU LOGICAL 1
POKEJDFT POKEJDFT LOGICAL 2
POKEJOIN POKEJOIN LOGICAL 2
POKEMON_ATTAQUES POKEM00003 LOGICAL VIEW 2
POKEMON_FEU POKEM00002 LOGICAL VIEW 1
POKEMON_PAR_TYPE POKEM00001 LOGICAL INDEX 1
POKETYPE POKETYPE LOGICAL 1
Seul le LF multi-format n'a pas d'équivalent : SQL refuse de le lire (SQL7003).
Un LF a un coût
Un LF à clé tient un chemin d'accès, mis à jour par défaut à chaque modification du
PF : le paramètre MAINT de CRTLF vaut *IMMED, et IBM précise que la
maintenance immédiate se fait que le fichier soit ouvert ou non. Sur nos huit fichiers logiques, les
six qui ont une clé sont en *IMMED : chaque écriture dans POKEMON les tient tous à jour.
Les deux vues SQL, elles, n'ont pas de chemin d'accès. Avant d'en créer un nouveau, on regarde ceux qui
existent avec DSPDBR (relations base de données) ou la colonne
BASED_ON_FILES de QSYS2.SYSFILES.
À retenir
- Un LF ne contient pas de données : il présente celles d'un ou plusieurs PF.
- Clé (K), sélection (S et COMP), zones choisies, jointure (JFILE, JOIN, JFLD, JREF, JDFTVAL).
- En SQL, un SELECT sur un LF n'est trié que par ORDER BY.
- Un index SQL et une vue SQL sont des fichiers logiques ; seul le multi-format n'a pas d'équivalent.
Sources
Les exemples ont été créés et relevés sur un IBM i 7.5 (voir la méthode). Les définitions et les règles viennent de ces sources, consultées le 16 octobre 2026 :
- IBM System/38 Technical Developments : File and data definition facilities in System/38, IBM, C. D. Truxal et S. R. Ridenour (1978, PDF numérisé). Les descriptions de données redondantes et divergentes d'avant (« each program … has required a separate definition of the data »), la description centrale par les DDS réutilisée par les compilateurs et les utilitaires, le contrôle de niveau, les fichiers décrits dans le programme conservés pour la conversion, les PF à un seul format et leurs membres. Le même recueil contient l'article de Conway et Harvey sur le choix d'un formulaire déclaratif séparé du programme, et l'indépendance des programmes vis-à-vis de la structure physique grâce aux fichiers logiques ; le LF qui fait suivre chaque en-tête de ses lignes de détail.
- IBM i 7.5 Database : Database programming, IBM (PDF). Définitions du fichier physique, du fichier logique (« contains no data ») et du membre ; un seul membre « en règle générale » et au moins un membre avant toute entrée-sortie ; premier membre choisi selon la date et l'heure de création ; fichier de référence de zones et fichier créé MBR(*NONE) ; attributs des fichiers source (92 = 6 + 6 + 80, sans clé, plusieurs membres) ; LF qui présente l'ancien format ; règles des LF de jointure (lecture seule, pas de DFU, clé du fichier primaire, JDFTVAL, un seul format) ; vu de SQL, LF = vues et index.
- IBM i 7.5 Database : SQL programming, IBM (PDF). CREATE ALIAS pour un membre, « sans substitution » ; tables partitionnées (option 27, Db2 Multisystem), dont chaque partition est un membre ; ORDER BY pour garantir l'ordre des lignes.
- IBM i 7.2 Programming : DDS for physical and logical files, IBM (PDF). Mots-clés des fichiers logiques : PFILE, sélection (S et COMP), JFILE, JOIN, JFLD, JREF, JDFTVAL ; un seul format R par fichier physique.
- L'aide en ligne des commandes citées, livrée avec IBM i 7.5 et reprise en français dans les fiches des commandes CL de ce site. Paramètres de CRTPF, CRTLF, CRTSRCPF, ADDPFM, OVRDBF, UPDDTA, DSPPFM, RGZPFM, CPYF, CRTBNDRPG et CRTBNDCL.
Questions fréquentes
À quoi sert un fichier logique (LF) ?
Un LF ne contient aucune donnée : il présente autrement les données d'un ou plusieurs PF, dans un autre ordre (clé), avec une sélection d'enregistrements, un sous-ensemble de zones ou une jointure. Il rend les programmes indépendants de la structure physique des fichiers.
Un SELECT sur un LF à clé rend-il les lignes dans l'ordre de la clé ?
Non. Sur notre IBM i 7.5, SELECT * sur un LF trié par type a rendu les lignes dans l'ordre du numéro. Seul ORDER BY garantit l'ordre en SQL ; la clé du LF ne joue que pour une lecture par clé, en RPG par exemple.
Comment faire une jointure avec un LF ?
Avec un LF de jointure : JFILE donne les fichiers (le premier est le primaire), une ligne J avec JOIN et JFLD donne les zones de liaison, JREF lève l'ambiguïté des zones communes. Sans JDFTVAL, seuls les enregistrements qui ont une correspondance sont rendus ; avec JDFTVAL, comme un LEFT JOIN. Un LF de jointure est en lecture seule.
Faut-il créer des LF ou des index et des vues SQL ?
Les deux produisent le même type d'objet : un index SQL et une vue SQL sont des fichiers logiques. Pour un nouveau développement, CREATE INDEX et CREATE VIEW (avec LEFT JOIN) couvrent la clé, la sélection et la jointure ; seul le LF multi-format n'a pas d'équivalent SQL.