Saklı yordamları ne zaman kullanmalıyım?


19

Kodumdaki tüm iş mantığım varsa ve Entity Framework'ten yararlanırsam, hangi durumlarda (varsa), bazı kodları yerine saklı bir yordama daha iyi hareket ederdim ?

Açıkça söylemek gerekirse, geçerli kurulumla (koddaki iş mantığı) birlikte değil, yani. Saklı yordamlarda tüm iş mantığına sahip olmanın artılarını ve eksilerini isteyen bir dizi benzer soru gördüm, ancak iş mantığının geri kalanını korurken, saklı yordamları uç vaka mantığı için idareli kullanma konusunda fazla bir şey bulamadım. kod.

Bir fark yaratırsa, MSSQL ve Entity Framework kullanıyorum.


Daha önce saklı yordamlar kullandığım durumlar şunlardır:

  • Çalışması birkaç dakika süren karmaşık bir rapor (bu bir web uygulamasındaki bir sayfaydı). Ben LINQ sağladığı ne çok daha verimli (çalıştırmak için sadece birkaç saniye sürüyor) SQL yazabilir bulundu.
  • Bir web uygulamasının, uygulama ile ilgisi olmayan diğer birçok hassas bilgiyi içeren ayrı bir veritabanındaki birkaç tabloyu okuması ve yazması gerekiyordu. Her şeye erişim vermek yerine, sadece gerekli olanı yapan ve sadece sınırlı bilgi veren saklı bir prosedür kullandım. Web uygulamasına daha sonra herhangi bir tabloya vb. Erişim olmadan yalnızca bu saklı yordama erişim verilebilir.

Bu soruyu sormadan önce baktığım diğer yayınlar:


4
Her iki durumunuz da saklı yordamları yazmanın mükemmel meşru nedenleridir. Neden meşru olduklarını mı soruyorsunuz ?
Robert Harvey

@RobertHarvey Meşru olduklarından emin oldum ve kodda tutmak yerine bir istisna yapıp saklı yordam yazmanın diğer senaryolarını veya nedenlerini aradım.
Amy Barrett

Sorunu sizin için mevcut olan diğer tekniklerden daha iyi çözdüğünü belirlediğinizde, bir istisna yapar ve saklı bir yordam yazarsınız.
Robert Harvey

Yanıtlar:


10

Zaten birkaç iyi senaryo var.

Bunun başka sebepleri de var. EF, CRUD'da ve oldukça basit raporlarda gerçekten iyidir. Bununla birlikte, bazen EF mükemmel bir araç değildir. Entity Framework ile birlikte saklı yordamları kullanmayı düşünmenin diğer bazı nedenleri (senaryolar) şunları içerir:

  • EF özelliklerini kullanarak bir işlemde kolayca paketlenemeyen, belki de birçok tablo içeren karmaşık iş birimleriniz var.
  • Tanımlayıcı referans bütünlüğünden (yabancı anahtar kısıtlamaları) yararlanamadığı için veritabanınız EF ile iyi oynamıyor. Bu genellikle kendinizi bulmak için kötü bir senaryodur, ancak bazen ETL süreçleri için kullanılan veritabanları gibi uygun senaryolar vardır.
  • Bağlı sunucularla sunucu sınırlarını aşan verilerle çalışmanız gerekir.
  • Yeterli performans sağlamak için "çıplak metal" SQL'in gerekli olduğu çok karmaşık veri alma senaryolarınız var. Örneğin, özel durumunuzda iyi çalışması için sorgu ipuçlarına ihtiyaç duyan karmaşık birleşimleriniz var.
  • Uygulamanızın bir tabloda tam CRUD izinleri yok, ancak uygulamanızın sunucunuzun güvendiği bir güvenlik bağlamında çalışmasına izin verilebilir (örneğin, kullanıcı kimliği yerine uygulama kimliği). Bu, DBA'ların depolanan proclara tablo erişimini kısıtladığı durumlarda ortaya çıkabilir, çünkü onlara kimin ne yapabileceği üzerinde daha ayrıntılı bir kontrol sağlar.

