· 8 dakikalık okuma

Bir veritabanı GUI'si neden asla doğrudan yazmamalı

Her veritabanı GUI'sinde bir tıklamanın production'a karşı bir yazmaya dönüştüğü bir an vardır. Biz o anın var olmaması gerektiğine karar verdik. DynoTable'da yaptığınız hiçbir şey — ne bir öğe düzenlemesi, ne toplu bir silme, ne de bir 'nın değişikliği — DynamoDB'ye doğrudan dokunmaz. Her yazma, attribute başına incelenebilir bir fark olarak bir na iner ve yalnızca bir insan commit ettiğinde gönderilir.

Hedeflediğimiz zihinsel model git'tir: inceleme için bir hazırlama alanı ve git push --force-with-lease gibi davranan bir commit — yalnızca uzak taraf en son gördüğünüz gibi görünüyorsa başarılı olur. Bu yazı, altındaki mühendisliktir: tüm tasarımı yeniden şekillendiren sekmeler arası hata, ana çıktısı silinen kod olan refactor ve AI ajanlarının gelişinin bir UX inceliğini yük taşıyan güvenlik duvarına dönüştürmesinin nedeni.

Yazmalar farktır

Düzenlemeler, yerel SQLite destekli bir hazırlama alanında birikir ve bir yan panelde fark kartları olarak — eski değer, yeni değer, attribute başına — görüntülenir. Izgarada satırlar renklenir, böylece hazırlanan durum yalnızca panelden değil, veriden de görünür. Commit, hazırlanan kümeyi DynamoDB olarak, hizmetin sınırlarına göre parçalara ayrılmış (transaction başına 100 öğe, operasyon başına ve istek başına bayt bütçeleriyle), sırayla, parça başına 30 saniyelik zaman aşımıyla gönderir.

Bekleyen değişiklikleri attribute başına fark kartları olarak gösteren hazırlama paneli; satır başına ve toplu commit ile.
Bekleyen değişiklikleri attribute başına fark kartları olarak gösteren hazırlama paneli; satır başına ve toplu commit ile.

Hazırlama dokümanları günlük iş akışını kapsar. Kapsamadıkları şey, hazırlama alanının neye göre anahtarlandığıdır — ki bu, sistemdeki en sonuç doğuran karar olduğu ortaya çıktı.

Sekmeye değil, tabloya göre anahtarlanmış

İlk sürüm, her hazırlama alanını onu oluşturan sekmeyle sınırlıyordu. Bu tasarım gerçek bir hata üretti: AI'ın hazırlama aracı hedefini etkin sekmeden türetiyordu ve koruyucusu, tablo görünümü olmayan sekmeleri atlıyordu. Dolayısıyla bir SQL Workbench sekmesi odaktayken asistandan bir satırı düzeltmesini istediğinizde, düzenleme Workbench'in hazırlama alanına alınıyordu — ve "hazırlanan değişikliği göster" çipi yanlış sekmeyi açıyordu.

Daha kötüsü, commit kilidi de sekme başınaydı. Aynı tabloyu görüntüleyen iki sekme, iki bağımsız kilit tutuyordu — yani ikisi de aynı hazırlanan satırları gerçek DynamoDB'ye eşzamanlı olarak commit edebiliyordu. Veri modeline gömülü, production'a karşı bir çift commit yarışı.

Çözüm, her şeyi sekme yerine tablo kimliğine{profile, region, tableName} — göre yeniden anahtarlamaktı:

  • Tablo başına tek bir hazırlama alanı; onun her görünümünden görünür, sekme kapatma ve yeniden açmadan sağ çıkar. AI, hiç tablo sekmesi açık olmadan da hazırlama alanına alabilir.
  • Tablo başına tek bir commit kilidi. Çift commit yarışı "ele alınmış" değildir — temsil edilemezdir.
  • Yanlış sekme hata sınıfı yapısı gereği ortadan kalkar: anahtarda sekme yoktur.

