PostgreSQL gibi ilişkisel veritabanı için gerçekten tetikleyicilere ihtiyacım var mı?


10

Ben tetikleyiciler veritabanı tutarlı tutmak için saklanan verileri doğrulamak için kullanılabilir biliyorum. Ancak, neden veritabanında saklanmadan önce uygulama tarafında veri doğrulaması yapmıyorsunuz?

Örneğin, istemcileri depolarız ve DDL düzeyinde kolayca yapılamayan bir doğrulama yapmak istiyoruz. https://severalnines.com/blog/postgresql-triggers-and-stored-function-basics

Başka bir örnek denetimdir.

Güncelleme

Tetikleyiciler ve veritabanı işlemi birlikte nasıl çalışır? Örneğin, eklenen verilerin doğrulamasını yapmak istersem. Bir işlemin içinde yapılır. Daha önce ne olur: işlem yapılır veya tetikleyici yürütülür?


However, why not perform validation of data on the application side before storing them into the database?bu ikisi birbirini dışlamazlar. Her iki tarafta da farklı şeyleri doğrulamanız muhtemeldir. Uygulama tarafındaki doğrulamalar iş merkezli olsa da, veritabanındaki doğrulamalar daha fazla veri merkezlidir. Birkaç ve farklı uygulamalardan beslenen bir veritabanında düşünün.
Laiv

Sisteminize akılsız bir veri dökümü yapan bir dış kaynaktan veri eklemeniz gerekecek mi? Öyleyse, daha sonra düzeltmek için verilerin geçersiz bir biçimde eklenmesi gereken durumlar olabilir. Bu durumda, tetikleyiciler sonsuz sorunlara neden olur. Bunu aklınızda tutun. Bazen yok yürütülen bir tetikleyici istiyorum.
Greg Burghardt

Güncellemeniz kendi başına, belki SO'da bir soru olmalıdır, ancak sorunuzun Veritabanı Yöneticileri üzerinde zaten bir cevabı var . Kısacası, işlem tamamlanmadan önce bir "güncelleme sonrası" tetikleyicisi bile yürütülür ve tetikleyicinin içine bir istisna atılırsa, geri dönmeye neden olur.
Doc Brown

@GregBurghardt Çoğu veritabanında, bu tür etkinlikler için tetikleyicileri devre dışı bırakmak için kullanılabilecek ifadeler bulunur.
Blrfl

1
@Blrfl: Evet, ancak yalnızca geçerli oturum için bu denetimleri koşullu olarak devre dışı bırakmak istediğinizde, bu tetikleyicilerin tüm bağlı kullanıcılar için geçici olarak devre dışı bırakılabileceğini bilmeniz gerekir.
Greg Burghardt

Yanıtlar:


12

Ne tür bir uygulama sistemi oluşturduğunuza bağlıdır:

  • yalnızca bir ana uygulama içeren, özellikle bu uygulama için özel bir veritabanına ve ideal olarak uygulama ve veritabanını yan yana geliştirmekten sorumlu bir ekibe sahip bir uygulama merkezli sistem oluşturuyorsanız, tüm doğrulama mantığını koruyabilir ve denetleyebilirsiniz. uygulama içindeki mantık.

    Bunun en büyük yararı, iş mantığını uygulama ve db arasında dağıtmak zorunda olmamanızdır, bu nedenle sistemi korumak ve geliştirmek genellikle daha kolay hale gelir. Bir bonus olarak, uygulamayı belirli bir DBMS veya DBMS satıcısına çok fazla bağlamıyorsunuz. Uygulamanız tetikleyici sağlamayan hafif bir DB sistemi kullanmak istiyorsa bu yaklaşım açıkça gereklidir.

  • Bununla birlikte, birçok farklı uygulamanın ortak bir veritabanını paylaştığı bir sistem oluşturursanız ve gelecekte hangi uygulamaların ona yazacağını veya gelecekte hangi ekiplerin db'ye veri doldurmak için uygulamalar geliştireceğini öngöremezseniz, o zaman veritabanınızın olabildiğince fazla veri tutarlılığını garanti etmekten sorumlu olması daha iyidir. İşte bu noktada tetikleyiciler gerçekten yardımcı oluyor. Daha büyük sistemlerde, referans kısıtlamaları genellikle bunun için yeterli değildir, ancak saklı bir yordamı çağıran bir tetikleyici ihtiyacınız olan hemen hemen her tür doğrulamayı uygulayabilir.

