“Asla kodda yapmayın, SQL server'ın sizin için iyi yapabileceği şeyler” - Bu kötü bir tasarım için bir tarif mi?


204

Bir kaç yerde tekrar tekrar duyduğum bir fikir. Bir ya da daha az, bir keresinde tamamen SQL'deki bir problemi çözmeye çalışmanın belirli bir karmaşıklık seviyesini aştığını kabul etmek, gerçekten de kodla başa çıkmanız gerektiğini kabul eder.

Bu fikrin ardındaki mantık, çoğu durumda, veritabanı motorunun, görevinizi tamamlamanın en etkili yolunu bulmak için kodda olabileceğinizden daha iyi bir iş çıkarmasıdır. Özellikle, veriler üzerinde gerçekleştirilen işlemlere bağlı olarak sonuçların yapılması gibi şeyler söz konusu olduğunda. Muhtemelen modern motorlarla etkili bir şekilde JIT'ing + sorgunuzun derlenmiş halini önbelleğe almak yüzeyde anlamlı olurdu.

Asıl soru, veritabanı motorunuzu bu şekilde kullanıp kullanmadığınızdır doğal olarak kötü tasarım uygulamasıdır (ve neden). Veritabanının içindeki tüm mantık mevcut olduğunda ve sadece bir ORM ile vurduğunuzda çizgiler daha da bulanıklaşır.


60
Bu, düşünceli alınması gereken sözlerden biridir. Ne zaman biri 'tablodan seçim yap' seçeneğini seçip başka bir mühendis bulduğunda ve ardından bir set cümlesi kullanmak ve sütun belirtmek yerine sonuç kümesini tararken ortaya çıkar. Ama çok ileri götürürseniz, farklı bir karmaşa ile bitirdiniz.
Michael Kohne

154
"Asla" veya "her zaman" ile bir cümle başlatmak neredeyse her zaman kötü bir tasarım için bir reçetedir.
vsz

34
SQL'de çok fazla şey yapmak kesinlikle mümkün olsa da , dürüstçe söyleyebilirim ki, 30 yıllık geliştirme ve danışmanlık hizmetlerinde bunun ciddi bir örneğini hiç görmedim (birkaç küçük olanlar). Öte yandan, kelimenin tam anlamıyla, SQL'de yapmaları gereken "kod" konusunda çok fazla şey yapmaya çalışan yüzlerce ciddi geliştirici vakası gördüm. Ve hala onları görüyorum. Sık ...
RBarryYoung

2
@MrEdmundo Meta'ya götürün.
ta.speot.is

4
Bu soru bire iki - bölünmesi gerektiğini düşünüyorum. 1) SQL'de ne kadar yapılmalı? 2) DBMS'de ne kadar yapılmalı? Saklı prosedürler ortasına düşer. Saklı yordamlarda kodlanmış tüm uygulamaları gördüm.
reinierpost

Yanıtlar:


321

Layman'ın sözleriyle:

Bunlar, SQL’in yaptığı ve inandığı veya inanmadığı, kodda yaptığım şeyler :

  • joins - codewise karmaşık bir dizi işleme gerektiriyor
  • veri filtreleme (nerede) - codewise, listelerdeki öğelerin yoğun şekilde eklenmesi ve silinmesini gerektirir
  • sütunların seçilmesi - büyük bir liste veya dizi manipülasyonu gerektirecek şekilde
  • toplama işlevleri - kodlama, değerlerin tutulması için dizilerin ve karmaşık anahtar kutularının kullanılmasını gerektirir
  • yabancı anahtar bütünlüğü - kodlamadan önce eklemek için sorgular gerektirir ve hiç kimsenin uygulama dışındaki verileri kullanmayacağını varsayar.
  • birincil anahtar bütünlüğü - kodlamadan önce eklemek için sorgular gerektirir ve hiç kimsenin uygulama dışındaki verileri kullanmayacağını varsayar.

Bunları SQL ya da RDBMS'ye güvenmek yerine yapmak , katma değeri olmayan tonlarca kod yazmaya , yani hata ayıklamak ve bakım yapmak için daha fazla kod anlamına gelir. Ayrıca, tehlikeli bir şekilde veritabanına yalnızca uygulama yoluyla erişileceğini varsayar.


88
+10000000000, her şeyin yalnızca uygulamada gerçekleşeceğini tehlikeli bir şekilde varsaydığını belirtti.
HLGEM

11
@ skynorth Kötü veritabanı tasarımına yol açar. Çizgi Aşağı Bir veritabanı ile sona olabilir ancak dolayı tüm post-processing öyle o uygulama tarafından anlamlı erişilebilir.
Sirex