Eminim bunların yanında çok daha fazlası vardır. Herhangi bir durumda ileriye doğru en iyi yolu belirlemenin yolu, sağduyulu bir şekilde kullanmak ve yüksek kaliteli, kolay korunabilir kod yazmak için birincil hedefe odaklanmaktır. Her durumda size bu sonucu veren araçları seçin.


Teşekkürler Joel, düşünmediğim birkaç senaryodan bahsettin.
Amy Barrett

Güzel cevap. Ancak, veritabanına bağlı ve karmaşık sorgular veya saklı yordamlar çalışan birçok kullanıcı olup olmadığını merak ediyorum, sonunda veritabanı sunucusuna çok yük koymak olmaz mı?
Ripal Barot

1
@RipalBarot İş yükü ne kadar fazla olursa (daha fazla kullanıcı, daha karmaşık sorgular) veritabanı sunucunuzdaki taleplerin o kadar fazla olacağına dair bir soru yoktur. Bununla birlikte, akılda tutulması gereken bir şey, Entity Framework gibi ORM'ler yerine saklı yordamlar kullanmanın, saklı yordamlar önceden derlenmiş sorgu planlarına sahip olabileceğinden iş yükünü (karşılaştırmalı olarak) sıklıkla azaltabileceğidir. Bir sorgu bir ORM'den geldiğinde, DBMS genellikle sorgunun nasıl işleneceği ile çalışmaya başlamalıdır. Eşdeğer bir saklı yordamı çağırdığınızda, veritabanı zaten verimli bir şekilde yerine getirmek için nasıl bilir.
Joel Brown

2

Belki de soruyu tersine çevirmek ve sadece saklı yordamların yapabileceği, elde etmek istediğiniz kullanımları bulmak mantıklıdır . Belki de saklı prosedürlerin öne çıktığı gerçekten kullanım durumları vardır.

Bir fark yaratırsa, MSSQL ve Entity Framework kullanıyorum.

EF hakkındaki bilgim sınırlıdır, ancak görebildiğim kadarıyla EF ( sadece ) diğerleri gibi bir ORM'dir; ve neyse kullanma yeteneğine sahiptir ham SQL .

İki önemli noktanızı alırsam:

Çalışması birkaç dakika süren karmaşık bir rapor (bu bir web uygulamasındaki bir sayfaydı). Ben LINQ sağladığı ne çok daha verimli (çalıştırmak için sadece birkaç saniye sürüyor) SQL yazabilir bulundu.

Rapor yaparken LINQ / EF azalıyordu. Ve fark ettiğiniz gibi SQL, bir ORM kullanmaktan çok daha hızlıydı. Ancak bunu saklı yordamlar lehine mi yoksa sadece her şey için ORM kullanmaya karşı mı konuşuyor ?

Sorununuz SQL ile açıkça çözülebilir . Bu sorgu depolanmışsa ve kod tabanınızda sürüm denetimli ise - örneğinize göre - en azından bir fark yaratmaz .

Bir web uygulamasının, uygulama ile ilgisi olmayan diğer birçok hassas bilgiyi içeren ayrı bir veritabanındaki birkaç tabloyu okuması ve yazması gerekiyordu. Her şeye erişim vermek yerine, sadece gerekli olanı yapan ve sadece sınırlı bilgi veren saklı bir prosedür kullandım. Web uygulamasına daha sonra herhangi bir tabloya vb. Erişim olmadan yalnızca bu saklı yordama erişim verilebilir.

Burada aynı şey: basit bir bağlantı dizesi ve ve GÜNCELLEME ve sorun yapılır. Bu problem bir ORM ile bile çözülebilir : sadece diğer DB'nin önünde bir web hizmeti kullanın ve aynı bölümlendirme / izolasyon elde edilir.

Yani burada görülecek bir şey yok.

Diğerlerinin yaptığı bazı noktalara bakıldığında:

EF özelliklerini kullanarak bir işlemde kolayca paketlenemeyen, belki de birçok tablo içeren karmaşık iş birimleriniz var.