Tetikleyicileri kullanmanın bir başka nedeni performans olabilir: karmaşık veri modellerinde, istemci uygulamasında mevcut olan geçerli çalışma kümesinin bir parçası olmayan çok fazla ek veri kullanılması gereken karmaşık tutarlılık kurallarıyla karşılaşmak nadir değildir. İstemci tarafında doğrulamayı mümkün kılmak için önce tüm bu verilerin ağ üzerinden aktarılması, dikkate değer bir performans etkisine sahip olabilir.

Ayrıca bu eski SE yayınına bakın: Veritabanı temizliği için Uygulama Logic Vs DB Tetikleyicileri

Bu nedenle, ne tür bir sistem oluşturduğunuza kendiniz karar verin, tetikleyicilerin durumunuz için doğru araç olup olmadığı konusunda yerleşik bir karar verebilirsiniz.


3

Bence soru verinin kalitesinin sorumluluğu ile ilgili.

Yanıt, sistemi nasıl gördüğünüze bağlıdır.

Veritabanını uygulamadan bağımsız, bağımsız ve özerk bir hizmet olarak görürseniz, veritabanı içerdiği verilerin tutarlılığını ve kalitesini sağlamaktan sorumludur. Esasen bu veritabanı farklı bir uygulama tarafından kullanılabileceğinden, aynı tutarlılığa ve kalite davranışlarına sahip ikinci uygulamaya güvenemez. Bu durumlarda, veritabanının bir API ve özerk davranışı ortaya çıkaracak şekilde tasarlanması gerekir. Bu görünümde en az iki uygulama vardır, bunlardan biri veritabanı, diğeri onu kullanan uygulamadır.

Bunun tersine, veritabanı uygulamanın doğrudan ve toplam kontrolü altında olan karmaşık bir dosya biçimi olarak düşünülebilir. Bu anlamda veritabanı, saf bir serileştirme ve belge gezinme aracı olarak gelişir. Sorguyu ve belge bakımını (JSON veya XML araçları gibi) desteklemek için bazı gelişmiş davranışlar sağlayabilir, ancak yine de (çoğu dosya akışının yaptığı gibi) gerekmez. Bu durumda, dosyada doğru biçimi ve içeriği korumak tamamen programların sorumluluğundadır. Bu görünümde bir uygulama vardır.

Her iki görünümde de sonraki soru, veritabanının süslü bir dosya veya ayrı bir hizmet olarak kullanılmasının nasıl destekleneceğidir. Bunu şu şekilde yapabilirsiniz:

  • veritabanı platformunun sağladığı araçları tablolar / görünümler / saklı yordamlar / tetikleyiciler / vb.
  • veritabanını, tüm istemcilerin veritabanına erişmek için kullanması gereken bir hizmetin içine kaydırma
  • veritabanına, verilere erişmek için tüm istemciler tarafından kullanılması gereken bir kitaplık içinde kaydırma.

Her birinin kendi artıları / eksileri vardır ve sistemin içinde çalıştığı ortamın mimari kısıtlamalarına bağlı olacaktır.

Hangi görünüme sahip olursanız olun, verileri her zaman sınırlarda doğrulamak ödeme yapar.

  • Bir kullanıcının girdiği kullanıcı arayüzündeki alanları doğrulayın
  • Ağ / API isteğini istemciden ayrılmadan önce doğrulayın
  • Herhangi bir şey yapmadan önce sunucudaki ağ / API İsteğini doğrulayın
  • İş kurallarına geçirilen verileri doğrulayın
  • Kalıcı olmadan önce verileri doğrulayın
  • Kalıcılıktan alındıktan sonra verileri doğrulayın
  • ve benzeri

Her sınırda ne kadar validasyonun garanti edileceği, validasyonun ne kadar riskli olduğuna bağlıdır.

  • iki sayıyı birlikte çarpmak?
    • yanlış numarayı alıyorsanız bu bir sorun mu?
  • belirli bir bellek konumunda bir prosedür mü çağırıyorsunuz?
    • Bu hafıza konumunda ne var?
    • Nesne yoksa veya kötü durumdaysa ne olur?
  • kanji içeren bir dize üzerinde regex kullanarak?
    • Normal ifade modülü unicode ile başa çıkabilir mi?
    • Normal ifade unicode ile başa çıkabilir mi?

Doğrulama mantığını merkezileştirmek iyidir, ancak imho tetikleyicileri bunu uygulamak için iyi bir yol değildir. Tetikleyiciler ve saklı yordamlar aracılığıyla veritabanında uygulanan tüm doğrulama mantığı ve yan etkileri ile birden çok uygulamanın bir veritabanını paylaştığı bir sistem üzerinde çalışıyordum. Veritabanının önünde bir mikro hizmete sahip olmanın ve oradaki tüm mantığı uygulamanın daha iyi olduğu izlenimi ile geldim. Bir SQL veritabanı içindeki önemsiz mantık bir anti-modeldir.
Joeri Sebrechts

