Ben her zaman PHP ile benim veritabanı girişini kontrol edeceğiz eğer NULL ve YABANCI DEĞİL KEY gibi kısıtlamalar ne kadar önemli?

15 Cevap php

Ben yabancı bir anahtar, bir tablodaki bir sütun oluşturmak çalışıyorum, ancak MySQL böyle olması gerekenden daha zor. Bu geri dönün ve zaten kullanımda tabloda bazı değişiklikler yapmak için beni gerektirir. Ben merak ediyorum, how necessary is it for MySQL to be sure that a certain value is appropriate? Couldn't I just do that with a language like PHP, which I'm using to access this database anyway

Benzer NOT NULL ile. Ben sadece PHP ile bu veritabanına erişim, ben sadece PHP hiç boş değer girildiğinden emin olamazdı?

Why should I use MySQL to do enforce these constraints, when I could just do it with PHP?


Ben NOT NULL Yukarıdaki nedenlerle ihmal etmek çok aptalca bir parçası olduğunu biliyoruz. Fakat MySQL etrafında monkeying ciddi bir derecesi olmayan yabancı anahtarları zorlamaz.

Sizce, hala "sahte" yabancı tuşlarını kullanmak için kötü olurdu, ve girilecek değerler diğer tablolarda eşleştirilir sadece eğer PHP ile kontrol?

15 Cevap

Sen going PHP, garantili% 100 hata yapmak için vardır. PHP usul olduğunu. Ne istediğiniz declarative kısıtlamaları vardır. Sen bütün yığını anlatmak istiyorum: ". Bu verilere kısıtlamalar vardır ve bu kısıtlamaları ihlal edilemez" Sen, veri kısıtlamaları zorlanarak yöntemi olarak, "Adım 1 ... Adım 2 ... Adım 3 Adım ... 432 ..." ile çevresinde çok istemiyorum çünkü

  • Eğer yanlış almak için gidiyoruz
  • daha sonra bunu değiştirmek zaman, sen şimdi ne yaptığını unutacak
  • Şimdi bunları bilmek gibi başka kimse bu örtük kısıtlamalarla bilecek ve bu gelecekteki kendini içerir
  • düzgün ve her zaman kısıtlamaları uygulamak için bir sürü kod alır - veritabanı sunucusu zaten bu kodu vardır, ama bunu yazmak için hazır mısınız?

Soru aslında, ifadeli olmalıdır "Ben sadece MySQL ile yapmak varken, neden ben, bu kısıtlamaları uygulamak için PHP kullanmak gerekir?"

Siz "sadece" programcı "sadece" bug ücretsiz bir kod yazamaz aynı nedenle PHP ile bunu yapamam. Bu düşündüğünüzden daha zor. Eğer bu zor değil bence Özellikle.

Hiçbir şey ever yalnız PHP ile yapıyor, sonra sonra (tabii bug-free) PHP sayfası başka yollarla olsa DB erişecek o sizin yaşam için yemin eğer iyi olacak.

Gerçek dünya senaryoları her zaman bazı belirsizlik içerdiğinden, bu verilerin bütünlüğünü izlerken DB sunucusuna sahip olmak iyidir.

Basit veritabanları için, başvuru bütünlük kısıtlamaları mutlak bir gereklilik olmayabilir, ama güzel-to-var. Uygulama alır, daha karmaşık, daha fazla yararı onlardan çizebilirsiniz. Onları Planlama erken sonra hayatınızı kolaylaştırır.

Ayrıca, başvuru bütünlüğünü değil, her kirli kesmek artık mümkün, çünkü bir daha by-kitapta şekilde veritabanı tasarımı sizi zorlayarak parçası yoktur. Bu da iyi bir şeydir.

Onlar oldukça önemlidir. Eğer PHP ile tamamen modelinizi tanımlamak istemiyorum. Ne PHP kodunda bir hata varsa? Sizin iş kuralları olmamalıdır devlet nerede kolayca sütunlar null'ed olabilirdi. Veritabanı düzeyinde tanımlayarak, en azından ücretsiz olduğunu kontrol olsun. Eğer PHP veya başka bir aracı hiç veritabanını kullanıyorsa hata olduğunda gerçekten nefret gidiyoruz. Sadece IMHO, sorun için soruyorsun.

Tavsiye, bu hikayenin çok kısa versiyonu.

Bu geleceği tahmin etmek imkansız çünkü veritabanında kısıtlamaları uygulamak için önemlidir! Gereksinimleri değişecek zaman asla bilemezsiniz.

