İlk geçişten önce PostgreSQL şema doğrulaması
PostgreSQL şema doğrulaması, ilk geçiş veriye dokunmadan önce yanlış eşlemeleri, zayıf kısıtları, eksik dizinleri ve güvenli olmayan değişiklikleri yakalar.

Bir yapay zekâ oluşturucu, geçerli PostgreSQL üretebilir ve yine de yanlış veritabanını çıkarabilir. Sözdizimi kolay kısımdır. Tehlikeli hatalar makul görünür: isteğe bağlı bir ilişki zorunlu olur, durum dizgesi eksik bir CHECK kısıtı alır, silme işleminde yaşaması gereken kayıtlar zincirleme silinir ya da geçiş bir tabloyu yeniden oluşturup bir sütunu sessizce kaybeder.
Bu yüzden PostgreSQL şema doğrulaması anlamı, geçiş davranışını ve kurtarmayı ayrı konular olarak test etmelidir. Çıkarılmış bir şemayı ancak bilinen bir veri kümesinden, açık değişmezlerden, temsilî sorgulardan, yıkıcı değişiklik incelemesinden ve geri yükleme provasından geçtikten sonra onaylarım. Bunlardan biri eksikse geçiş hâlâ bir öneridir.
İlk geçiş, üretim veritabanı boş olsa bile bu incelemeyi hak eder. Erken şema hataları hızla kalıcılaşır; uygulama kodu, başlangıç verileri, raporlar ve sonraki geçişler bunlara bağımlı olmaya başlar. İlk çalıştırmadan önce yapılacak on beş dakikalık inceleme, altı ay sonra iki farklı kavramın neden tek bir null olabilir metin sütununu paylaştığını açıklamaktan genellikle daha ucuzdur.
Çıkarılmış şema güvenilmeyen bir belirtimdir
Çıkarılmış şemeyi çalıştırılabilir gerçek olarak değil, taslak bir belirtim olarak ele alın. Oluşturucu istemleri, örnek ekranları, içe aktarılan kayıtları veya üretilmiş uygulama kodunu gördü. Veritabanının zamanla barındıracağı her iş istisnasına, saklama kuralına, toplu içe aktarıma, destek düzeltmesine ve başarısız ödemeye tanık olmadı.
Ekiplerin sıkça birbirine karıştırdığı üç soruyu ayırarak başlayın. Şema doğruluğu, tablo ve kısıtların alanı modelleyip modellemediğini sorar. Geçiş güvenliği, önerilen işlemlerin mevcut veriyi koruyup korumadığını ve çalışırken veritabanını kullanılabilir tutup tutmadığını sorar. Kurtarmaya hazırlık ise kısmi veya anlamsal açıdan yanlış bir değişiklikten sonra bilinen bir duruma dönüp dönemeyeceğinizi sorar. Birini geçmek, diğer ikisi hakkında çok az şey söyler.
Bir CREATE TABLE ifadesi hedeflenen son yapıyı tanımlayabilir, ancak oraya güvenli olmayan işlemlerle varabilir. Oluşturucunun customer_name text alanını customer_id bigint alanına çevirdiğini düşünün. Son yabancı anahtar mantıklı olabilir; fakat geçmiş adları müşterilerle eşleştirmeden önce ad sütununu bırakan bir geçiş, bu eşleştirme için gereken tek kanıtı yok eder. Şema incelemesi varış noktasını onaylar, geçiş incelemesi yolculuğu inceler.
Önerilen modeli alan diliyle sesli okuyun. invoices.customer_id alanı customers.id alanına başvuruyor demek yerine her faturanın tam olarak bir yasal müşteriye ait olduğunu söyleyin. İlk cümle faydalı itirazlara davet eder: müşteri seçilmeden önce taslaklar bulunabilir, içe aktarılan faturalar arşivlenmiş müşterilere ait olabilir ve yasal kayıtların düzenlenme anındaki müşteri adını sabitlemesi gerekebilir. SQL sözlüğü bu anlaşmazlıkları gizleyebilir.
Çıkarılmış her tablonun yanında bir varsayım notu isterim. Bu not, bir satırın ne anlama geldiğini, nasıl tanımlandığını, sahibinin kim olduğunu, görünen üst kaydı olmadan var olup olamayacağını ve silmenin ne anlama geldiğini belirtmelidir. Ekip bu noktaları yanıtlayamıyorsa oluşturucu, ekibin tasarlamadığı bir veritabanı tahmin etmiştir.
Bilinen kayıtlar yanlış tablo eşlemelerini ortaya çıkarır
Bilinen veri kümesi anlamsal kapsam için seçilmiş kayıtlar içermelidir; büyük rastgele bir örnek çoğu zaman aynı kolay durumu tekrarlar. Özenle seçilmiş on kayıt, birbirinin neredeyse aynısı olan on bin sorunsuz satırdan daha çok şey açığa çıkarabilir.
DDL'yi çalıştırmadan önce bir eşleme matrisi oluşturun. Matrisin her satırı, kaynak kavramı önerilen hedef boyunca izlemeli ve beklenen sayıyı veya değeri kaydetmelidir. Bir sipariş uygulaması için bu çalışma şöyle görünebilir:
| Bilinen gerçek | Önerilen hedef | Beklenen sonuç |
|---|---|---|
| A siparişinde iki satır kalemi var | orders ve order_items | Bir sipariş satırı ve iki alt satır |
| B siparişine hesap atanmadı | orders.account_id | NULL hesaplı bir satır |
| İki kişi aynı e-postayı paylaşıyor | contacts.email | Benzersizlik açıkça belirtilmiş kural değilse iki satır da kalır |
| Ürün kodunda baştaki sıfırlar var | products.code | Metin değeri 00417 değişmeden kalır |
| İptal edilen sipariş ücretleri korur | orders ve charges | İptalden sonra ücret satırları kalır |
Bu, kısıt ayrıntıları incelemenin dikkatini dağıtmadan önce tablo eşleme hatalarını yakalar. Yapay zekâ oluşturucular yinelenen nesneleri çoğu zaman ayrı tablolara normalleştirir; bu genellikle mantıklıdır, ancak tekrar kimliği kanıtlamaz. Metni aynı olan iki teslimat adresi, düzenlenebilir tek bir adres satırına başvuru değil, geçmişe ait anlık görüntüler olabilir. Bunları birleştirmek, daha sonraki bir adres düzenlemesinin geçmişi yeniden yazması demektir.
Tersi hata da görülür. Bir oluşturucu, ekran bunları birlikte gösterdiği için müşteri alanlarını her siparişe kopyalayabilir. Bazı değerler müşteriye aittir, başka değerler ise sipariş anlık görüntüsü olarak kalmalıdır. Doğru tasarım hem customer_id hem de billing_name gibi düzenlenmiş belge alanlarını içerebilir. Buna yinelenme deyip bir tarafı silmek, ya güncel kimliği ya da geçmiş gerçeği kaybettirir.
Bilinen veri kümesini uygulamanın kullanacağı içe aktarma veya başlangıç verisi yolunun aynısıyla geçici bir veritabanına yükleyin. Ardından yalnızca satır sayılarına değil, gerçeklere yönelik doğrulamalar yazın:
SELECT
(SELECT count(*) FROM orders WHERE external_id = 'ORDER-A') AS order_a,
(SELECT count(*) FROM order_items i
JOIN orders o ON o.id = i.order_id
WHERE o.external_id = 'ORDER-A') AS order_a_items,
(SELECT account_id IS NULL FROM orders
WHERE external_id = 'ORDER-B') AS order_b_unassigned;
Başarılı şekil açık olmalıdır:
order_a | order_a_items | order_b_unassigned
---------+---------------+---------------------
1 | 2 | t
Üretilen uygulama hâlâ görüntüleniyor diye açıklanmamış bir farkı kabul etmeyin. Bir arayüz yinelenen üst kayıtları, kaybolan alt kayıtları, kesilmiş kodları ve uydurulmuş varsayılanları gizleyebilir. Üretime alma konuşulmadan önce her kasıtlı test kaydını mutabık hâle getirin.
Kısıtlar alanın gerçeklerini kodlamalıdır
Bir veritabanı kısıtı, satırı hangi ekranın, API'nin, içe aktarmanın veya düzeltme betiğinin yazdığından bağımsız olarak her zaman geçersiz olan bir durumu reddetmelidir. Kuralın istisnaları varsa ya da değişken dış gerçeklere bağlıysa onu basit bir kısıta zorlamak, çoğu zaman ya işi engeller ya da dürüst olmayan veri üretir.
Birincil anahtarlar satırları tanımlar; kendiliğinden anlamlı bir iş kimliği sağlamaz. İç bigint kimliği, kiracı kapsamındaki benzersiz sipariş numarasıyla birlikte bulunabilir. İş kuralı sipariş numaralarının kiracı başına benzersiz olduğunu söylüyorsa UNIQUE (tenant_id, order_number) bunu ifade eder. Genel bir benzersiz kısıt geçerli kayıtları reddeder, hiç kısıt olmaması ise yeniden denemelerde belirsizliğe izin verir.
CHECK kısıtları quantity > 0 veya finished_at >= started_at gibi sabit satır gerçekleri için uygundur. PostgreSQL kılavuzu, veritabanının bir CHECK ifadesinin kısıtın ömrü boyunca değişmez olduğunu varsaydığını açıklar. Bu nedenle davranışı sonradan değişen bir işlevi çağıran CHECK, eski satırların görünen kuralı ihlal etmesine yol açabilir. Sabit gerçek için sabit bir ifade kullanın. Yöneticilerin kontrol ettiği güncel izinli küme gibi değişen politikayı başvurulan bir tabloda veya uygulama akışında tutun.
Üretilen durum kısıtlarına şüpheyle yaklaşın. Oluşturucu mevcut örnekleri inceleyip şunu üretebilir:
status text NOT NULL
CHECK (status IN ('draft', 'active', 'closed'))
Bu ancak bunlar eksiksiz ve kalıcı durumlar ise doğrudur. Başarısız, iptal edilmiş, askıya alınmış, içe aktarılmış ve bilinmeyen eski kayıtları sorun. Durum makinesi hâlâ değişiyorsa arama tablosu eklemeleri açık hâle getirebilir, ancak geçiş doğrulamasının yerini almaz. Satırın closed içerebilmesi, doğrudan draft durumundan closed durumuna geçebileceği hakkında hiçbir şey söylemez.
Benzersizliği bilinçli kullanın. PostgreSQL benzersiz kısıtı benzersiz bir B-tree diziniyle uygular, ancak kısmi benzersiz dizin farklı bir kuralı ifade eder. Mantıksal silmede benzersizlik çoğunlukla yalnızca etkin satırlar için gerekir:
CREATE UNIQUE INDEX users_tenant_email_live_uq
ON users (tenant_id, lower(email))
WHERE deleted_at IS NULL;
Bu, UNIQUE (tenant_id, email, deleted_at) ile aynı şey değildir. PostgreSQL NULL değerleri kendi benzersizlik kurallarına göre ele alır ve silme zaman damgasını eklemek zorlanan kimliği değiştirir. Davranışı sütun listesinden tahmin etmek yerine tam yinelenen durumları test kayıtlarıyla inceleyin.
Null olabilirlik bir iş kararıdır
Bir sütunu yalnızca alan her geçerli satır için değer gerektiriyorsa ve her yazma yolu o değeri sağlayabiliyorsa NOT NULL yapın. Ekran tasarımı zayıf bir kanıttır. Mevcut formdaki zorunlu alan, içe aktarmalar, taslaklar, sistemin ürettiği satırlar veya geçmiş kayıtlar hakkında hiçbir şey söylemez.
Dört durumu ayrı inceleyin: kaynak alanı göndermedi, kaynak açıkça null gönderdi, kaynak boş değer gönderdi ve kaynak anlamlı değer sağladı. JSON API'leri, formlar, CSV içe aktarmaları ve PostgreSQL bu durumları farklı ele alabilir. Uygulama eklemeden önce dördünü de tek duruma indiriyorsa, şema incelemesi veritabanının bunu çözdüğünü varsaymak yerine bu kararı görünür kılmalıdır.
Varsayılanlar da aynı özeni hak eder. Varsayılan, INSERT bir sütunu atladığında değer sağlar; açık NULL değerini düzeltmez ve değerin doğru olduğunu kanıtlamaz. Bilinmeyen ülke olasılığı varsa country_code DEFAULT 'US' tehlikelidir. Satır artık raporların ve uyumluluk mantığının güvenebileceği, kendinden emin bir yalan içerir.
Yaygın bir üretilmiş geçiş, tek ifadeyle zorunlu bir sütun ekler:
ALTER TABLE customers
ADD COLUMN account_type text NOT NULL DEFAULT 'standard';
İfade çalışabilir, fakat her geçmiş müşteri kanıt olmadan standart olur. Daha güvenli sıra, null olabilir sütunu eklemek, değerleri bilinen veriden türetmek, çözülemeyen satırları ölçmek, uygulama yazmalarında yeni eksiklikleri engellemek ve ancak alan destekliyorsa NOT NULL eklemektir. Bilinmeyen değer geçerliyse NULL'ı koruyun ve sorguların, arayüzlerin bunu nasıl göstereceğini tanımlayın.
PostgreSQL bazı kısıtlar için yararlı bir ayrım sağlar. CHECK veya yabancı anahtar NOT VALID olarak eklenebilir. Bu, oluşturma sırasında tüm mevcut satırları doğrulamayı önler; daha sonra VALIDATE CONSTRAINT ile denetlenir. Kılavuz bunu ilk tablo taramasını ertelemenin bir yolu olarak açıklar. Eski ihlalleri yok sayma izni değildir: yeni yazmalar zorlanır ve onaydan önce doğrulama adımının yine geçmesi gerekir.
Null olabilirliği sıkılaştırmadan önce gerçek kategorileri gösteren bir dağılım sorgusu çalıştırın:
SELECT
count(*) AS total,
count(*) FILTER (WHERE account_type IS NULL) AS nulls,
count(*) FILTER (WHERE account_type = '') AS empty_strings,
count(*) FILTER (WHERE account_type NOT IN
('standard', 'partner', 'internal')) AS unexpected
FROM customers;
Yapay zekânın ürettiği varsayılan, geçişten sonra bu sorguyu temiz gösterebilir. Bunu veri doldurmadan önce de çalıştırın ve sonucu saklayın. Aksi hâlde türetilmiş değerleri uydurulmuş olanlardan ayırmak için gereken kanıtı kaybedersiniz.
Dizinler gözlenen erişim kalıplarına yanıt vermelidir
Bir dizini, bilinen bir sorguyu desteklediğinde, açıkça belirtilmiş benzersizlik kuralını zorladığında veya operasyonel gereksinimi sağladığında onaylayın. Kimlik gibi görünen her sütunu dizinlemek depolamayı ve yazma işini boşa harcar. Öte yandan önemli bir bileşik dizini kaçırmak, sıradan liste sayfasını giderek büyüyen bir taramaya dönüştürebilir.
Üretilen uygulamanın gerçekten gönderdiği sorgularla başlayın. Filtre sütunlarını, kiracı sınırını, birleştirme sütunlarını, sıralamayı ve beklenen sonuç boyutunu kaydedin. Son siparişler sayfasında tablo diyagramından çok bu sorgu şekli önemlidir:
SELECT id, order_number, status, created_at
FROM orders
WHERE tenant_id = $1
AND status = $2
ORDER BY created_at DESC
LIMIT 50;
Yalnızca tenant_id üzerindeki bir dizin yine de çok sayıda kiracı satırını inceleyip sıralayabilir. (tenant_id, status, created_at DESC) üzerindeki dizin bu erişim kalıbına daha yakından uyar. Sütun sırası popülerlik yarışması değildir; gerçek sorgudaki eşitlik koşullarını, aralık koşullarını, sıralamayı ve seçiciliği izler.
EXPLAIN (ANALYZE, BUFFERS) komutunu temsilî veriyle çalıştırın, fakat küçük tek bir test kaydını performans kanıtı saymayın. PostgreSQL küçük tabloda sıralı taramayı haklı olarak tercih edebilir. Doğrulama, hedeflenen dizinin var olduğunu ve üretim boyutunda bir provanın planlayıcıya gerçekçi bir seçenek sunduğunu onaylamalıdır. Onay almak için dizin taraması üretmek amacıyla sıralı taramaları asla devre dışı bırakmayın.
Yabancı anahtarlar da sık rastlanan bir sürpriz yaratır: PostgreSQL başvurulan birincil veya benzersiz sütunları dizinler, fakat başvuran alt sütunlarda otomatik dizin oluşturmaz. Bu yüzden üst kaydı silmek veya güncellemek, başvuruları denetlemek için alt tabloyu tarayabilir. Alttan üste birleştirmeler de bu alt dizine ihtiyaç duyabilir. Her ilişkiyi beklenen okumalar ve üst kayıt değişiklikleri temelinde inceleyin.
İlk öneride yinelenen ve kullanılmayan dizinleri reddedin. Uygun bir (tenant_id, status, created_at) dizini zaten varsa (tenant_id, status) gereksiz olabilir, ancak iş yükünün ayrıntıları bu yargıyı değiştirebilir. Adları değil tanımları karşılaştırın. Yapay zekâ oluşturucular çoğu zaman özellik başına bir dizin yaratır ve birkaç özelliğin aynı öncü sütunları istediğini fark etmez.
Mevcut, yoğun veritabanlarında CREATE INDEX CONCURRENTLY komutunun işlem bloğu içinde çalışamayacağını, daha fazla iş gerektirdiğini ve başarısızlık sonrası geçersiz dizin bırakabileceğini unutmayın. PostgreSQL kılavuzu bu operasyonel farkları açıklar. Her geçişi işlem içinde saran bir geçiş çerçevesinin umutlu bir anahtar sözcük değişimi yerine açık bir istisna ve temizleme prosedürüne ihtiyacı vardır.
Yabancı anahtarlar sahiplik ve silme kuralları gerektirir
Yabancı anahtar ancak ekip ilişkinin sahipliği, başvuruyu, isteğe bağlı bağlamı veya geçmişe ait atfı ifade edip etmediğine karar verdikten sonra doğrudur. Benzer görünen sütunlar zıt silme davranışları gerektirebilir.
projects.owner_user_id, invoices.customer_id ve audit_events.actor_user_id alanlarını düşünün. Bir projenin sahipliği devredilebilir. Fatura, müşteri hesabı kapandıktan sonra da yaşamak zorunda olabilir. Denetim olayı, kimlik verileri kaldırıldıktan sonra bile aktörün eski tanımlayıcısını koruyabilir. Üçü de users tablosuna başvuruyor diye hepsine ON DELETE CASCADE uygulamak, yıkıcı bir kurgu kodlar.
CASCADE'i, alt kaydın üst kayıt olmadan anlamı yoksa ve üst kaydı silmek gerçekten tüm bütünün silinmesi demekse kullanın. Sipariş satır kalemleri buna sıkça uyar. Ödeme kayıtları, düzenlenmiş belgeler, içe aktarmalar, günlükler ve moderasyon kanıtları çoğu zaman uymaz. Bunlar için reddetme, arşivleme, kontrollü anonimleştirme veya saklanan anlık görüntü alanlarıyla eşleştirilmiş null olabilir başvuru daha uygun olabilir.
SET NULL da anlamsal inceleme gerektirir. Alt satırı korur, ancak doğrudan ilişkiyi siler. Personelin daha sonra bir raporu hangi hesabın oluşturduğunu açıklaması gerekiyorsa null başvuru yetersiz kalabilir. Kimliği belli etmeyen geçmiş belirteci veya anlık görüntü, tüm kişisel veriyi tutmadan hesap verebilirliği koruyabilir; ancak tam saklama tercihi yapay zekâ tahminine değil ürün politikasına aittir.
Kardinaliteyi iki yönde de denetleyin. Oluşturucu, benzersiz kısıt olmadan yabancı anahtar koyup bire bir ilişkiyi modelleyebilir ve sessizce birçok alt satıra izin verebilir. Geçmiş birden fazla sürüm gerektirirken de benzersizliği zorlayabilir. Sıfır, bir ve birkaç alt kaydı olan üst kayıtlar için test durumları yazın, ardından hangi eklemelerin geçmesi gerektiğini belirtin.
Ertelenebilir kısıtların belirli bir nedeni olmalıdır. İşlem geçici olarak başvuru sırasını ihlal etmek veya birbirine bağımlı satırları güncellemek zorundaysa yararlı olabilirler. Ancak her yabancı anahtarı varsayılan olarak ertelemek hataları işlem sonuna taşır ve başarısızlıkların yerini bulmayı zorlaştırır. Gerçek bir işlem dizisi erteleme gerektirmedikçe anında zorlamayı koruyun.
Geçişi prova veritabanına uyguladıktan sonra kataloğu inceleyin:
SELECT
conname,
contype,
convalidated,
pg_get_constraintdef(oid) AS definition
FROM pg_constraint
WHERE conrelid = 'public.orders'::regclass
ORDER BY conname;
Temsilî çıktı şu şekildedir:
conname | contype | convalidated | definition
----------------------+---------+--------------+---------------------------------------
orders_pkey | p | t | PRIMARY KEY (id)
orders_customer_fk | f | t | FOREIGN KEY (customer_id) REFERENCES customers(id)
orders_total_check | c | t | CHECK ((total_cents >= 0))
Dönen tanımları onaylanmış sahiplik kurallarıyla karşılaştırın. Geçişin başarılı olması tek başına eksik bir eylemi, beklenmeyen ertelemeyi veya doğrulanmamış kısıtı göstermez.
Yıkıcı değişiklikler makul SQL'in içinde gizlenir
Geçişi veri dönüşümü olarak inceleyin; düzenli görünen DDL, açık bir DROP TABLE kullanmadan anlamı yok edebilir. Önce doğrudan yok etmeyi arayın, sonra dönüşümleri, veri doldurmaları, yeniden yazımları, yeniden adlandırmaları ve kısıt değişimlerini inceleyin.
Yeniden adlandırma ile bırakma, son şema aynı görünse bile operasyonel olarak farklıdır. surname, family_name oluyorsa yeniden adlandırma veriyi ve bağımlılıkları daha doğru korur. Eski sütunu bırakıp yenisini eklemek aynı diyagramı verir, ancak bütün değerleri boşaltır. Üretilen geçişler çoğu zaman sürekliliği anlamadan son durumu çıkarır.
Tür değişiklikleri örnek dönüşümler ve ret durumları gerektirir. Metin tanımlayıcılarını tam sayıya çevirmek baştaki sıfırları kaldırabilir veya karışık tanımlayıcıları reddedebilir. Sayısal hassasiyeti azaltmak değerleri yuvarlayabilir. Zaman damgalarını dönüştürmek açıkça belirtilmiş saat dilimi varsayımı ister. Sütunu değiştirmeden önce gerçek USING ifadesini minimum, maksimum, null, hatalı biçimli ve geçmişten gelen sıra dışı değerlerle test edin.
Şu işlemleri yazılı gerekçe gerektirir sayın: tablo veya sütun bırakmak, kayıplı dönüşümle tür değiştirmek, dolu bir sütunu değiştirmek, CASCADE eklemek, üretilmiş veri doldurmadan sonra NOT NULL koymak ve benzersizliği farklı sütunlarla yeniden kurmak. Üretilen işlevlere veya geçiş geri çağrılarına gömülmüş ham SQL'i de inceleyin. Metin araması başlangıç filtresidir, incelemenin tamamı değildir.
Bir başarısızlık kalıbı sürekli görülür. Bilinen veride isteğe bağlı şirketleri olan kişiler vardır, ancak örnek ekran yalnızca iş bağlantılarını gösterir. Oluşturucu contacts.company_id alanını NOT NULL yapar ve eşleşmeyen satırlar için Unknown adlı üretilmiş bir şirket ekler. Geçiş geçer, sayılar uzlaşır ve her yabancı anahtar doğrulanır. Veri yine de yanlıştır: bireysel bağlantılar artık bir şirkete ait görünür, raporlar ilgisiz kişileri birlikte gruplar ve yer tutucuyu silmek gerçek bağlantılara zincirleme silme uygulayabilir.
Çözüm başka bir varsayılan değildir. Kaynak duruma geri dönün, ilişkiyi null olabilir yapın, yalnızca kanıtla desteklenen eşleşmeleri taşıyın ve eşleşmeyen kümenin bilinen bireysel bağlantılara eşit olduğunu doğrulayan bir kontrol ekleyin. Anlamsal test kayıtlarının yalnızca beklenen satır sayılarını değil, beklenen ilişkileri de kaydetmesi bu yüzdendir.
Şema fark araçları yardımcı olur, ancak yalnızca farka bakarak onay vermeye karşıyım. Bu öneri yaygındır; çünkü fark kısa ve incelemesi kolaydır. Tek geçit olarak yanlıştır, çünkü yapısal değişikliği gösterir ama veri doldurulmuş değerlerin kökenini, işlem sınırlarını, kilit davranışını veya geçiş sonrası gerçeği göstermez.
Prova, sonuçları ve başarısızlık davranışını kanıtlamalıdır
Tam geçişi bilinen veri kümesinin geçici bir geri yüklemesi üzerinde çalıştırın, ardından hem hedeflenen sonucu hem de kesintiye uğramış veya reddedilmiş yolu test edin. Yeni ve boş veritabanı sıralama hatalarını yakalamak için yararlıdır, ancak kayıplı dönüşümü, geçersiz geçmiş satırları veya yavaş doğrulamayı ortaya çıkaramaz.
Bu prova sırasını sürüm artefaktı olarak kullanın:
- Değişiklik öncesi veri kümesini yalıtılmış veritabanına geri yükleyin; satır sayılarını ve anlamsal doğrulamaları kaydedin.
- Mevcut şemayı alın, tam geçiş artefaktını uygulayın; süre ve işlem sınırlarıyla birlikte tüm çıktıyı saklayın.
- Katalog kontrollerini, eşleme doğrulamalarını, kısıt ret testlerini ve temsilî uygulama sorgularını çalıştırın.
- Eşleşmeyen ve null kategorileri dâhil önemli değerleri kaydedilmiş beklentilerle karşılaştırın.
- Belgelenmiş kurtarma yöntemini uygulayın, ardından kurtarılan veritabanında geçiş öncesi doğrulamaları yeniden çalıştırın.
Önce ve sonra yalnızca şema dökümü alın:
pg_dump --schema-only --no-owner --no-privileges \
--dbname "$DATABASE_URL" > schema.sql
Tabloları, dizileri, dizinleri, kısıtları, işlevleri, tetikleyicileri, eklentileri ve uygulamayla ilgili ayrıcalıkları inceleyin. ORM model farkı, özellikle tetikleyiciler, ifade dizinleri, kısmi dizinler ve elle kurulmuş işlevler olmak üzere uygulamanın modellemediği veritabanı nesnelerini atlayabilir.
Kısıtların kötü durumları reddettiğini kanıtlayan olumsuz testler ekleyin. Test işlemi geçersiz ekleme deneyip sonuç ne olursa olsun geri alabilir:
BEGIN;
INSERT INTO order_items (order_id, quantity, unit_price_cents)
VALUES (1001, 0, 2500);
ROLLBACK;
Beklenen çıktı ihlal edilen kısıtı adlandırmalıdır, örneğin:
ERROR: new row for relation "order_items" violates check constraint "order_items_quantity_check"
DETAIL: Failing row contains (..., 0, 2500, ...).
Ayrıntılar değişebileceği için tüm hata metnini her ortamda karşılaştırmayın. Otomatik testlerde SQLSTATE'i veya kısıt kimliğini doğrulayın, incelemeci için okunabilir çıktıyı da saklayın.
Kilitleri ve süreyi hedeflenen dağıtıma benzeyecek kadar büyük veri kümesinde ölçün. Elli satırda anında biten işlem milyonları doğrularken yazmaları engelleyebilir. İlk boş üretim veritabanında acil risk daha düşüktür, ancak prova yine içe aktarılan başlangıç verisini test eder ve sonraki değişiklikler için temel oluşturur.
Kurtarma ters geçişten daha fazlasını gerektirir
Kurtarma, veriyi ve uygulama uyumluluğunu hizmetin tolere edebileceği sürede geri getirebiliyorsa inandırıcıdır. Bırakılmış sütunları yeniden oluşturan ters geçiş, eski değerlerini geri getirmez.
Çalıştırmadan önce kurtarma birimini seçin. Boş ilk veritabanında, kullanıcı yazmaları başlamadıysa veritabanını bırakıp yeniden oluşturmak kabul edilebilir olabilir. Gerçek yazmalar başladığında kurtarma veritabanı anlık görüntüsü, mantıksal yedek, eski sütunları koruma veya ileriye dönük düzeltme gerektirebilir. Doğru yöntem, geçiş sırasında ve sonrasında ne kadar yeni verinin gelebileceğine bağlıdır.
Yedekleme komutlarını ve kimlik bilgilerini onlara güvenmeden önce test edin. Var olan ancak dağıtım operatörü tarafından geri yüklenemeyen yedek kurtarma planı değildir. Ayrı veritabanına geri yükleyin, sahipliği ve eklentileri doğrulayın, sonra geçişten önce kullanılan aynı bilinen doğrulamaları çalıştırın.
Anlık görüntüler ve işlem geri alma farklı başarısızlıkları çözer. Her işlem o işlemde yer alıyorsa geçiş taahhütten önce başarısız olduğunda işlem ifadeleri geri alabilir. Anlık görüntü bütün veritabanını önceki duruma döndürebilir, ancak bundan sonra yapılmış geçerli yazmaları atabilir. Hiçbiri bu yazmaları kendiliğinden uzlaştırmaz.
Belirsizlik sürerken eklemeli değişiklikleri tercih edin. Yeni sütunu veya tabloyu ekleyin, veriyi ölçülebilir kurallarla kopyalayın, gerekirse kontrollü süre boyunca iki kod yolunu da çalıştırın ve eski yapıyı yalnızca doğrulamadan sonra kaldırın. Genişletme ve daraltma yaklaşımı ek iş gerektirir, fakat kanıtı korur. Yeniden adlandırılmış eski sütunu bir sürüm boyunca tutmak, onu günlüklerden yeniden kurmaktan çoğu zaman daha ucuzdur.
Kurtarma tetikleyicilerini önceden yazın. Örnekler arasında başarısız anlamsal doğrulama, beklenmeyen eşleşmeyen kayıtlar, geçersiz kısıt, geçişin onaylanmış kilit süresini aşması veya sürüm uyumsuzluğunun yol açtığı uygulama hataları vardır. Kullanıcılar beklerken operatör kararı icat etmemelidir.
Eski veritabanını geri yüklemenin eski uygulamayı da geri yüklemeyi gerektirdiği noktayı kaydedin. Yeni uygulama yeni sütuna bağımlı olabilir; eski uygulama ise yeni enum değerini reddedebilir veya eski şekli yazabilir. Veritabanı ve uygulama kurtarması uyumlu sürümler kullanmalıdır.
Onay güven değil, kanıt gerektirir
İlk geçişi ancak başka biri saklanan artefaktlardan neden güvenli olduğunu yeniden üretebiliyorsa onaylayın. Temiz bir kod incelemesinin veya özenle üretilmiş bir arayüzün verdiği güven, ilk açıklanamayan veri farkına dayanmaz.
Onay kaydı; çıkarılmış varsayımları, tablo eşleme matrisini, bilinen veri kümesinin kimliğini, şema farkını, tam geçişi, doğrulama sorgularını ve sonuçlarını, reddedilen girdi testlerini, dizin gerekçelerini, yıkıcı işlem gerekçelerini ve test edilmiş kurtarma prosedürünü içermelidir. İncelemecinin adını yazın; çözülmemiş kararları sohbet geçmişine gömmek yerine engel olarak koruyun.
Bir uygulama Koder.ai içinde üretiliyorsa geçişe izin vermeden önce şema kararlarını planlama modunda yazın, inceleme için kaynak kodu dışa aktarın ve anlık görüntüleriyle geri almayı, bilinen veri kümesine karşı hâlâ prova gerektiren kurtarma araçları olarak görün.
Testler geçmeden kodu yeniden üreterek oluşturucunun kendi çıkarımını onaylamasına izin vermeyin. Bu döngü modeli düzeltmek yerine uygulamayı hatalı şemaya uydurabilir. Özellikle kimlik, silme, saklama ve bilinmeyen değerler konusunda veritabanının alanla eşleşip eşleşmediğine insan karar vermelidir.
Son onay sorgusu sıkıcı olmalıdır. Her bilinen gerçek tek bir beklenen sonuca eşlenir, her kısıt hedeflenen karşı örneği reddeder, her yıkıcı işlemin gerekçesi vardır ve geri yükleme geçiş öncesi doğrulamaları yeniden üretir. Bir uyuşmazlığı mazur göstermek için kanıtın ikna edici açıklamaya ihtiyacı varsa geçişi durdurun. PostgreSQL şemayı, oluşturucunun yanlış tahmin ettiği kısımlar da dâhil olmak üzere, tam olarak zorlar.
SSS
Yapay zekâ tarafından üretilen bir PostgreSQL şemasında neleri kontrol etmeliyim?
Üretilen DDL'yi, geçiş işlemlerini ve ikisinin ardındaki varsayımları kontrol edin. Doğru bir nihai şemaya bile veriyi silen, yazmaları engelleyen veya yanıltıcı varsayılan değerler üreten bir geçişle ulaşılmış olabilir.
Şema doğrulama veri kümesi ne kadar büyük olmalı?
Sıradan satırların yanı sıra sınır değerler, eksik ilişkiler, yinelenenler, null değerler, boş dizeler ve geçmişten gelen sıra dışı kayıtlar içeren küçük bir veri kümesi kullanın. Amaç hacim değil, üreticinin varsayımlarını üretim verileri yapmadan önce çürütmektir.
Başarılı bir test geçişi şemanın güvenli olduğunu kanıtlar mı?
Hayır. Başarılı bir geçiş, PostgreSQL'in ifadeleri o veritabanı durumu için kabul ettiğini gösterir. Tablo eşlemelerinin doğru olduğunu, verinin anlamını koruduğunu, dizinlerin gerçek sorguları desteklediğini veya kurtarmanın çalıştığını kanıtlamaz.
Bir PostgreSQL sütunu ne zaman NOT NULL olmalı?
Bir alan, her geçerli kayıtta değer bulunması ve uygulamanın bunu her yazma yolunda sağlayabilmesi durumunda NOT NULL olmalıdır. Kısıtı karşılamak için uydurma bir varsayılan kullanmayın. Bu, görünür eksik veriyi inandırıcı ama yanlış veriye dönüştürür.
Benzersiz kısıt mı yoksa benzersiz dizin mi kullanmalıyım?
Benzersiz kısıt, başka veritabanı nesnelerinin başvurabileceği bir kuralı ifade eder ve PostgreSQL bunu bir dizinle destekler. Benzersiz dizin ise benzersizliğin yalnızca seçilmiş satırlar veya ifadeler için geçerli olduğu durumlarda kullanışlıdır. Örneğin silinmemiş kayıtlar veya normalleştirilmiş e-posta adresleri için.
PostgreSQL yabancı anahtarları otomatik olarak dizin oluşturur mu?
Üst satırları bulmak, sık sorguları filtrelemek, büyük tabloları birleştirmek veya benzersizliği zorlamak için kullanılan sütunları dizinleyin. PostgreSQL, yabancı anahtarın başvuran tarafını otomatik olarak dizinlemez. Bu nedenle kısıtın bunu hallettiğini varsaymak yerine alt tablodaki sütunları ayrıca inceleyin.
ON DELETE CASCADE ne zaman güvenlidir?
CASCADE'i yalnızca üst satır kaybolduktan sonra alt satırın bağımsız bir anlamı kalmıyorsa kullanın. Silme bir iş kararıysa veya alt satır fatura ya da denetim kaydı gibi kanıtsa silmeyi reddedin veya açıkça işleyin.
Bir geçişte yıkıcı değişiklikleri nasıl tespit edebilirim?
Her DROP, daraltıcı dönüşüm, tablo yeniden yazımı, yeni zorunlu sütun ve değiştirilen kısıtı potansiyel olarak yıkıcı kabul edin. Geçiş metninde arama yapın, ancak yıkıcı davranış bunların içinde gizlenebileceği için üretilen işlevleri ve ham SQL'i de inceleyin.
Geçiş kurtarmasını test etmenin en güvenli yolu nedir?
Değişiklik öncesi veritabanını ayrı bir konuma geri yükleyin, geçişi orada çalıştırın, anlamsal doğrulama sorgularını yürütün ve sonuçları kaydedilmiş beklentilerle karşılaştırın. Yalnızca ters geçişi test etmek, silinmiş veriyi gözden kaçırır ve yanlış güven yaratabilir.
Bir şemayı onayladıktan sonra hangi kanıtları saklamalıyım?
Üretilen DDL'yi, geçiş metnini, şema farkını, doğrulama sorgularını ve sonuçlarını, kurtarma prosedürünü ve incelemecinin kimliğini birlikte saklayın. Bu kayıt neyin onaylandığını açıklar ve sonraki geçiş incelemesinin değişen varsayımları fark etmesini sağlar.