Structure de Base de Données : Datasets Normalisés

Vue d’ensemble

La structure de base de données d’IBIS-X a été entièrement refondée pour supporter une approche normalisée de la gestion des datasets. Cette nouvelle architecture remplace l’ancienne table unique datasets par 5 tables relationnelles interconnectées qui offrent une granularité et une flexibilité bien supérieures.

Objectifs de la Refonte

  • Normalisation : Élimination de la redondance et amélioration de l’intégrité des données

  • Granularité : Gestion détaillée des fichiers et colonnes individuels

  • Métadonnées éthiques : Support étendu pour les critères éthiques de l’IA explicable

  • Multi-fichiers : Support natif des datasets composés de plusieurs fichiers

  • Relations : Traçabilité des relations entre fichiers et colonnes

  • Évolutivité : Structure adaptée aux besoins futurs d’IBIS-X

Structure des Tables

La nouvelle structure comprend 5 tables principales organisées hiérarchiquement :

@startuml
!theme plain

entity "datasets" as dataset {
  + id : UUID [PK]
  --
  dataset_name : VARCHAR(255)
  year : INTEGER
  objective : TEXT
  access : VARCHAR(100)
  availability : VARCHAR(100)
  num_citations : INTEGER
  citation_link : TEXT
  sources : TEXT
  storage_uri : VARCHAR(500)
  ...
  (40+ champs métadonnées)
  --
  created_at : TIMESTAMPTZ
  updated_at : TIMESTAMPTZ
}

entity "dataset_files" as file {
  + id : UUID [PK]
  --
  dataset_id : UUID [FK]
  file_name_in_storage : VARCHAR(255)
  logical_role : VARCHAR(255)
  format : VARCHAR(50)
  mime_type : VARCHAR(100)
  size_bytes : BIGINT
  row_count : BIGINT
  description : TEXT
  --
  created_at : TIMESTAMPTZ
  updated_at : TIMESTAMPTZ
}

entity "file_columns" as column {
  + id : UUID [PK]
  --
  dataset_file_id : UUID [FK]
  column_name : VARCHAR(255)
  data_type_original : VARCHAR(100)
  data_type_interpreted : VARCHAR(50)
  description : TEXT
  is_primary_key_component : BOOLEAN
  is_nullable : BOOLEAN
  is_pii : BOOLEAN
  example_values : TEXT[]
  position : INTEGER
  stats : JSONB
  --
  created_at : TIMESTAMPTZ
  updated_at : TIMESTAMPTZ
}

entity "dataset_relationships" as relationship {
  + id : UUID [PK]
  --
  dataset_id : UUID [FK]
  from_file_id : UUID [FK]
  to_file_id : UUID [FK]
  relationship_type : VARCHAR(50)
  description : TEXT
  --
  created_at : TIMESTAMPTZ
  updated_at : TIMESTAMPTZ
}

entity "dataset_relationship_column_links" as link {
  + id : UUID [PK]
  --
  relationship_id : UUID [FK]
  from_column_id : UUID [FK]
  to_column_id : UUID [FK]
  link_order : INTEGER
}