21
@ skynorth Anahtarlarınızın bütünlüğünü koruduğundan emin olmak için koda güveniyorsanız, temel bir RDBMS ilkesini DB'den kaldırıyorsunuzdur. Bu hiçbir anlam ifade etmiyor, çünkü o zaman DB'ye erişen her uygulamanın bu işlevselliği tam olarak çoğalttığından emin olmak zorunda kalacak. Neden DB'nin bunu yapmasına izin vermiyoruz, çünkü bunun için tasarlandı. DB, örneğin yinelenen anahtarları yerel olarak önleyebilir.
Buttle Butkus

10
işlemleri unutma!
Sklivvz

24
@ skynorth: tl; dr: Verilerinizi tutarlı tutan kurallar veritabanında uygulanmalıdır. yani şimdiye kadar yazılan uygulamaların% 99'unda, verileriniz (ve bu nedenle veritabanı) , başvurunuz sona erdikten ve geçtikten sonra looooooooooong'da kalır . Yıllar boyunca pek çok kez bunu gördüm (Hey, Windows / iPhone / Android'de bir sürüm kurmamız gerekiyor / ne olursa olsun, çünkü ll burada veya Oracle veritabanını burada barındıracak ve orada yeni bir kullanıcı arayüzü oluşturacaksınız ). Bu eğilimin bugün veya herhangi bir zamanda durması için bir sebep yok.
Binary Worrier

122

Ben "sizin için neler yapabileceğini SQL Server kodunda yapılacak asla bu ifadeleri ediyorum iyi ".

Dize manipülasyonu, regex çalışması ve SQL Server'da yapamayacağım şeyler (SQL CLR'yi engelleyen) gibi şeyler.

Yukarıdakiler, birleşme, ayarlama işlemleri ve sorgular gibi şeyler hakkında konuşma eğilimindedir. Bunun arkasındaki amaç, ağır kaldırma işleminin çoğunu SQL Server'a devretmek (iyi olduğu durumlarda) ve mümkün olduğu kadar IO miktarını azaltmaktır (bu nedenle SQL birleşmeleri yapsın ve bir WHEREcümle ile süzün , çok fazla geri getirin diğerlerinden daha küçük veri seti).


27
Her şey SQL'in uygulama kodundan daha iyi yapacağı şeyleri SQL katmanına koyarsa, veritabanında sona erecek daha iyi veya daha kötüsü için bir sürü iş mantığı vardır. Bunu gördüm ve evet, performans yıldız oldu. Neyse ki, dev ekip hepsi uygulama geliştirmeyi ve SQL'i son derece iyi biliyorlardı çünkü ikisi arasındaki sınır çok şekilsiz hale geldi. Bunu bir başlangıç ​​noktası olarak değil, sistemin son derece popüler hale gelmesinden ve performans zamanla bozulduktan sonra bir son nokta olarak önermem.
Jimmy Hoffa

3
Kurslar için atlar innit guv?
StuperUser

28
@NathanLong Neden birçok insanın hala SQL'inizi kaynak kontrolünde tutamayacağınızı düşündüğünü bilmiyorum. İlk önce veritabanını sıfırdan kaynak kontrolünde oluşturmak için gerekli olan tüm saklı yordamlarımız / tablo komut dosyalarımız / vb. Vardı, daha sonra görsel stüdyo veritabanı projeleri kullandık. Projeleri olmadan iyi çalıştı ve onlarla daha iyi. Sisteminizi oluşturmak için gerekli olan diğer her şeyde olduğu gibi SQL sürüm kontrolü altında olmalıdır! Oluşturma komut dosyalarınızı sürüm kontrolü altında tutarsanız dağıtma komutlarının çoğu RDBMS için redgate diff araçlarıyla yapılabilir, farklı komut dosyaları bulundurma araçlarını kullanmayın
Jimmy Hoffa

3
SQL'iniz REGEX işlemleri ve string manipülasyonu destekliyorsa, bunları SQL'de yapmak iyi bir seçim olabilir.
kevin cline

3
@NathanLong: Bunun gibi düşünün, bir DB tablosu bir metin dosyasında yazılı bir kod parçası tarafından tanımlanır, sözdizimi "tablo oluşturma ..." satırları boyuncadır. Artık, bu metin dosyasını, istediğiniz uygulamada dilediğiniz API’yi çağıran DB tablosu oluşturma kodunuz varsa ve bu metin dosyasını SCM’nizde saklarsanız olduğu gibi, istediğiniz SCM’de saklayabilirsiniz. Bence bir problem, bazı insanların DB'lerin bir şekilde sihirli canavarlar olduğunu düşünmeleri ve sadece VB kodunu (ya da her neyse) yazmayı bilmeleri ve bu nedenle de yalnızca bildikleri uygulama diliyle düşünmeleri.
gbjbaanb

47

Asla kodda SQL server'ı sizin için iyi bir şekilde yapabileceklerinizi yapmayın (vurgu benimdir)