Ama SQLbunu yapabilir. Hiçbir sihirli burada içeriyordu.

Veritabanınız EF ile iyi oynamıyor

Tekrar: Uygun olduğunda EF kullanın .

Bağlı sunucularla sunucu sınırlarını aşan verilerle çalışmanız gerekir

Saklı yordamların nasıl yardımcı olduğunu görmüyorum. Bu yüzden saklı yordamların bir avantajını göremiyorum ; ama belki birisi buna ışık tutuyor.

Yeterli performans sağlamak için "çıplak metal" SQL'in gerekli olduğu çok karmaşık veri alma senaryolarınız var

Tekrar: " EF sınırları ".

Uygulamanızın bir tabloda tam CRUD izinleri yok, ancak uygulamanızın sunucunuzun güvendiği bir güvenlik bağlamında çalışmasına izin verilebilir

Tamam. Ben gitmek belki .

Şimdiye kadar sadece yarım puan saklı prosedürler lehine yapılmıştır.


Belki de saklı yordamlar lehine konuşan performans hususları vardır.

1) Sorguların saklanması , karmaşıklığı kapsayan saklı yordama basit bir çağrı yapma avantajına sahiptir . Sorgu planlayıcı sorguyu bildiğinden, optimize etmek "daha kolay". Ancak tasarruflar şu anki karmaşık sorgu planlayıcısı _minimal ile.

Bunun da ötesinde, geçici sorguları kullanırken küçük bir maliyet olsa bile, verileriniz iyi yapılandırılmış ve dikkatli bir şekilde dizine eklenmişse, veritabanı yalnızca uygulamanızın darboğazıdır . Yani küçük bir delta olsa bile, diğer faktörler göz önüne alındığında ihmal edilebilir.

2) Bununla birlikte, karmaşık sorguların bir DB'de depolandığı ileri sürülmüştür. Dikkate alınması gereken iki şey vardır:

a) Karmaşık sorgular, diğer her sorgu için şaşırtıcı süreleri artıran DB altyapısını büyük ölçüde kullanır. Paralel olarak çok sayıda maliyetli sorgu çalıştıramazsınız . Bu, ne pro ne de kontra prosedürler hakkında değil, karmaşık sorgulara karşı konuşuyor .

b) Sorgu yine de zaman alıyorsa, saklı bir yordamın neden küçük hız kazançları ile uğraştığını.

tl; Dr.

Hiçbir şey doğrudan saklı yordamlara karşı konuşmaz . Bu nedenle, saklı yordamları kullanmak iyidir - sizi mutlu ediyorsa.

Ancak öte yandan: Kesin olarak pro konuşan düzgün bir kullanım durumu hayal edemedim .

Saklı yordamları ne zaman kullanmalıyım?

Doğru cevap: İstediğiniz zaman . Ancak başka seçenekler de var.


0

Özel durumunuz için, varlık çerçevesini kullandığınızdan, varlık çerçevesi bir gereksinimi veya endişeyi karşılayamadığında saklı yordamlar kullanmayı düşünebilirsiniz.

Varlık çerçevesi iyi bir iş çıkarır ve performans saklı yordamlar kullanmaya yakın veya eşit olur. Varlık çerçevesini seçtiniz çünkü SQL ile ilgilenmek istemediniz ve çerçevenin sizin için SQL oluşturmasına izin vereceksiniz.

Ancak, varlık çerçevesinin yetersiz kaldığı ve ihtiyaçlarınızı karşılayamadığı bir uç dava olabilir. Bu durumda, bir saklı yordam veya parametreli sorgu kullanarak SQL el ile yazmak ve sonra bu saklı yordam / SQL deyimi doğrudan çağırmak için varlık çerçevesi kullanın.

Bu nedenle, kullanılan çerçeve gereksinimi karşılayamadıkça, saklı bir yordama hiçbir şey taşımazdım.

Olabilecek en kötü şey, birinin varlık çerçevesini kullanmayı seçmesi ve daha sonra tüm saklı yordamları yazmasıdır. Artık bir katma değer olmayan ekstra bir katman var.


