Bonjour à toutes et à tous
J’ai créé une discussion Aide pour le choix d'une suite SGBD dont le titre dit tout. Grâce aux conseils amicaux et judicieux que j’ai reçus j’ai pu faire mon choix : pour le SGBD ce sera PostgreSQL et pour l’IDE j’ai une short list. J’ai aussi posé assez schématiquement un des problèmes qui va se poser à moi : j’ai déjà des données que j’avais accumulées dans une base créée avec FileMaker Pro et que j’avais exportées dans des fichiers TSV quand j’ai cessé de mettre à jour ce soft.
En quoi consistent ces fichiers :
- Ce sont des fichiers texte tabulés (TSV).
- Chaque table de la base est contenue dans un fichier dédié.
- Ils contiennent les titres des colonnes, les clés primaires et étrangères et les data.
Quel est le problème ?
- Postgres interdit d’assigner des données dans une colonne auto-incrémentée. C’est normal, je ferais pareil à sa place.
Il est donc impossible d’importer les clés primaires dans les colonnes correspondantes.
- Les tables filles auront donc des clés étrangères qui ne correspondent plus aux clés primaires de leurs tables mères. Les relations donc tombent à l’eau.
- Puisque chaque enregistrement des tables mères aura une nouvelle clé primaire il faut donc trouver un moyen d’assigner celle-ci aux clés étrangères des enregistrements liés de ses tables filles.
J’ai retenu une méthode que je soumets à votre sagacité :
- Les tables ne comporteront pas de colonne pour importer les clés primaires depuis le fichier texte. Les clés primaires seront assignées par le SGBD.
- Les clés étrangères ne seront pas importées dans les tables liées puisqu’elles ne sont plus valides.
- Lors du développement de ma base, pour chaque table possédant une relation de type mère ou fille, je vais créer ce que j’appelle une table annexe qui sera dédiée à l’import des clés et de rien d’autre. Elles auront les colonnes suivantes :
- Une clé primaire comme toute bonne table qui se respecte.
- La clé étrangère correspondant à la clé primaire de sa table mère assignée par le SGBD au moment de la création de l’enregistrement.
- La clé primaire de l’enregistrement importé (peut-être pas nécessaire mais utile quand même).
- Pour les tables filles liées à une autre table mère, les clés étrangères de l’enregistrement importé.
- Il ne restera plus qu’à assigner aux clés étrangères les clés primaires qui vont bien.
Pour bien illustrer mon propos je vous présente une partie de mon schéma. Il s’agit des tables Artist et Opus (les œuvres). Elles ont une relation de n à n via une table intermédiaire Creating avec laquelle elles ont une relation de 0 à n. Dans ces définitions j’ai omis les data proprement dites pour alléger. Il n’y a donc que les clés.
Un petit mot d’abord sur mes conventions de nommage :
- J’écris tout en anglais, de façon explicite et sensible à la casse.
- Une table représentant une entité porte le nom complet de celle-ci.
- Une table de liaison entre plusieurs tables (comment appelle-t-on ce genre de table ?) a en général pour nom un verbe au participe présent (pour éviter le mot clé Create par exemple) et parce que il s’agit en général d’une action.
- Les clés primaires ont le préfixe PK_ suivi de <nom de la table>
- Les clés étrangères ont le préfixe FK_ suivi de <nom de la table>_2_<nom de la clé primaire référencée>.
- Les index ont le préfixe Ind_ suivi de <nom de la colonne>
Voilà déjà les tables principales
Code:CREATE TABLE “Artist” (/* This table records all Artists: composers, librettists, musicians, etc. It does not contain their Name because they may have several of them. They are stored in the secondary table Artist_Name.*/“PK_Artist” longint PRIMARY KEY SERIAL UNIQUE CREATE INDEX Ind_PK_Artist,);CREATE TABLE “Opus” ( /*This table records musical works*/“PK_Opus” longint PRIMARY KEY SERIAL UNIQUE CREATE INDEX “Ind_PK_Opus”,); CREATE TABLE “Creating” (/*Relation table between Artist and Opus.*/“PK_Creating” longint PRIMARY KEY SERIAL UNIQUE CREATE INDEX “Ind_PK_Creating”,“FK_Creating_2_PK_Opus” longint REFERENCES “Opus” (“PK_Opus”) CREATE INDEX “Ind_FK_Creating_2_PK_Opus”,“FK_Creating_2_PK_Artist” longint REFERENCES “Artist” (“PK_Artist”) CREATE INDEX “Ind_FK_Creating_2_PK_Artist”,);Et voilà les tables annexes : CREATE TABLE “Artist_Annex” (/*Annex table to Artist for managing the primary key during import.*/“PK_Artist_Annex” longint PRIMARY KEY UNIQUE SERIAL CREATE INDEX “Ind_PK_Artist_Annex”,“FK_Artist_Annex_2_PK_Artist” longint REFERENCES “Artist” (“PK_Artist”) CREATE INDEX “Ind_FK_Artist_Annex_2_PK_Artist”,“Imported_PK_Artist” longint UNIQUE CREATE INDEX “Ind_Imported_PK_Artist”,);CREATE TABLE “Opus_Annex” (/*Annex table to Opus for managing the primary key during import.*/“PK_Opus_Annex” longint PRIMARY KEY SERIAL CREATE INDEX “Ind_PK_Opus_Annex”,“FK_Opus_Annex_2_PK_Opus” longint REFERENCES “Opus” (“PK_Opus”) CREATE INDEX “Ind_FK_Opus_Name_2_PK_Opus”,“Imported_PK_Opus” longint UNIQUE CREATE INDEX “Ind_Imported_PK_Opus,);CREATE TABLE “Creating_Annex” (/*Annex table to Creating for managing the primary and foreign keys during import.*/“PK_Creating_Annex” longint PRIMARY KEY SERIAL CREATE INDEX “Ind_PK_Creating_Annex”,“FK_Creating_Annex_2_PK_Creating“ REFERENCES “Creating“ (“PK_Creating“) CREATE INDEX “Ind_FK_Creating_Name_2_PK_Creating”,“Imported_PK_Creating“ longint UNIQUE CREATE INDEX “Ind_Imported_PK_Creating” ,“Imported_FK_Creating_2_PK_Opus” REFERENCES “Opus_Annex” (“Imported_PK_Opus”) CREATE INDEX “Ind_FK_Imported_PK_Opus”,“Imported_FK_Creating_2_PK_Artist” REFERENCES “Artist_Annex” (“Imported_PK_Artist”) CREATE INDEX “Ind_Imported_FK_Creating_2_PK_Artist”,);
J’ai deux premières questions :
Est-il licite de créer les deux dernières relations chacune référençant une colonne qui n’est pas une clé primaire, à savoir Imported_PK_Opus et Imported_PK_Artist ?
Si oui la procédure pour rétablir la relation est simplissime puisqu’il s’agit de récupérer les valeurs contenues dans FK_Opus_Annex_2_PK_Opus et dans FK_Artist_Annex_2_PK_Artist qui sont égales respectivement à PK_Opus et à PK_Artist (à savoir celles qui nous intéressent) et de les insérer respectivement dans FK_Creating_2_PK_Opus et FK_Creating_2_PK_Artist.
Il faut naturellement commencer par importer les données. Les fonctions d’importation que j’ai vues, notamment dans jetbrains, consistent à importer en masse toutes les données d’un fichier CSV ou TSV dans une table de colonne à colonne. Il faut sans doute créer une procédure qui va importer d’abord les tables mères puis les filles en procédant ligne par ligne. C’est à programmer.
Par exemple pour les table Artist et Creating.
Toutes les remarques et les corrections d’erreurs de votre part sont les bienvenues.
- Pour une ligne donnée du fichier texte à importer il faut créer un enregistrement dans la table Artist et un lié dans Artist_Annex.
- Importer uniquement les data de cette ligne dans l’enregistrement de la table Artist.
- Importer dans celui la table Artist_Annex uniquement les clés primaires.
- Une fois toutes les importations effectuées, il faut récupérer la valeur de PK_Artist pour l’insérer dans FK_Creating_2_PK_Artist. Elle se trouve dans FK_Artist_Annex_2_PK_Artist.
- Une fois l’importation terminée et les clés étrangères ventilées où elles vont bien, tous les enregistrements de toutes les tables annexes, devenus inutiles, sont supprimés. Tout cela prendra donc une place négligeable sur le disque.
Merci d'avance de vos lumières.
Nico
-----


Il est donc impossible d’importer les clés primaires dans les colonnes correspondantes.
(en fait, c'est ce qu'on utilisait au taf, et c'est la seule que j'administre les doigts dans le nez)). donc j'ai voulu voir comment ça s'enquillait. plutôt bien en fait...