Cevabın anahtarı, sizin için basitçe bir şeyler yapmak yerine, iyi bir şeyler yapmak için SQL aramanız gerekir. SQL inanılmaz derecede güçlü bir dildir. Yerleşik işlevlerle birleştiğinde, potansiyel olarak birçok şey yapabilir. Ancak, SQL'de bir şey yapabileceğiniz gerçeği aslında SQL'de yapmak için bir bahane olmamalıdır.

Bir karar vermemdeki özel kriterlerim, geri aldığınız veri miktarına ve gidiş dönüş sayısına bakmaktır: veri toplama miktarını arttırmadan sunucuya bir görev göndererek veri miktarını azaltabilirseniz- gezileri, sonra görev sunucuya aittir; veri miktarı aynı kalırsa veya gidiş-dönüş sayısında aynı anda bir düşüş olmadan artarsa, görev kodunuzdadır.

Bu örnekleri göz önünde bulundurun:

  • Bir doğum tarihi saklarsınız ve bir grup kullanıcının yaşını hesaplamanız gerekir. SQL sunucusunu çıkarma işlemini yapabilir veya kodunuzda yapabilirsiniz. Gidiş-dönüş sayısı aynı kalır ve size gönderilen veri miktarı artar. Bu nedenle, kod tabanlı bir çözüm kazanır
  • Bir doğum tarihi saklarsınız ve 20 ile 30 yaş arasındaki kullanıcıları bulmanız gerekir. Tüm kullanıcıları müşteriye geri yükleyebilir, yaşı bulmak için çıkarma işlemini yapabilir ve sonra filtrelemeyi yapabilir, ancak mantığı SQL Server'a gönderebilirsiniz. ek bir gezi gerekmeden veri miktarını azaltacaktır; bu nedenle, SQL tabanlı çözüm kazanır.

1
Bir yerde çalıştığımda, iş mantığı SQL ile şekilsiz hale geldiğinde, çoklu turlarda sorun yaşamadık; biz sadece bir turluk turda birden fazla sonuç seti kullandık, bu yüzden kurallar orada bozulur, kuralın ruhu altın ortalamayı hedeflemekte oldukça iyidir
Jimmy Hoffa

2
+1 bu harika bir cevap çünkü her iki yöne de destek olacak somut örnekler veriyor
Brandon,

1
İkinci örneğinde. ne diyorsunuz, Senaryo aşağıdaki gibi ise - Kullanıcılar ve bday önbellek ve kayıt büyüklüğü 1000-2000 aralığında. Bunu bellekte yapmak daha hızlı olmaz mı? Veri önbelleğe alındığı için db çağrısı gerekmez ve 'sql işlemi' engellenir. İşlem bellekteki 1000 + kullanıcı listesi boyunca yinelenecek ve eşleşmenin nerede gerçekleştiğini bulacaktır. Bu db yapmaktan daha hızlı olmayacak mı
user4677228

1
@ user4677228 Ancak, yukarı ölçeklemeyi deneyin :-p. Kodunuz tüm yaşları hesaplamak için tüm verileri taramak zorundaysa ve istediğiniz sonuç sadece “en az 20 ve 30 yaşından küçük kullanıcılar?” İse, önbellek size yardımcı olmaz. Hala müşteriye bütün tabloyu akışı bitireceğiz ama veritabanı sunucusu içinde hepsi yapabileceği onun bellek / önbelleklerine ve ne olursa olsun db istemci yerel prizler aracılığıyla veya uzaktan ağa eğer üzerinden bağlanmayı olup olmadığından, daha hızlı bir cevap vermek Sadece bir WHEREmaddede yaşını hesaplamak için istekli .
binki

21

Kısacası , şunu söylemek doğru olacaktır : “ Veri tabanınızda veri tabanına özel işlemler yapmayın”, çünkü veri tabanınızda daha iyi ele alınmaktadır.

Örneğin bak seti baz işlemleri . Bildiğiniz gibi, RDBMS ortak bir veri depolama ve manipülasyon işlemlerini yürütmek için oluşturulmuştur.

Ayrıca, proje veritabanı seçimi de önemli rol oynamaktadır . Bir RDBMS'ye (MS SQL, Oracle, vb ..) sahip olmak RavenDB gibi NoSQL veritabanlarından farklıdır.


Asla ayarlanmış işlemleri kod tabanınıza koymak, LINQ'da yapılan işlemlerin koleksiyonlara (select, sum, where, single) SQL'de yapılması gerektiği ve uygulamanızda değil , veritabanınıza LOT'un çok fazla iş mantığı koyacağı anlamına gelir.
Jimmy Hoffa

4
Tarif ettiğiniz şeyler bir müşteri kodu değildir. Kendi manipülasyon mantığınıza sahip olabileceğiniz bir İş katmanıdır. Ancak bu mantığı 1M + kayıtlarında gerçekleştirmek size geri dönecektir.
EL Yusubov