1
@JoeriSebrechts Tamam, ısırırım: Neden bir veritabanındaki önemsiz mantık bir antipattern ve onu ayrı bir bakım programına koymaktan daha fazla bir antipattern yapan şey nedir?
Blrfl

@Blrfl İki nedenden dolayı, DB'deki mantığa erişim API'si bir web hizmeti API'sinden daha düşüktür (sürümü daha zordur, kullanımı zordur, kolayca önbelleğe alınmaz, ...) ve veritabanları temiz bir şekilde yapılandırılmasını ve bakımını zorlaştırır kod tabanı içinde barındırılıyor. Deneyimlerime göre, mantığı veritabanının önünde bir web hizmetinde barındırmak veritabanının içinde olduğundan daha kolaydır.
Joeri Sebrechts

@JoeriSebrechts Çoğu Veritabanı platformunun güvenilir, kullanışlı ve geliştirilebilir bir API uygulamak için kederli araçlar sağladığını kabul ediyorum. Birçok yönden kesinlikle çok acı hissetmek için bir davettir. Demek istediğim, DB'nin süslü bir dosya olduğunu ya da gerçekten ayrı bir hizmet olduğunun farkına varmak, perspektifle ilgili olmasıydı. Bu konuda net olmak için cevabımı detaylandıracağım.
Kain0_0

2

Hayır, doğrulama yapmak için asla tetikleyicileri kullanmamalısınız.

Veritabanı sadece kendi bütünlüğünden sorumludur. Doğrulamayla karşılaşan tüm kullanıcılar uygulamanız tarafından gerçekleştirilmelidir.

Veritabanları, bütünlük için üç doğrulama düzeyi gerçekleştirir. Birincisi saha düzeyinde doğrulamadır. Bir alan gerekli olabilir, eğer değer yoksa (null) bir hatadır. Ayrıca bir kontrol kısıtlaması da olabilir; bir alanın numaralandırılmış sayısı vardır.

İkinci olarak tablolar arasında ilişkiler vardır. Bir tabloda, bu tabloyu diğer tablolarla ilişkilendiren ve değerlerin "diğer tablo" için geçerli anahtarlar olmasını gerektiren bir veya daha fazla yabancı anahtar depolarsınız. Farklı ülkelerin adreslerini desteklediğimiz bir adres veritabanı düşünün. Bir adresteki ülke anahtarı bilinen bir ülkeyi göstermelidir. Verilerin (örneğin bir posta kodu) geçerli olup olmadığı, bu bütünlük denetiminin bir endişesi değildir.

Üçüncüsü ve en karmaşık tetikleyicilerdir. Genel bir kural olarak, bunlar koşullu olan bütünlük kurallarını ele almalıdır (pun amaçlı değil). Adres örneğine geri dönmek için: bir ülkenin posta kodları yoksa, bu listedeki bir ülkenin posta koduna sahip olması bir sorun olacaktır. Dolayısıyla, kontrol şu şekilde olur: bu ülkede posta kodları yoksa, posta kodu alanı boş olmalıdır.

Doğrulama uygulamanın konusudur. Bir Alman posta kodunun yalnızca rakamlardan oluşması, uygulamanın veritabanı değil, yapması gereken bir çek olmasıdır. Çizgi ince bir çizgidir, bu nedenle bazı durumlarda bir şeyin tetikleyicide olması (veritabanınızın bütünlüğünü koruma) veya uygulamada (kullanıcı doğrulaması) bazı düşünme / tartışmaya ihtiyacınız olabilir.


Sadece OP'nin veritabanında olması gereken bir karmaşık doğrulama kuralı eklemesi gerekiyorsa, saklı yordamları her zaman daha güvenli bir alternatif olarak kullanabileceğini eklemek istedim.
Borjab

@Borjab: Veritabanını doğru tutuyormuş gibi doğrulama, belki. Ancak kullanıcı doğrulama ile karşı karşıya mı? No
Menno Hölscher

1
İlk ifadeniz "hiçbir zaman doğrulama yapmak için tetikleyicileri kullanma" diyor , ancak altında "evet, belirli doğrulama türleri için tetikleyicileri kullanabilirsiniz ve çizgiyi nereye çizeceğiniz açık değildir". Bu oldukça çelişkili. İlk cümlenizi silmenizi tavsiye ederim, bu da cevabınızı büyük ölçüde artıracaktır. Oh, ve son cümleniz OPs güncelleme sorusuna cevap vermez, çünkü "önce / sonra" işlemle ilgisi yoktur. Ben de silmenizi tavsiye ederim. (OPs sorusunun altındaki yorumuma bakın).
Doc Brown