% 100 son paragrafta hemfikir
Ewan

0

Teknik bir ihtiyaca sahip olmak en olası seçenek değildir. Programcılar araçlarını tercih ederler ve genellikle onlarla olan problemlerini çözmede daha uyumludurlar. Bir mantığa bir sproc koymak istisna olacaktır. İstisna ile çalışmak için zaman ayırması gereken teknik borç ve gelecekteki geliştiriciler dikkate alınmalıdır. Belirli RDBMS'nizde bir sproc veya belki de dizinlenmiş bir görünüm gibi başka bir db nesnesinin uygulanması daha kolay bir performans artışı olabilir.

Bir veritabanından veriye ihtiyaç duyduğunuz zamanlar olacaktır ve bunu uygulama kodunuzdan alamazsınız. Birçok büyük şirket / işletme durumunda, iş ihtiyaçları BT Departmanının kavrayışını aşabilir. Şirketler alınıp satılıyor, uygulamaları da yanlarında geliyor. Düzenleyici ajanslar ve bankalar, yüksek oranda ölçeklenebilir ve güzel kodlanmış uygulamanızı oluşturamazsanız umursamaz. İş için hayatı zorlaştırabilirler, bu yüzden bunu yapmanız gerekir.

Üçüncü taraf uygulamalarının veya rapor yazma araçlarının kodunuza girmenize izin vermediği durumlarla karşılaştım. Açık kaynak kodu yok, API yok, web arayüzü yok ve servis yok. Sahip oldukları tek şey, yalnızca veritabanı nesneleriyle çalışan kendi özel rapor yazma aracıdır: tablolar, görünümler, sprocs, kullanıcı tanımlı işlevler, vb.

Saklı yordamları yazma konusunda çok iyi bir DBA'nız varsa, bazı durumlarda bu yetenekten yararlanabilirsiniz. Önemli bir veri değişikliği yapacağınız için uygulamanızdan bir yedeklemeyi tetiklemek isteyebilirsiniz, neden dba'nızın kullandığı şeyi kullanmıyorsunuz?

Bazı Geçici istekleri, uygulamanızdaki tüm işlevleri elde edene kadar bir proc yazmak daha kolaydır. Bundan nefret ediyoruz. Geri itiyoruz, ancak şov devam etmeli.


0

Herhangi bir mantığını depolanmış bir yordama yerleştirmemenizi şiddetle tavsiye ederim . Ancak, veri erişim mantığının oraya yerleştirilmesinin tercih edildiği bir durum (iki iyi örnek listelediniz) olabilir .

Genel olarak konuşursak, SP'leri kullanmak için cazip hissediyorsanız, veri modelinizin ihtiyaçlarına uygun olmadığını belirten bir işarettir (bir kod kokusu).

Düzenleme: Geliştiriciler bana iş / veri erişim mantığı hakkında sorduğunda, veri mantığı nasıl saklanır ve alınır hakkında veri mantık veri davranır ve etkileşim hakkında olduğunu söylüyorlar.

Örnek olarak: Alan adı modelinizde, her ikisi de "Kişi" den türetilen "Öğrenci" ve "Öğretmen" öğelerine sahip olabilirsiniz. (Bunun tercih edildiğini söylememek, sadece bir örnek). Bu ilişkisel veritabanlarında bir, iki veya üç tablo olarak saklanabilir. Seçim, kaç özelliği paylaştıklarına ve okuma / yazma performans gereksinimlerine bağlıdır.