@JimmyHoffa: Bu doğru değil, bazen uygulama hafızasındaki verilerle işlenmesi gereken geçici bilgiler üretiyorsunuz. Linq bu konuda harikalar yaratıyor.
Fabricio Araujo

@FabricioAraujo Linq'in neden harika olduğunu biliyorum, ancak bu cevap Asla uygulama kodunda asla uygulama kodunu ayarlamadığını belirtir. Asla uygulama kodunda işlem yapmadıysanız , linq kullanmazsınız çünkü linq'in tüm amacı budur. Asla uygulama kodunda ayarlanmış işlem
yapmamanın

@JimmyHoffa: Hayır, kural "uygulamada asla RDBMS'nin sizin için neler yapabileceğini yapmayın" diyor. Ve geçici bilgilerden bahsediyorum - veritabanında ısrar eden bilgiler değil. İş kurallarını yerine getirmek için kod üzerinde işlem yapmam gereken sistemler üzerinde çalıştım. DB üzerinde yoğun işlem yaptıktan sonra (çok önemli) bir rapor oluşturmak için bu veriler üzerinde ek işlemler yaptığım bir İşletme kuralını hatırlıyorum. Bunun üzerine linq kullanabildiğim (şimdi feshedilmiş Delphi.Net sitesinde yapıldı). Başka bir deyişle, linq bu kuralı izleyerek bile kullanılabilir.
Fabricio Araujo

13

Kural olarak, DB'nizin uygulamanızdan daha fazla çalışması gereken bilgiler vardır ve genel veri işlemlerini daha verimli bir şekilde yapabilirsiniz. Veritabanınız, örneğin uygulamanızın anında arama sonuçlarını dizine eklemesi gerekirken, dizinleri tutar. Bu nedenle, diğer herkes eşit olduğunda, işi uygulama yerine veritabanına iterek genel iş yükünüz azaltılabilir.

Ancak, ürününüz ölçeklenirken, genellikle uygulamanızı ölçeklendirmek, db'nizi ölçeklendirmekten daha kolay hale gelir. Büyük kurulumlarda, uygulama sunucularının veritabanı sunucularını 10 ila 1 veya daha fazla bir oranda aştığını görmek nadir değildir. Daha fazla uygulama sunucusu eklemek, genellikle mevcut bir sunucuyu yeni donanıma klonlamanın basit bir sorunudur. Öte yandan, yeni veritabanı sunucuları eklemek çoğu durumda çok daha zordur.

Böylece bu noktada mantra veritabanını korur . Veritabanını önbelleğe almak memcachedveya bir uygulama tarafı günlüğündeki güncellemeleri sıraya koymak veya verileri bir kez almak ve uygulamanızdaki istatistiklerinizi hesaplamak yoluyla başvurmak zorunda kalmamanızdan, veritabanı iş yükünü önemli ölçüde azaltabileceğiniz anlaşılıyor. daha da karmaşık ve kırılgan bir DB kümesi yapılandırması.


1
Para, donanım ölçeklenebilirliği sorunlarını çözebilirken, hiçbir miktar yazılım karmaşıklığını çözemez.
Tulains Córdova

3
@ user1598390 Gerçekten: Donanım Ucuz, Programcılar Pahalı . Para edebilirsiniz yazılım karmaşıklığı çözmek. Programcılara harcanan para. Ama dikkat edin, speghetti'ye karşı temiz koddan bahsetmiyoruz. DB tarafında, uygulama tarafında iş yapmaktan bahsediyoruz. Her iki seçenek de iyi tasarım ilkelerini izleyebildiğinden, yazılım karmaşıklığı yalnızca marjinal düzeydedir. Daha iyi bir soru şudur: " hangi tasarım daha pahalı? ".
tylerl

Nemli ve yağ dolu bir kod tabanına sahip olduğunuzda, çoğu iş dışı şeyler yapıyor, yapabileceğiniz tek şey, donanımdan daha pahalıya mal olan ve çok fazla belirsizlik içeren tüm yeniden yapılanmaların annesidir. nerede iyi bir donanım bulacağınızı her zaman bileceksiniz, ancak iyi programcılar farklı bir hikaye ... bu arada rakipleriniz zamanlarını geliştirmek, uyum sağlamak ve müşterileri mutlu etmek için uyum sağlamak için kullanıyor.
Tulains Córdova

1
Cevabınızda ölçeklendirmeden bahseden tek kişi olmak için +1.
Matt

Donanım artık ucuz değildi - veri merkezinde, elektrik ve donanım işletme maliyetinin% 88'ini (Microsoft tarafından belirtildi) tutar. Bu nedenle, programcılara verimli kod yazmak için daha fazla harcama yapmak çok düşük maliyetlidir ve sınırsız ve ucuz füzyon gücü.
gbjbaanb

12