Ve yeniden anahtarlama, eklediğinden daha fazla kod sildi. Kapalı sekmeler için hazırlama alanlarını çöp toplayan başlangıç taraması mı? Bir gözden geçiren bunu yeni model altında özellik yıkıcı olarak işaretledi — hazırlama alanları artık sekmelerle birlikte ölmüyor — bu yüzden tamamen kaldırıldı. Sekme kapatınca at ve onay diyaloğu: kaldırıldı. Geriye kalan tek gerçek yetim, açıkça basamaklı olarak temizlenen silinmiş bir bağlantı profilidir.

Migrasyonun kendisi, repo'nun ilk satır değiştiren migrasyonuydu: eski sekme başına satırları bir ROW_NUMBER() OVER (PARTITION BY …) penceresiyle tekilleştiren (en yeni düzenleme kazanır) ve yeni anahtarı, çalışma zamanının anahtar oluşturucusuyla bayt bayt aynı olacak şekilde char(0) ayırıcılarla dolduran elle yazılmış bir SQLite tablo yeniden oluşturması. Satır değiştiren migrasyonlar o gün kendi önce-seed-sonra-migrasyon test düzeneklerini edindi.

DynamoDB için --force-with-lease

İncelediğiniz şey yazılan şey değilse, bir inceleme arayüzü değersizdir. Hazırlama ile commit arasında, başka biri satırı değiştirmiş olabilir. Bu yüzden her commit operasyonu, yazmayı incelediğiniz tam anlık görüntüye sabitleyen taşır — attribute attribute :

  • Bir oluşturma, öğenin zaten var olmadığını doğrular.
  • Bir güncelleme, değiştirdiğiniz her attribute'un, hazırlama alanına aldığınızda gördüğünüz değeri hâlâ tuttuğunu doğrular.
  • Bir kaldırma bile, attribute'un hâlâ eski değerine eşit olduğunu doğrular — bir ekip arkadaşınız, sizin note kaldırmanız hazırlanmış dururken note'u "old"'dan "new"'e değiştirdiyse, commit onların düzenlemesini sessizce silmemelidir.

Bir koşul başarısız olduğunda, DynamoDB tüm transaction'ı iptal eder ve hangi öğenin kaydığını bize söyler. O satır, iki yönde de sessiz bir üzerine yazma yerine bir çakışma bandı alır — canlı değere karşı rebase yapın ya da iptal edin.

Ve herhangi bir parça başarısızlığında, commit eden durur. Commit edilen parçalar commit edilmiş kalır, başarısız parça atomik olarak geri alınır, başka hiçbir şey denenmez. En iyi çaba ile devam etmeyi kasıtlı olarak reddettik: bir çakışmanın ötesinde yazmaya devam eden bir inceleme aracı, kimsenin incelemediği bir değişiklik kümesini uyguluyordur.

human reviews diffsTransactWriteItems +per-attribute conditionscondition failedrebaseEdit / AI stageItemStaging areaper tableCommitDynamoDBConflict banner:rebase or abort

Bir alt sistemi silen refactor

Commit'ler uzun sürer: uygulama, bir renderer'ın yeniden yüklenmesi — veya ikinci bir pencere — yeniden bağlanıp bitişini izleyebilsin diye her birini bir yeniden oynatma kaydına kaydeder. Zamanla, üç farklı kod yolu commit başına iki gözlemci bağlıyordu ve tek bir soru etrafında koca bir hakemlik mekanizması büyüdü: hangi gözlemcinin commit kilidini serbest bırakmasına izin var? Kendi korkutucu adı (ownsLockOnBeforeRegistration), bir IPC sıralama yarışını açıklayan bir yorum bloğu ve 230 satırlık bir toast izleyicisi vardı.

Çözüm tek bir sahipti: commit başına tam olarak bir kez bağlanan, kilidi münhasıran sahiplenen, ilerlemeyi store'a yansıtan ve başlatma çağrısının her çıkış yolunda sonuçlanmasını garanti eden bir Commit Session — asla asılı kalmaz, asla reddetmez. Hakemlik makinesi ve izleyici taşınmadı; silindi. Hazırlama panelini hırpalayan bellek karşılaştırması, yığınının yaklaşık üçte birini düşürdü. O ay aldığımız en iyi kod inceleme yorumu: "bu PR çoğunlukla kırmızı."