Ayrıca birden çok geliştiriciler aynı uygulama üzerinde çalışıyor olabilir olasılığını düşünün. Tüm kısıtlamalar ne olduğunu biliyorum, ama bir junior geliştirici olmayabilir. Veritabanı üzerinde kısıtlamaları ile, genç geliştiricinin kod bir hata üretecektir, ve o şey sabit gerektiğini bileceksiniz. Kısıtlamalar olmadan, kod başarısız olabilir ve veri bozuk alabilir.

Ben veritabanında ilan kısıtlamaları lehine genellikle değilim. Kısıtlamaları için Argümanlar:

  • Bildirime kod bug-free Emir kodu daha yapmak daha kolaydır. Kısıtlamalar app kod hataları içeriyor olsa bile uygulanır.
  • "Kendinizi tekrarlayın etmeyin" prensibini destekler, birden çok uygulama veya aynı veritabanına erişen kod modülleri var ve düzgün yürütülebilmesi için iş kurallarını gerekiyorsa. Eğer kısıtlama değiştirmeniz gerekirse, size birçok uygulamalar olsa bile, bir yerde yapabilirsiniz.
  • Insanlar veritabanı ile tamircilik ad hoc sorgu araçlarını kullanarak, uygulamayı atlamak çalıştığınızda bile veri bütünlüğünü zorlar.
  • Güçlendiği consistency hangi zaman veri herhangi bir veri güncelleme önce ve sonra geçerli bir durumda olduğunu belli olması anlamına gelir. Eğer kısıtlamaları kullanmak istemiyorsanız, kırık referansları kontrol edin ve onları temizlemek için periyodik sorguları çalıştırmak gerekebilir.
  • Siz güncelleme / kısıtlamaları ile kolayca silebilirsiniz basamaklı model olabilir. Uygulama kodu aynı şeyi yapıyor, karmaşık ve verimsiz (hareket yalıtım kullanılması tavsiye edilir gerçi) atomically değişiklikleri uygulayabilirsiniz edemez ve hata açıktır.
  • Kısıtlamalar sütun adları ve SQL veri türleri yardım gibi, veritabanları daha kendi kendini belgeleyen olmak yardımcı.

Kısıtlamalarına karşı argümanlar:

  • Daha karmaşık iş kuralları bildirime kısıtlamaları tarafından model olamaz, bu yüzden yine uygulama alanında bazı uygulamak zorunda. Göz önüne alındığında, neden bir yerde (app) ve aynı dilde tüm iş kurallarını uygulamak değil? Bu hata ayıklama, test ve parça kod değişiklikleri kolaylaştırır.
  • Kısıtlamaları genellikle ekler / güncellemeleri sırasında havai miktar tabi indeksleri içerir. Sütun arama kriterleri kullanılan veya sık sık birleştirme koşullarını olabilir çünkü Öte yandan, bir kısıtlamayı beyan bile, muhtemelen, zaten bir dizin gerekir.
  • Kısıtlamaları veri hatalarını "temizlemek" için girişimleri karmaşık hale getirebilir.
  • Mevcut projede, başvuru kısıtlamaları ile ilgili InnoDb vs MyISAM bir uyumsuzluk biraz keder neden oluyor.

MySQL bu kısıtlamaları sağlayarak neredeyse sıfır zaman alır. Onlar yüzünden hatalı PHP veya diğer kodlar için bile bir tek hata sizi kurtarmak ise, o değer değil mi?

Eğer kendinizi tasarruf edeceksiniz hataların türlü oldukça kötü olabilir unutmayın. Bulma ve kendisi zor olmayabilir hata düzeltme; kötü kısmı hata düzeltildi ettik kez bile kurtarılabilir olmayabilir hatalı verilerin bir grup ile sol olacak olmasıdır.

Hatta "iyi, PHP daha başka bir şey veri Birgün erişmek olabilir" açıdan bu sorunu yaklaşım olmaz. Bu doğru, ama daha da önemlisi kafamda bir kaç basit kısıtlamaları ekleyerek sadece kendinizi kaydedebilirsiniz zaman (para), baş ağrısı, ve veri kaybı vardır.

Yapısal veri bütünlüğü için veritabanını kullanın ve geri kalanı için BR katmanı kullanın. Ve mümkün olduğunca erken hataları yakalamak. Onlar birlikte çalışır.

Kod olgunlaştı zaman şans ile, sen databse RI hatalarla karşılaşabilirsiniz olmaz; ve gururla ilk olarak kendinizi ilan edebilirsiniz.

PHP kodu mükemmel bug-free bile, InnoDB ve işlemleri kullanarak dolayısıyla önemi, veritabanında yarım takılı şeyler bırakarak, (bazı kütüphanede bellek hatası, segfault, vb dışında) orta-script vermeyebilir.

Kısıtlamaları için aynı, tabii ki doğru form doğrulama olmalı, ve bunun arkasında veritabanı kısıtları böcek yakalamak için.