Bence kastedilen şeyler için veritabanını kullanmamak kötü bir tasarım olacağını düşünüyorum. Kuralların iyi veriye sahip veritabanının dışında uygulandığı hiçbir veritabanı görmedim. Ve yüzlerce veritabanına baktım.

Yani bir veritabanında yapılması gerekenler:

  • Denetim (yalnızca uygulama denetimi, veritabanındaki tüm değişiklikleri izlemeyecektir ve bu nedenle de değersizdir).

  • Veri yetersizliği, varsayılan değerler, yabancı anahtar kısıtlamaları ve her zaman tüm verilere uygulanması gereken kuralları içeren kısıtlamalar içerir. Tüm veriler her zaman değiştirilmez veya bir uygulama aracılığıyla eklenmez, özellikle bir kerede bir kayıt yapmak için pratik olmayan büyük veri kümeleri için tek seferlik veri düzeltmeleri vardır (lütfen gerektiğinde durum 1 olarak yanlış olarak işaretlenen bu 100.000 kaydı güncelleyin). Bir uygulama kodu hatası nedeniyle 2 olun veya lütfen A müşterisinden B müşterisine tüm kayıtlarını güncelleyin, çünkü B şirketi A firmasını satın aldı) ve aynı veri tabanına dokunabilecek veri ithalatı ve diğer uygulamaları.

  • JOINS ve where cümlesi filtreleme (ağ üzerinden gönderilen kayıt sayısını azaltmak için)


6

"Erken optimizasyon, bilgisayar programcılığındaki tüm kötülüklerin köküdür (çoğunu, yine de)" - Donald Knuth

Veri tabanı tam olarak bu; uygulamanızın veri katmanı. Görevi, başvurunuza istenen veriyi sağlamak ve ona verilen verileri saklamaktır. Uygulamanız, aslında verilerle çalışan kodu koyabileceğiniz yerdir; görüntüleme, doğrulama, vb.

Başlıktaki doğrultusunda güven bir noktaya takdire, ve doğru ise (filtreleme asıl mesele, çıkıntı yapan, vb gruplama gerekir bölgesi olabilir "de" bir tanımını Örneklerin baskın bir dizi DB bırakılması) sipariş. SQL Server performans düzeyi yüksek yürütebileceği görevler çoktur, fakat görevler olduğunu göstermekSQL Server'ın yalıtılmış, tekrarlanabilir bir şekilde doğru şekilde yaptığı çok azdır. SQL Management Studio, harika bir veritabanı IDE'sidir (özellikle TOAD gibi çalıştığım diğer seçenekler göz önüne alındığında), ancak bunların arasında öncelikle yapmak için kullandığınız hemen hemen her şeyi (veya uyguladığınız herhangi bir prosedür kodunu) içeren sınırlamaları vardır. altındaki DB) tanım gereği "yan etki" dir (işleminizin bellek alanının etki alanı dışında kalan durumu değiştirir). Buna ek olarak, SQL Server içindeki prosedür kodları henüz yenidir, en son IDE'ler ve araçlar ile, yönetilen kodun kapsama ölçümleri ve yol analizi kullanarak nasıl yönetilebileceğini ölçebilirsiniz (bu nedenle, testin X ifadesiyle karşılaştığı durumlarda bunu gösterebilirsiniz. , Y ve Z ve X testi, koşulu doğru hale getirmek ve Y ve Z "else" i yürütürken bu yarıyı yürütmek için tasarlanmıştır. . Bu da, veritabanını belirli bir başlangıç ​​durumuyla ayarlayabilen, bazı işlemlerle veritabanı prosedür kodunu çalıştırabilen ve beklenen sonuçları ortaya koyabilecek bir testiniz olduğunu varsayar.

Bunların hepsi, çoğu veri erişim katmanının sağladığı çözümden çok daha zor ve ilgili; veri katmanını (ve DAL için) doğru giriş verildiğinde işlerinin nasıl yapıldığını bildiğini ve ardından kodunuzun doğru giriş sağladığını test edin. SP'ler gibi prosedür kodlarını saklamak ve veri tabanını DB'den uzak tutmak ve bunun yerine uygulama kodunda bu tür şeyleri yapmak suretiyle, uygulama kodunun kullanılması çok daha kolaydır.


Bekle, bekle, ne? Doğruluk kanıtlarından testlere nasıl geçtiniz ki bu hataların var olduğunu ancak hiçbir zaman bu kodun doğru olduğunu kanıtlayamaz mı?
Mason Wheeler

2
saklı bir prosedür prosedür kodu değildir. Bir SP, DB içinde depolanan ve çalıştırılan önceden hesaplanmış bir SQL sorgusudur. Bu uygulama kodu değil.
gbjbaanb

1
SP, bir SQL sorgusuyla sınırlıysa, haklısınız demektir. Koşullu kopmalar, döngüler, imleçler ve / veya diğer sorgu dışı mantıkları içeren T-SQL veya PL / SQL ise, yanılıyorsunuz. Ve bir sürü SP, siber alanın her yanındaki DB'lerdeki fonksiyonlar ve tetikleyiciler bu ekstra öğelere sahiptir.
KeithS

