Şema değişiklikleri ve kesinti olmadan canlı bir veritabanına veri geçişi için en iyi yöntemler?


43

Kesinti olmadan canlı bir veritabanında şema değişiklikleri nasıl yaparsınız?

Örneğin, hepsi belirli kullanıcılarla ilişkilendirilmiş, e-posta adresleri vb. Gibi çeşitli kullanıcı verilerini içeren bir tablo içeren bir PostgreSQL veritabanım olduğunu varsayalım. E-posta adreslerini yeni atanmış bir tabloya taşımak istersem, şemayı değiştirmem ve ardından e-posta verilerini yeni tabloya geçirmem gerekir. Bu, orijinal tablodaki yazıları durdurmadan nasıl yapılabilir? Elbette veriler eski tablodan yenisine aktarılırken, yeni veriler eski tabloya yazılmaya ve özlenmeye devam ederdi, değil mi?

Sanırım bu problem oldukça sık ortaya çıkıyor ama onunla başa çıkmak için herhangi bir standart çözüm bulamıyorum.

Bu makale sorunla ilgileniyor ancak 3. adımı gerçekten anlamadım. Her iki tabloya da yazıp eski verileri ilk tablodan yenisine geçirdiğini söylüyor. Yalnızca eski verileri taşıdığınızdan nasıl emin olabilirsiniz?

( Heroku'da PostgreSQL kullanıyorum .)


2
Facebook , MySQL için bunu yapmak için bir araç geliştirdi .
Nick Chammas

2
K. Scott Allen, burada şema versiyonlarını yönetmek için bir sistem hakkında yazdı . Sürüme duyarlı şema dağıtımı için açık kaynak bir araç olan DbUpdater'ı oluşturdum. Daha fazla burada - http://www.tewari.info/dbupdater
ash

@NickChammas Bunu paylaştığın için teşekkürler. Bunun üzerine bir sürü sorum var. Lütfen daha ayrıntılı bir öğretici, tercihen bir video, bit günlüğü, kümelenmemiş dizinler gibi şeyleri açıklayan ve - 1 gibi soruları cevaplar mısınız? doğrudan masa. 2. Kopyalama aşaması ne zaman bitecek? Bunlar sadece birkaç sorum var ve ben sadece okumaya başladım.
Sandeepan Nath

@SandeepanNath - Üzgünüm, Facebook'un aracına o kadar aşina değilim ve bu yüzden sizi daha fazla kaynağa yönlendiremez. Bununla ilgili bir duyuru okudum ve yorumumu yıllar önce yayınladım, ancak hiç kullanmadım.
Nick Chammas,

Yanıtlar:


27

Neredeyse cevabını neredeyse aldın:

  1. Paralel olarak yeni yapı oluşturun
  2. Her iki yapıya yazmaya başla
  3. Eski verileri yeni yapıya taşı
  4. Sadece yeni yapıyı yaz ve oku
  5. Eski sütunları sil

3. adıma gelince , böyle bir şey kullanın (tek işlemde):

Henüz orada olmayanları ekleyin:

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);

Bu arada nelerin değiştiğini güncelleyin:

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;

Yeni verilere dokunulmayacak, çünkü her iki yerde de aynı.


Bu cevabı önerdiğiniz senaryoyu anlamaya çalışırken birkaç sorum var - 1. Kod değişiklikleri, db değişikliklerinin başlangıcı ile birlikte dağıtılacak mı? 2. Neden her iki yapıya da yazma ihtiyacı olacak? 3. Niçin önce yeni yapı ortaya çıkarılamaz, sonra mevcut veriler taşınır ve sonra yeni yapıya yer verecek kod değişiklikleri dağıtılır? 4. Neyin olmadığını öğrenmek için neden bir ihtiyaç var? Birden çok denemede ekleme teklif ediyor musunuz?
Sandeepan Nath

2
@SandeepanNath, yorumunuzdaki 3. soruyu cevaplamak için: çünkü eğer (a) yeni bir yapı ortaya çıkarırsanız, (b) veriyi ona geçirirseniz, (c) eski, sonra hepsini yeni yapıya veri yazmak için kodunuzu değiştirin adım b ve adım c arasında yapılan veri değişiklikleri sadece eski yapı içinde olacaktır . Sorun şema değişikliklerinin kesinti olmadan nasıl yapılacağıydı . Bu cevabı tekrar dikkatlice okuyunuz.
Joker
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.