web-dev-qa-db-fra.com

Meilleures pratiques pour les modifications de schéma et les migrations de données vers une base de données en direct sans temps d'arrêt?

Comment apporter des modifications de schéma à une base de données active sans interruption?

Par exemple, disons que j'ai une base de données PostgreSQL avec une table comprenant diverses données utilisateur comme des adresses e-mail, etc., toutes associées à des utilisateurs spécifiques. Si je voulais déplacer les adresses e-mail vers une nouvelle table dédiée, je devrais modifier le schéma, puis migrer les données de messagerie vers la nouvelle table. Comment cela pourrait-il être fait sans arrêter les écritures dans la table d'origine? Certes, alors que les données sont écrites de l'ancienne table vers la nouvelle, de nouvelles données continueraient d'être écrites dans l'ancienne table et seraient manquées, non?

Je suppose que ce problème revient assez fréquemment, mais je ne trouve aucune solution standard pour y faire face.

Cet article traite du problème mais je n'ai pas vraiment compris l'étape 3. Il dit d'écrire dans les deux tables, puis de migrer les anciennes données de la première table vers la nouvelle. Comment vous assurez-vous que vous migrez uniquement les anciennes données?

(J'utilise PostgreSQL sur Herok .)

44
Dan Leary

Vous avez déjà presque votre réponse:

  1. Créer la nouvelle structure en parallèle
  2. Commencez à écrire sur les deux structures
  3. Migrer les anciennes données vers la nouvelle structure
  4. N'écrire et lire que la nouvelle structure
  5. Supprimer les anciennes colonnes

Quant à étape, utilisez quelque chose comme ça (en une seule transaction):

Insérez ce qui n'est pas encore là:

INSERT INTO new_tbl (old_id, data)
SELECT old_id, data
FROM   old_tbl
WHERE  NOT EXISTS (SELECT * FROM new_tbl WHERE new_tbl.old_id = old_tbl.old_id);

Mettez à jour ce qui a changé entre-temps:

UPDATE new_tbl
SET    data  = old.data
USING  old_tbl
WHERE  new_tbl.old_id = old_tbl.old_id
AND    new_tbl.data IS DISTINCT FROM old_tbl.data;

Les nouvelles données ne seront pas touchées, car elles sont identiques aux deux endroits.

27
Erwin Brandstetter