Veritabanı kısıtlamaları uygulamada hata bulma, belirtmek kolay bile zor kısıtlamalar olmaksızın sert, ve olduğunu.

Benim deneyim bu yanlış kısıtlı veri tabanları olmuştur ve MyISAM kullanan bir şey, kullanım birkaç ay sonra inconssitent veri OLACAK, ve o nereden geldiğini bulmak çok zordur.

Veri katmanı kısıtlamalar yoluyla veri tutarlılığını zorlamak olması, veri tutarlı kalır ve uygulama içinde ucuz zamanı hata kontrolü sağlar sağlamak için yardımcı olur.

Eğer kısıtlamaları küçük / olmayan misyon kritik sistemine sahip ya da size sistemin kalitesini artırmak için huge fırsatı geçiyoruz değerli değildir düşünüyorsanız. Bu sade olamaz.

Seçimler şunlardır: Farklı bir RDBMS'yi seçerek, kendi meta sisteminizi yeniden icat veya elle kısıtlamaları yönetmek. Bir meta veri sistemi olmadan sorguları Manuel yönetimi hızla korumak ve şema / sistem karmaşıklığı büyür ve unecessarily gelişen bir şema zorlaştırıyor gibi düzgün denetlemek olanaksız hale gelir.

Benim öneri farklı bir RDBMS'yi seçmektir.

Tutarlılık denetimi düşündüğünüzden çok daha zordur. Örneğin MySQL karşı kontrol ediyoruz değerler başka bir işlem kapsamında aynı değerler olmayabilir demektir işlem okuma tutarlılığı kullanır. Eşzamanlı erişim için Tutarlılık scemantics veri katmanı doğrudan bağlı değilse doğru almak çok çok zordur.

Tüm söyledi ve hatta elle kontrol koymak çaba mütevazı bir miktarda, yapıldığında, sonuç büyük olasılıkla hala dikkate başarısız ya da oluşturan bir hata işledikleri köşe durumlarda üzerinden bir kamyon sürücü mümkün olacaktır olmasıdır.

Lütfen NOT NULL soru üzerine ... bariz veri alanı gereksinimleri iyi bir başlangıç ​​noktası vardır. Burada sütun nullability tanımlarken dikkat edilmesi gereken diğer bir kaç şey vardır.

Bu sorguları çok yararlı yazılı bir garanti sağlar. Çeşitli durum boşlara izin eğer kabul edilemez bir NULL değeri ayrı bir tablo satırının olmayan bir maç göstermek için NULL koşulları kullanabilirsiniz katıldı. (NULL izin verilirse, bir maç satır maç veya satır yaptım maç ama sütun değeri null değil ya anlamına gelebilir.)

NOT NULL kullanımı da eşleşen değerleri basit sorgular için kurallar tanımlamak yardımcı olur. Eğer diyemem yana "değer1 = value2 ZAMAN" değer1 ve value2 hem değerlendirmenin NULL sonucu olup olmadığını hala yanlıştır.

Benim için NOT NULL kullanımı ile ilgili en önemli şey, daha fazla dokümantasyon parçasıdır. Ben bunu sütun NOT NULL diyorsa içeri boş değerlere sahip kabul edilebilir sütunları unutmak bir kaç ay sonra proje döndüğünüzde, o zaman ben hiç ondan potansiyel null değerleri ile uğraşmak zorunda kalmayacaksınız biliyorum. Null verir ve eğer, o zaman ben onlarla uğraşmak zorunda emin biliyorum.

Diğerleri de belirtildiği gibi diğer şey şudur: Bir yerde bir şey özledim, ve verileri temizleyerek berbat veya tamamen imkansız da olabilir. Bu veritabanındaki tüm verilerin tutarlı olduğundan emin bilmek daha iyidir.

  1. Ben size veritabanı sadece PHP tarafından erişilebilir olacak ve eğer öyleyse, geliştiriciler tarafından kim veritabanı tüm lifecyle için bu kısıtlamalar saygı kullanacağız emin olabilirsiniz sanmıyorum.

  2. Eğer şema bu kısıtlamaları dahil ederseniz, daha sonra bir veri şema araştıran tarafından kullanılan ve ilgili nasıl bir iyi bir fikir edinebilirsiniz. Sadece kod tüm bu koyarsanız, o zaman birisi veritabanı ve PHP kodu hem de bakmak gerekir.

But shouldn't that stuff be in the design documentation, data dictionary, and logical database design?

Evet, ama bu belgelerin tarih ve bayat çıkıyorum için kötü üne sahip. I you bunun olmasına asla izin vermez biliyorum, ama daha az disiplin projeler ile deneyime sahip bazı insanlar proje hakkında bu varsayabiliriz, ve oldukça belgelere göre gerçek kod ve şema danışmak istiyorum.