5

İnsanların farkına varmadığı şeylerden biri, SQL sunucunuzdaki tüm işlemlerinizi yapmanın kod kalitesi üzerindeki etkilerden bağımsız olarak mutlaka iyi olmamasıdır.

Örneğin, bazı verileri almanız ve ardından verilerden bir şey hesaplamanız ve ardından bu verileri veritabanında saklamanız gerekirse. İki seçenek var:

  • Verileri uygulamanıza alın, uygulamanızın içinden hesaplayın ve ardından verileri veritabanına geri gönderin
  • Verileri kapmak, hesaplamak ve ardından tek bir çağrıdan SQL sunucusuna depolamak için saklı bir prosedür hazırlayın.

İkinci çözümün her zaman en hızlı olduğunu düşünebilirsiniz, ancak bu kesinlikle doğru değil. SQL sorun için uygun değilse bile görmezden geliyorum (örn. Regex ve string manipülasyon). SQL CLR'ye veya veritabanında bile güçlü bir dile sahip olmak gibi bir şeye sahip olduğunuzu farz edelim. Gidiş-dönüş yapmak ve verileri almak için 1 saniye, saklamak için 1 saniye, daha sonra da hesaplamayı yapmak için 10 saniye sürer. Eğer hepsini veritabanında yapıyorsan, yanlış yapıyorsun.

Tabii, 2 saniye tıraş olursun. Ancak, 10 saniye boyunca veritabanı sunucunuzda (en az) bir CPU çekirdeğinin% 100'ünü harcamayı tercih ettiniz mi, yoksa bu zamanı web sunucunuzda mı harcadınız?

Web sunucularının ölçeklendirilmeleri kolaydır, diğer yandan veritabanları özellikle de SQL veritabanları oldukça pahalıdır. Çoğu zaman, web sunucuları da “vatansız” dır ve yük dengeleyiciden başka hiçbir şey yapmadan ek olarak eklenebilir ve çıkarılabilir.

Yani, sadece bir operasyon 2 saniye tıraş değil, aynı zamanda ölçeklenebilirlik düşünün hakkında düşünün. Neden daha ucuz bir web sunucusu kaynaklarını nispeten küçük bir performans etkisi ile kullanabiliyorken, veritabanı sunucusu kaynakları gibi pahalı bir kaynağı israf ediyorsunuz?


1
aynı zamanda ağ gezilerini de unutuyorsunuz - biraz verimlilik çarpmadan sunucular ekleyerek yatay olarak ölçekleyemezsiniz. Bu nedenle, veri yükünü bir yere ekleyerek açık bir şekilde yan tümce açık - ancak diğer sql işlemleri mutlaka performansı düşürmez. Ancak, genel olarak amacınız doğrudur, ancak DB'yi aptal bir veri deposu olarak gördüğünüz nokta için doğru değildir. Şimdiye kadar çalıştığım en ölçeklenebilir uygulama, her veri araması için kullanılan saklı yordamlar (2 karmaşık sorgu dışında). 3. çözüm en iyisidir - "sadece gerekli verileri almak için depolanmış işlem", bunu 'hesaplama' olarak mı kastettiğinizden emin değilsiniz.
gbjbaanb

4

SQL'in yalnızca veriyle ilgilenmesi gerektiğine bakmayı seviyorum. Sorgunun nasıl görüneceğine karar veren iş kuralları kodda olabilir. Bilginin regex veya validasyonu kodda yapılmalıdır. Yalnızca masanıza katılmak, verilerinizi sorgulamak, temiz veriler eklemek vb. İçin SQL bırakılmalıdır.

SQL'e geçen, temiz veriler olmalı ve SQL'in depolamak, güncellemek, silmek veya bir şey almak için gerekenden daha fazlasını bilmesi gerekmez. Birçok geliştiricinin iş mantığını atmak ve SQL'de kodlama yapmak istediğini, çünkü verileri iş olarak düşündüklerini gördüm. Mantığınızı verilerinizden ayırın; kodunuzun daha temiz ve kolay yönetildiğini göreceksiniz.

Sadece benim 0,02 $.


Neden zaten veritabanında bulunan verilerde bir regex veya doğrulama çalıştırıyorsunuz? Kısıtlamalar, kötü verilerin hiç gelmesini engellemelidir ve regex kullanımı muhtemelen daha faydalı sütunlara ihtiyaç duyduğunuz anlamına gelir ..
Brendan Long

Veritabanından gelen verilerde regex veya doğrulama kullanacağımı söylemiyordum. Sanırım bunun veritabanına giden veriler için olduğunu söylemeliydim. Demek istediğim, verilerin DAL'a ulaşmadan önce temizlenmesi ve doğrulanması gerektiği idi.
Stanley Glass Jr