@DocBrown Farklılık, veritabanının bozulmaya karşı korunması ve kullanıcı tarafından onaylanması arasındadır. Yani "herhangi bir başka doğrulama" da kullanıcı ile ilgili doğrulama anlamına gelir. Bu ayrımı nasıl daha net hale getirebilirim? Başlangıç ​​olarak "daha fazla" kaldırdım.
Menno Hölscher

2
Veritabanında doğrulama yapmak gayet iyi. Tıpkı uygulamada iyi olduğu gibi. Her ikisinin de avantajları var. Doğrulamayı uygulamada yapmak, neredeyse her karmaşık uygulama için gerekli olan ORM'niz olmadan SQL'i her çalıştırdığınızda çok dikkatli olmanız gerektiği anlamına gelir.
Qwertie

1

Denetim, tetikleyicilerin etkin kullanımına klasik bir örnektir. Tetikleyiciler tarafından uygulanan bir Denetim tablosu sayesinde test cihazı tarafından yapılan bazı hataları buldum (bir istemciyi bir hizmet düzeyinden diğerine taşıma). Denetim için tetikleyicilerin kullanılmasını şiddetle tavsiye ederim.

Doğrulama olabilir ön uç seviyesinde yapılabilir, ama ben (3000 doğumlu insanlar, vs) ele ettik ve kendimi yapılmış bazıları beri ben çok ekstra bir tabakaya sahip olan öneririz veritabanında garip hatalar gördüm Her ihtimale karşı veritabanında doğrulama. Tabii ki, bu tür hatalar kontrol kısıtlamaları ile önlenebilir ve birçok kez daha etkilidirler (MS SQL'de tercih edilen yöntemdir; her zaman belgeleri kontrol edin).


1

Soru, ilişkisel veritabanları için gerçekten tetikleyicilere ihtiyacımız olup olmadığı ile ilgili.

  1. Diğer cevaplarda açıklandığı gibi denetim için.
  2. Daha geniş anlamda denetim: eğer bir veritabanı girişi değiştirilirse, bir tetikleyici olayı asenkronize son işlem için kaydedebilir, örneğin gece başka bir uygulamaya aktarılabilir.
  3. Görünümler için tetikleyiciler: tetikleyiciler tanımlanabilir instead of. Bu demektir ki, bir görünümden giriş ekleyebilir, güncelleyebilir ve silebilirsiniz. Tetikleyiciler bu eylemleri birden çok tabloya yayabilir. Bu, alttaki tabloların ayrıntılarını göstermeden sınırlı bir görünüm elde etmenin bir yoludur.
  4. Veritabanını açık bir şekilde kaydetmek için: A ve B tablosu ile bir ara tablo R arasında bir N: M ilişkisi olduğunu varsayın. R'den A'ya ve B'den R'ye girişin bırakılacağını belirten yabancı anahtar kısıtlamaları tanımlayabilirsiniz. B'deki karşılık gelen giriş silinir. Ancak, iş mantığı bazen A'daki girişlerin B'deki bir girişle en az bir ilişkisi olmasını gerektirir. Bu durumda R'nin silinmesi üzerine tetikleyici bu mantığın uygulanmasına yardımcı olabilir: eğer A'daki bir giriş için R'deki son giriş ise silindikten sonra tetikleyici A'yı silebilir. Uygulama merkezli görünümde en az iki tur gereklidir. Bu bir doğrulama örneğidir. Diğer örnekler düşünülebilir: kullanım durumlarının (1), (2) yanında,
  5. Güven: Bazen veritabanı yöneticileri, komut satırındaki uygulamanızı kullanmayan girdileri değiştirir. Yöneticiler dikkatli çalışır ve ne yaptığını bilir. Ancak, bazen yanlış olabilirler. Tutarlılık kritik ise tetikleyici emniyet kemeri.

Bir dezavantaj olarak iş mantığı katmanlar arasında dağıtılır ve bu bakım için büyük bir dezavantajdır. Başka bir yazarın yazdığı gibi, uygulama ve veritabanı arasında ince bir sınır vardır ve seçim her zaman net değildir. Kişisel düşüncem, tetikleyicilerin geliştiricilere yük getirdiğidir. Geliştirme sürecinde zamandan tasarruf edebilirler. Kesinlikle kullanıcı yavaşlığını artırır, çünkü yavaş ağ bağlantılarında performansı artırırlar.

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.