Ben varsayılan değeri kuralları kod tarafında değil, veritabanı tarafında uygulanan gerektiğini derinden ikna olduğum gibi ben çok soru takdir ve bu çok basit bir nedenle: Kullanıcıların veritabanı değişiklikleri başlatmak biri olduğunda ( İNSERTLER, seçer ve GÜNCELLEME), bu değişiklikler tüm iş kurallarını entegre eder ve varsayılan değerler temelde iş kuralları şunlardır:

  • Fatura numarası olmadan hiçbir fatura yok
  • Orada bir miktar olmadan fatura hat ve 0 veya null kabul edilemez
  • Hiçbir gelen posta alımı tarihinden olmadan var
  • vb

Biz, "boş değil" gibi tüm bu "veritabanı tarafı" eserler kurtulmak için birkaç yıl önce karar verdik, ve diğer "varsayılan değer" hileler "boş dizeler izin (yok)", ve mükemmel çalışıyor. Eğer kod tarafında bunu unutacak çünkü varsayılan değer lehine argümanlar çoğunlukla "güvenlik" ilkesine ("veritabanı tarafında bunu bir türlü ifade / dil bunun için yapılmış değil / o bunu yapmak daha kolay Veritabanı tarafında ") Eğer veritabanı tarafında herhangi bir varsayılan değeri uygulamak için seçmiş bir kez herhangi bir anlam ifade etmez: sadece hata ayıklama sırasında iş kurallarının doğru uygulanmasını kontrol edin.

Son 2 yıldır, takımda kimsenin bir tabloda varsayılan bir değer ilan düşündüm. Sanırım bu bizim genç stajyer does not even know "varsayılan değer" denir şey hakkında .

EDIT: Burada bazı yanıtları rereading, benim son açıklama olacaktır:, herhangi bir tarafta bunu DB veya kod ya, ama seçim yapmak ve sadece bir yanından bunu! Her iki taraf gerçekten (2) kontrol kuralları, her iki tarafı kontrol anlamına olacak, yani aynı kuralı uyguluyor eğer sonunda (1) Bildiğiniz asla çünkü her iki tarafta bu tür kontrolleri olan daha tehlikeli bir şey yoktur, hangi olabilir gerçekten bir karmaşa haline! Kötü durum işin bir parçası (veritabanı oluşturulduğunda belirlendi kuralları yani) veritabanı tarafında yapılır kurs ve istemci tarafında yapılan diğer kısmı (yani yeni identitified kuralları) ile bir ... kabus ....

Veritabanı düzeyinde varsayılan değerleri ve kısıtlamaları uygulamak; herhangi bir tüketici tarafından kabul edilebilir bir uygulama verileri neden olur kurallar. Bu bütünlük sorunları sizi yalıtır.

Ardından, uygulama düzeyinde daha iyi varsayılan değerleri ve kısıtlamaları uygulamak. Eğer (access to APIs external to the database) bir kısıtlama uygulanması, ya da veritabanı düzeyinde bir varsayılan değer üreten teknik olarak yasak varsa bunu yapmak gerekir nerede uygulamadır. Bu, better varsayılan değer neden olur. Ancak segfault, ya da uygulamanın genel başarısızlık kabul edilemez verilerini devam ediliyor neden olmaz.

Ben bu dini bir konudur korkuyorum.

Bir puristic noktası görünümünden, veritabanı tutarlılığını yapmak istiyorum. Eğer veritabanına erişen uygulamaların çokluğu olduğunda kısıtlamaları tek bir yerde olduğu için bu, idealdir. Ne yazık ki, gerçek dünya ideal değildir.

Benim deneyim, referans bütünlüğü çeşit zorlamak varsa, uygulama bunu bilmek gerekir. Bu ne olursa olsun son söz sahibi olup olmadığı, ya da veritabanı de bunu denetler. Ve veritabanı does tutarlılığını yapmak, daha sonra uygulama başvuru bütünlüğü ihlal olurdu çünkü veritabanı, bir güncelleştirme reddederse ne yapacağını bilmek zorunda bile ...

Eğer InnoDB kayması gerekir, çünkü bir dipnot düşmek gibi, yabancı anahtar kısıtlamaları desteklemek için MySQL kurma bir sürecin bir parçasıdır. Eğer just bunu yaparsan, sen innodb_flush_log_at_tx_commit 1 ayarlayarak geriye çok fazla bir performans alabilirsiniz. Ancak bunun yerine sitenizi yeniden mühendisi eğer muhtemelen işlem olması daha iyi olurdu -farkında. Sonra InnoDB iki faydaları olsun.