3

Genel olarak, kodun iş mantığını kontrol etmesi ve DB'nin mantıksız bir hash olması gerektiği konusunda hemfikirim. Ancak burada bazı karşı noktalar var:

Birincil, yabancı anahtar ve gerekli (boş değil) kısıtlamalar kodla uygulanabilir. Kısıtlamalar iş mantığıdır. Hangi kodun yapabileceğini yineledikleri için veritabanından çıkarılmaları gerekir mi?

Kontrolünüz dışındaki diğer partiler veritabanına dokunuyor mu? Eğer öyleyse, verilere yakın bir şekilde uygulanacak kısıtlamalar olması güzeldir. Erişim, mantığı uygulayan bir web servisiyle sınırlı olabilir, ancak bu, sizin “ilk” olduğunuzu ve hizmetin diğer taraflarda kullanılmasını zorunlu kılma gücünüz olduğunu varsayar.

ORM'niz her nesne için ayrı bir ekleme / güncelleme yapıyor mu? Eğer evet ise, büyük veri kümelerini toplu işlemede ciddi performans problemleriniz olacaktır. İşlemleri ayarlamanın yolu budur. Bir ORM, üzerinde işlem yapabileceğiniz tüm olası birleştirilmiş kümeleri doğru bir şekilde modelleme konusunda sorun yaşar.

Sunucular tarafından fiziksel bir bölünme veya mantıksal bölme olarak bir "katman" mı düşünüyorsunuz? Mantık yürütmek herhangi bir sunucuda teorik olarak hala mantıksal katmanının altına düşebilir. Sunucuyu yalnızca sunucuları bölmek yerine farklı DLL dosyalarına derleyerek düzenleyebilirsiniz. Bu, endişelerin ayrılmasını korurken, tepki süresini önemli ölçüde artırabilir (ancak güç düşürmeden). Bölünmüş bir DLL daha sonra verimliliği artırmak için (yanıt süresi pahasına) yeni bir derlemesiz başka sunuculara taşınabilir.


neden aşağı oy?
mike30

5
Hiç oy kullanmadım, ancak herhangi bir veritabanı uzmanı size veritabanını düşünmeden mantıksız bir hash yapmanın çok kötü bir fikir olduğunu söyleyecektir. Veri bütünlüğü sorunlarına veya performans sorunlarına veya her ikisine de neden olur.
HLGEM

1
@HLGEM. Cevap mantığı tutmak için nedenleri açıklanır içinde veritabanı veya DB sunucu üzerinde oturan. Hala açıklamıyor.
mike30 23:12

Karşılaştığım gibi tezgahlara ulaşmamış olabilirler, bu yüzden düşürmedim.
HLGEM

3