dataset ||--o{ file
file ||--o{ column
dataset ||--o{ relationship
file ||--o{ relationship
relationship ||--o{ link
column ||--o{ link

@enduml

Table datasets (Principale)

La table principale contient toutes les métadonnées d’un dataset, organisées en sections logiques :

Identification & Informations Générales

  • dataset_name : Nom du dataset

  • year : Année de création/publication

  • objective : Description de l’objectif du dataset

  • access : Niveau d’accès (public, privé, etc.)

  • availability : Disponibilité du dataset

  • num_citations : Nombre de citations

  • citation_link : Lien vers les informations de citation

  • sources : Sources et origines du dataset

  • storage_uri : URI de stockage du dataset

Caractéristiques Techniques

  • instances_number : Nombre d’instances/lignes

  • features_description : Description des caractéristiques

  • features_number : Nombre de caractéristiques/colonnes

  • domain : Domaines d’application (array)

  • representativity_description : Description de la représentativité

  • representativity_level : Niveau de représentativité

  • sample_balance_description : Description de l’équilibre des échantillons

  • sample_balance_level : Niveau d’équilibre des échantillons

  • split : Dataset déjà divisé en train/test

  • missing_values_description : Description des valeurs manquantes

  • has_missing_values : Présence de valeurs manquantes

  • global_missing_percentage : Pourcentage global de valeurs manquantes

  • missing_values_handling_method : Méthode de traitement des valeurs manquantes

  • temporal_factors : Présence de facteurs temporels

  • metadata_provided_with_dataset : Métadonnées fournies avec le dataset

  • external_documentation_available : Documentation externe disponible

  • documentation_link : Lien vers la documentation

  • task : Types de tâches ML supportées (array)

Critères Éthiques (Spécifiques à IBIS-X)

  • informed_consent : Consentement éclairé obtenu

  • transparency : Transparence des données

  • user_control : Contrôle utilisateur

  • equity_non_discrimination : Équité et non-discrimination

  • security_measures_in_place : Mesures de sécurité en place

  • data_quality_documented : Qualité des données documentée

  • data_errors_description : Description des erreurs de données

  • anonymization_applied : Anonymisation appliquée

  • record_keeping_policy_exists : Politique de conservation des données

  • purpose_limitation_respected : Limitation d’usage respectée

  • accountability_defined : Responsabilités définies

Table dataset_files

Gère les fichiers individuels associés à un dataset.

-- Exemple : Dataset avec fichiers multiples
INSERT INTO dataset_files (dataset_id, file_name_in_storage, logical_role) VALUES
  ('uuid-dataset', 'train.csv', 'training_data'),
  ('uuid-dataset', 'test.csv', 'test_data'),
  ('uuid-dataset', 'metadata.json', 'metadata');

Champs principaux

  • logical_role : Rôle du fichier (training_data, test_data, metadata, documentation, etc.)

  • format : Format du fichier (csv, json, parquet, etc.)

  • mime_type : Type MIME (text/csv, application/json, etc.)

  • size_bytes : Taille en octets

  • row_count : Nombre de lignes

Table file_columns

Décrit chaque colonne/feature d’un fichier avec ses métadonnées détaillées.

-- Exemple : Colonnes d'un fichier CSV
INSERT INTO file_columns (dataset_file_id, column_name, data_type_interpreted, is_pii, position) VALUES
  ('uuid-file', 'user_id', 'identifier', true, 1),
  ('uuid-file', 'age', 'numerical', false, 2),
  ('uuid-file', 'income', 'numerical', false, 3);

Champs spécialisés

  • data_type_original : Type original dans le fichier

  • data_type_interpreted : Type interprété (numerical, categorical, text, identifier, etc.)

  • is_primary_key_component : Fait partie de la clé primaire

  • is_pii : Contient des informations personnelles (important pour l’éthique)

  • example_values : Exemples de valeurs (array)

  • stats : Statistiques calculées (JSON) - min, max, mean, std, etc.

Table dataset_relationships

Décrit les relations logiques entre fichiers d’un même dataset ou de datasets différents.

-- Exemple : Relation foreign key entre deux fichiers
INSERT INTO dataset_relationships (dataset_id, from_file_id, to_file_id, relationship_type) VALUES
  ('uuid-dataset', 'uuid-users-file', 'uuid-orders-file', 'foreign_key');

Types de relations

  • foreign_key : Clé étrangère classique

  • join : Possibilité de jointure

  • reference : Référence logique

  • aggregation : Relation d’agrégation

  • derived : Données dérivées

Spécifie précisément quelles colonnes sont liées dans une relation.

-- Exemple : Lien user_id -> customer_id
INSERT INTO dataset_relationship_column_links (relationship_id, from_column_id, to_column_id, link_order) VALUES
  ('uuid-relationship', 'uuid-user-id-column', 'uuid-customer-id-column', 1);

Migration et Compatibilité

Migration Alembic

La migration 71ec68fa0302 effectue la transition complète :

# Application de la migration
cd service-selection
alembic upgrade head

La migration : 1. Supprime l’ancienne table datasets 2. Crée les 5 nouvelles tables avec toutes leurs contraintes 3. Ajoute tous les index nécessaires pour les performances

Cette migration est destructive et supprime toutes les données existantes. Assurez-vous d’avoir une sauvegarde si nécessaire.

Rollback

Un rollback vers l’ancienne structure est possible :

# Retour à la version précédente
alembic downgrade d0542934a037

Modèles Pydantic

La refonte inclut des schémas Pydantic complets pour chaque table :

Schémas de base

  • DatasetBase/Create/Update/Read

  • DatasetFileBase/Create/Update/Read

  • FileColumnBase/Create/Update/Read

  • DatasetRelationshipBase/Create/Update/Read

  • DatasetRelationshipColumnLinkBase/Create/Update/Read

Schémas composés

  • DatasetWithFiles : Dataset avec ses fichiers

  • DatasetFileWithColumns : Fichier avec ses colonnes

  • DatasetComplete : Dataset complet avec fichiers et colonnes

Schémas de filtrage

  • DatasetFilterCriteria : Critères de recherche avancée

  • DatasetScoreRequest : Requête de scoring

  • DatasetScoredRead : Dataset avec score calculé

Exemples d’Usage

Création d’un dataset complet

# 1. Créer le dataset principal
dataset = Dataset(
    dataset_name="Customer Analytics Dataset",
    year=2024,
    objective="Analyse comportementale des clients",
    domain=["marketing", "analytics"],
    task=["classification", "clustering"],
    anonymization_applied=True,
    informed_consent=True
)

# 2. Ajouter des fichiers
train_file = DatasetFile(
    dataset_id=dataset.id,
    file_name_in_storage="customers_train.csv",
    logical_role="training_data",
    format="csv",
    row_count=10000
)

test_file = DatasetFile(
    dataset_id=dataset.id,
    file_name_in_storage="customers_test.csv",
    logical_role="test_data",
    format="csv",
    row_count=2500
)

# 3. Décrire les colonnes
columns = [
    FileColumn(
        dataset_file_id=train_file.id,
        column_name="customer_id",
        data_type_interpreted="identifier",
        is_primary_key_component=True,
        is_pii=True,
        position=1
    ),
    FileColumn(
        dataset_file_id=train_file.id,
        column_name="age_group",
        data_type_interpreted="categorical",
        example_values=["18-25", "26-35", "36-50", "50+"],
        position=2
    )
]

Requête de filtrage avancée

# Recherche avec critères éthiques
filters = DatasetFilterCriteria(
    domain=["healthcare", "finance"],
    anonymization_applied=True,
    informed_consent=True,
    instances_number_min=1000,
    year_min=2020
)

# Scoring basé sur critères éthiques
weights = [
    CriterionWeight(criterion_name="anonymization_applied", weight=2.0),
    CriterionWeight(criterion_name="informed_consent", weight=2.0),
    CriterionWeight(criterion_name="transparency", weight=1.5),
    CriterionWeight(criterion_name="data_quality_documented", weight=1.0)
]

score_request = DatasetScoreRequest(filters=filters, weights=weights)

Performance et Index

Index automatiques

  • Clés primaires UUID sur toutes les tables

  • Index sur les clés étrangères

  • Index sur les champs de recherche fréquents (dataset_name, column_name)

Requêtes optimisées

  • Utilisation des relations ORM SQLAlchemy pour les jointures

  • Pagination efficace avec LIMIT/OFFSET

  • Filtrage au niveau BDD pour réduire le transfert de données

Considérations de Sécurité

Données personnelles (PII)

  • Champ is_pii pour marquer les colonnes sensibles

  • Critères éthiques intégrés dans la structure

  • Support pour les politiques de conservation

Audit et traçabilité

  • Timestamps automatiques sur toutes les tables

  • Historique des modifications via updated_at

  • Relations préservées pour la traçabilité

Évolution Future

Cette structure normalisée prépare le terrain pour :

  • Versioning des datasets : Ajout de tables de versions

  • Provenance des données : Traçabilité complète de l’origine

  • Métadonnées ML : Informations sur les modèles entraînés

  • Audit avancé : Logs détaillés des accès et modifications

  • Fédération : Support de datasets distribués

Cette architecture respecte les principes de normalisation de base de données tout en étant optimisée pour les besoins spécifiques d’IBIS-X en matière d’explicabilité et d’éthique de l’IA.