Bu sahiplik modelinden, production'a yazan herhangi bir araç için olmazsa olmaz saydığımız iki davranış çıkar: devam eden bir commit bir renderer yeniden yüklemesinden sağ çıkar (oturum yeniden bağlanır ve tamamlar) ve hatta commit ortasında lisansınızın salt okunura dönmesinden bile sağ çıkar — yeni commit'ler engellenir, ama zaten devam eden bir yazma sonuna kadar izlenir, asla yarı uygulanmış halde terk edilmez.

Wire formatı neden kasıtlı olarak çirkin

Hazırlanan değerler, dost canlısı unmarshalled JSON olarak değil, ham DynamoDB türlü zarfları olarak — {N: "42"}, {S: "42"} — saklanır. İki neden. Fark tür bilinçli olmalı: {N: "1"} ve {S: "1"} farklı değerlerdir ve unmarshalled değerler üzerine kurulu bir primary key hash'i onları çakıştırırdı. Ve gidiş-dönüş kayıpsız olmalı: SDK'nın unmarshalled sayı sarmalayıcıları, SQLite'a ve geri JSON serileştirmesinden sağ çıkmaz ve kullanıcı girdisine karşı derin eşitlik bozulur. Commit yolu da aynı nedenle ham istemciyi kullanır — incelediğiniz şey, üzerine koşul konulan ve yazılan şeyle bayt bayt aynıdır.

Sonra ajanlar geldi

Hazırlama, AI özelliklerimizden önce gelir, ama onların gönderilebilmesinin nedeni odur. Asistanın yazma aracı hazırlama alanına alır; kendi açıklaması modele — kelimesi kelimesine — şunu söyler:

The user reviews + commits from the staging panel —
this tool never writes to DynamoDB directly.

Bir commit aracı yoktur. İzinle kapılanmış değil, denetlenmiş değil — yok. MCP sunucusu aynı sınırı yapısal olarak sunar: ortadaki onay kapsamı tam anlamıyla "read + stage" olarak adlandırılmıştır. O kapsamdaki bir ajan çöp önerebilir ve etki yarıçapı, bir insanın okuduğu bir fark kartıdır. Ve commit'ler attribute başına iyimser kilitler taşıdığından, eski bir ajan düzenlemesi bile eşzamanlı bir insan düzenlemesini sessizce ezemez — her şey gibi bir çakışma olarak yüzeye çıkar.

Ajanın sorgularını güvenilir kılma hakkında yazdık; hazırlama diğer yarıdır — onun yazmalarını sıkıcı kılma.

Veritabanınıza yazan herhangi bir araçtan ne talep etmeli

  • Niyet ile yazma arasında bir inceleme adımı — onay diyalogları değil, farklar.
  • Silmeler ve kaldırmalar dahil, incelenen anlık görüntü üzerinde iyimser eşzamanlılık — asla last-writer-wins değil.
  • Bir çakışmanın ötesinde en iyi çaba ile devam değil, başarısızlıkta duran atomik gruplar.
  • Yarı uygulanmış bir küme bırakmadan bir çökme veya yeniden yüklemeden sağ çıkan bir yazma yolu.
  • AI için: bir ajanın sahip olduğu tek yazma ilkeli olarak hazırlama — eksik bir yetenek, korumalı olandan iyidir.

Hazırlama dokümanları iş akışını gösterir ve DynamoDB verisini düzenleme, onun koruduğu temelleri kapsar. Ya da DynoTable'ı indirin, ⌘S ile birkaç düzenlemeyi hazırlama alanına alın ve toplu bir değişikliğin, gerçekleşmeden önce gerçekten okuyabileceğiniz bir şeye dönüşmesini izleyin.

Console olmadan DynamoDB ile çalışın

DynoTable, DynamoDB için hızlı bir masaüstü istemcisidir — tablolara göz atın, SQL tarzı sorgular çalıştırın ve item'ları yerel olarak düzenleyin.