Deyim, iş kurallarının sürdürülmesi, verilerle yapılması, ilişkiler ile birlikte (veri ve yapı ve ilişkiler) yapılmasıyla daha fazlasıdır. Her sorun için tek bir yerden değil, elle yapılan şeylerden kaçınmaya yardımcı olur. Bunlar, veri tabanı düzeyinde mevcutsa, el ile tutulan ilişki bütünlüğü vb. Bu yüzden eğer bir başkası gelir ve programları genişletirse veya veritabanı ile etkileşime giren başka bir program yazarsa, önceki koddan veritabanı bütünlüğünün nasıl korunacağını bulmak zorunda kalmayacaklardır. El ile tutulan bir kayıt sayacı söz konusu olduğunda, özellikle bir başkası aynı veritabanıyla etkileşim kurmak için yeni bir program yazmak istediğinde geçerlidir. Yeni oluşturulan programın sayaç için tam olarak doğru kodu olsa bile, Orijinal program ve yaklaşık olarak aynı anda çalışan yenisinin programı bozması muhtemeldir. Mümkünse bu ekleme veya güncelleme deyiminde çoğu zaman elde edilebildiği zaman, kayıtları alan ve yeni veya güncellenmiş bir kayıt yazmadan önce koşulları kontrol eden (kodda veya ayrı sorgularda) bile kod var. Veri bozulması yine sonuçlanabilir. Veri tabanı motoru, atomiteyi garanti eder; koşullu güncelleme veya ekleme sorgusunun yalnızca koşulları karşılayan kayıtları etkilemesi garanti edilir ve hiçbir harici sorgu güncellememiz boyunca verileri değiştiremez. Veritabanı altyapısının daha iyi hizmet vereceği durumlarda kodun kullanıldığı birçok başka durum vardır. Her şey veri bütünlüğü ile ilgili, performans ile ilgili değil. Hatta mümkünse bu ekleme veya güncelleme deyiminde çoğu zaman elde edilebildiğinde bile kayıtları alan ve yeni veya güncellenmiş bir kayıt yazmadan önce koşulları kontrol eden (kodda veya ayrı sorgularda) bile kodlama. Veri bozulması yine sonuçlanabilir. Veri tabanı motoru, atomiteyi garanti eder; koşullu güncelleme veya ekleme sorgusunun yalnızca koşulları karşılayan kayıtları etkilemesi garanti edilir ve hiçbir harici sorgu güncellememiz boyunca verileri değiştiremez. Veritabanı altyapısının daha iyi hizmet vereceği durumlarda kodun kullanıldığı birçok başka durum vardır. Her şey veri bütünlüğü ile ilgili, performans ile ilgili değil. Hatta mümkünse bu ekleme veya güncelleme deyiminde çoğu zaman elde edilebildiğinde bile kayıtları alan ve yeni veya güncellenmiş bir kayıt yazmadan önce koşulları kontrol eden (kodda veya ayrı sorgularda) bile kodlama. Veri bozulması yine sonuçlanabilir. Veri tabanı motoru, atomiteyi garanti eder; koşullu güncelleme veya ekleme sorgusunun yalnızca koşulları karşılayan kayıtları etkilemesi garanti edilir ve hiçbir harici sorgu güncellememiz boyunca verileri değiştiremez. Veritabanı altyapısının daha iyi hizmet vereceği durumlarda kodun kullanıldığı birçok başka durum vardır. Her şey veri bütünlüğü ile ilgili, performans ile ilgili değil. Veri tabanı motoru, atomiteyi garanti eder; koşullu güncelleme veya ekleme sorgusunun yalnızca koşulları karşılayan kayıtları etkilemesi garanti edilir ve hiçbir harici sorgu güncellememiz boyunca verileri değiştiremez. Veritabanı altyapısının daha iyi hizmet vereceği durumlarda kodun kullanıldığı birçok başka durum vardır. Her şey veri bütünlüğü ile ilgili, performans ile ilgili değil. Veri tabanı motoru, atomiteyi garanti eder; koşullu güncelleme veya ekleme sorgusunun yalnızca koşulları karşılayan kayıtları etkilemesi garanti edilir ve hiçbir harici sorgu güncellememiz boyunca verileri değiştiremez. Veritabanı altyapısının daha iyi hizmet vereceği durumlarda kodun kullanıldığı birçok başka durum vardır. Her şey veri bütünlüğü ile ilgili, performans ile ilgili değil.

Bu yüzden aslında iyi bir tasarım deyimi ya da temel kuraldır. Bozuk veri içeren bir sistemde performans için hiçbir miktar yardımcı olmayacaktır.


0

Daha önce de belirtildiği gibi, hedef, veri tabanından olabildiğince az veri gönderip almaktır, çünkü gidiş dönüşler oldukça maliyetlidir. SQL istatistiklerinin tekrar tekrar gönderilmesi, özellikle daha karmaşık sorgularda zaman kaybıdır.

Veritabanında saklı yordamların kullanılması, geliştiricilerin bir API gibi veritabanıyla arkadaki karmaşık şemadan endişe etmeden etkileşime girmelerini sağlar. Ayrıca yalnızca isim ve birkaç parametre gönderildiğinden sunucuya gönderilen verileri azaltır. Bu senaryoda, iş mantığının çoğu hala kodda olabilir ancak SQL biçiminde olmayabilir. Kod esas olarak veritabanından neyin gönderileceğini veya talep edileceğini hazırlar.


0

Hatırlanması gereken birkaç şey var:

  • İlişkisel bir veritabanı yabancı anahtarlar aracılığıyla referans bütünlüğü sağlamalıdır
  • Bir veritabanını ölçeklemek zor ve pahalı olabilir. Bir web sunucusunu ölçeklendirmek, daha fazla web sunucusu ekleyerek çok daha kolaydır. Daha fazla SQL sunucu gücü eklemeye çalışırken eğlenin.
  • C # ve LINQ ile, "birleştirmelerinizi" yapabilirsiniz ve kod aracılığıyla yapmazsınız, böylece birçok durumda her iki dünyanın da en iyisini elde edebilirsiniz.

0

"Erken optimizasyon tüm kötülüklerin kökenidir" - Donald Knuth

İşe en uygun aracı kullanın. Veri bütünlüğü için bu genellikle veritabanıdır. Gelişmiş iş kuralları için bu, JBoss Drools gibi bir kural tabanlı sistemdir. Veri görselleştirmesi için bu bir raporlama çerçevesi olacaktır. vb.

Performans sorunlarınız varsa, daha sonra herhangi bir verinin önbelleğe alınabileceğini veya veritabanındaki bir uygulamanın daha hızlı olup olmayacağına bakmalısınız. Genel olarak, ekstra sunucu satın almanın maliyeti veya ekstra bulut gücü, ilave bakım maliyetinden ve ekstra hataların etkisinden çok daha düşük olacaktır.

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.