İş mantığında, bu varlıkların nasıl saklandığı önemli değildir. (veya bir RDB'de bulunup bulunmadıkları). Veri erişim mantığı tamamen fiziksel olarak nasıl depolandıklarıyla ilgilidir.

Bu nedenle, orijinal soru ile ilgili olarak: Saklı bir yordam, verilerin depolanmasını ve alınmasını daha verimli (veya daha sağlam) yaparsa, bir vakanız vardır. Saklı yordam yalnızca verilerin nasıl saklandığına bakılmaksızın geçerli olduğum bir kural uygulamak için kullanılıyorsa, bundan kaçının. Kodunuzu veritabanına daha sıkı bir şekilde bağlar.


2
İş mantığını ve veri erişim mantığını nasıl tanımlarsınız ?
Amy Barrett


@RobertHarvey Bağlantılar için teşekkürler. Veri erişim katmanı, veri erişim mantığı ile aynı mıdır? Veri erişim katmanında çok fazla gerçek mantık yok gibi görünüyor - sadece basit CRUD işlemleri.
Amy Barrett

@AmyBarrett: Bazen Veri Erişimi katmanına özel yöntemler yazıyorsunuz, bu yüzden her zaman CRUD değil.
Robert Harvey

@RobertHarvey Bu özel yöntemler iş mantığı katmanına ait olmaz mı?
Amy Barrett

-4

Bence burada üç sorun var.

  1. SQL'deki iş mantığı kötü. Bireysel olarak daha hızlı çalışsa bile ölçeklenmez.

  2. Zaman zaman SPROC'lar her zaman bir soyutlama katmanı olarak tüm veri erişimi için kullanılmalıdır. DBA'nın, tüketen uygulamaları etkilemeden performans veya diğer veri katmanı değişiklikleri sunmasını sağlamak.

  3. EF sprocs ile hoş oynamaz. Linq'in dinamik sorgu nesnesinden uzaklaşarak bir çok 'iyi' özellik ve verimlilik kazancı kaybedeceksiniz.

Genel tavsiyem

  • Tüm SQL sorguları için SPROC'ları kullanın,

  • Bunlara iş mantığı veya herhangi bir döngü koymayın,

  • EF kullanmayın.


Tüm SQL db sunucusunda çalıştığından, yalnızca ekstra bilgi işlem kutuları yerine fazladan dbs ile ölçeklendirebilirsiniz.
Ewan

1
Anlıyorum. Ama sonra # 1 noktası tamamen iki performans sorunu arasındaki ödünleşimle ilgilidir. Ancak SQL çözümünün performans açısından net bir kazanç olduğu zamanlar olacaktır, bu yüzden bu temelde kategorik olarak "kötü" olarak nasıl değerlendirilebileceğini görmüyorum.

1
Diyelim ki hesap yapan bir web servisiniz var. Bunu kodda veya sql'de yapabilirsiniz. diyelim ki sql tek bir hesaplamanın kafa kafaya testinde daha hızlıdır. Ama hizmet cpu dışarı maxed zaman çok ucuz ve kolay ikinci, üçüncü, dördüncü eklemek .. web hizmetini çalıştıran kutu ama zor ve pahalı ikinci çoğaltılmış veritabanı eklemek için
Ewan

1
Bu, SQL'in ölçeklenebilirlik nedeniyle kötü bir tasarım olabileceği belirli bir senaryoya bir örnektir . Ancak o zaman bile net değil: beklenen kullanıcı sayısına, dışa kıyasla veritabanında hesaplama yapmanın göreli maliyetine vb. Bağlıdır. Tabii ki bazı durumlarda haklısınız, bunun evrensel bir kural olduğunu düşünmüyorum.

3
Bu genel olarak kötü bir tavsiye. Saklanan yordamları elle kodlamadan daha avantajlı olan ve aynı zamanda performans gösteren veri erişimi için birçok seçenek vardır. Sproksları doğrudan EF'den çalıştırabilirsiniz; aslında herhangi bir sql sorgusunu doğrudan EF'den çalıştırabilirsiniz . Bazı iş mantığı bir veritabanı sunucusunda daha iyi çalışır, bu yüzden orada yasak olduğunu kategorik olarak belirtemezsiniz. Nesne ilişkisel eşleştiricileri% 80 bir araçtır; hiçbir zaman veri erişim süreçlerinizi tamamen değiştirmek istememişlerdir. Ne amaçla kullanıldıkları için saklı yordamlar kullanın: ORM'in iyi yapmadığı% 20.
Robert Harvey
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.