Robert C. Martin, SQL'nin gereksiz olması ile ne demek istiyor? [kapalı]


45

Çok fazla Robert C. Martin içeriği okuyordum / izliyorum. Ona katı hal sürücülerinden dolayı SQL'nin gereksiz olduğunu söyleyerek rastladım. Bunu desteklemek için başka kaynaklar ararken, sabit diskler ve yarıiletken sürücüler arasındaki SQL performansının farkını anlatan bir grup rastgele makale alıyorum (ki bunlar ilişkili ama araştırmaya çalıştığım değil).

Sonunda, neye ulaşmak istediğini anlamıyorum. SQL'in yerini No-SQL teknolojisiyle mi değiştiriyor? Bir dosya sistemindeki dosyalarda veri depolamak mı diyor? Yoksa sadece insanların SQLi saldırıları nedeniyle SQL / İlişkisel Veritabanlarını kullanmayı bırakmasını mı istiyor? Korkarım yapmaya çalıştığı noktayı özlüyorum.

Burada bazı linkler vereceğim, böylece onun aklından direkt olarak okuyabilirsiniz:

  1. Bobby Tablolar
  2. Temiz Mimari Dersi

İlk olarak, SQL'in sistemden tamamen kaldırılması gerektiğini belirtir.

Çözüm. Tek çözüm. SQL sistemden tamamen ortadan kaldırmaktır. SQL motoru yoksa, SQLi saldırısı olamaz.

SQL'i bir API ile değiştirmek hakkında konuşsa da, önceki alıntı ve makalede daha önce söylediklerinden dolayı SQL'i bir API'nin arkasına koymak demek DEĞİLDİR.

Altyapılar konuyla ilgilenmez;

Not: SQL derken, Robert'ın en ilişkisel veritabanları anlamına geldiğinden eminim. Belki hepsi değil, çoğu. Her durumda, çoğu kişi yine de SQL kullanıyor. yani...

Eğer veriyi sürdürmek için SQL kullanılmıyorsa, ne kullanmamız gerekiyor?

Bunu cevaplamadan önce, ayrıca not etmeliyim. Robert, katı hal sürücülerinin, verileri sürdürmek için kullandığımız araçları değiştirmesi gerektiğini vurgulamaktadır. Søren D. Ptæus'un cevabı bunu gösteriyor.

Ayrıca "ama veri bütünlüğü" grubuna da cevap vermeliyim. Bazı araştırmalar sonrasında , Robert datomic gibi işlemsel veritabanlarını kullanmamız gerektiğini söylüyor . Daha sonra CRUD, CR'ye dönüşür (yarat ve oku) ve SQL işlemleri tamamen ortadan kalkar. Veri bütünlüğü elbette önemlidir.

Tüm bunları kapsayan bir soru bulamıyorum. Galiba Robert’ın kurallarına uygun alternatifler arıyorum. Datomik bir değil mi? Bu yönergelere uygun başka hangi seçenekler var? Ve aslında katı hal sürücülerle daha iyi çalışıyorlar mı?


5
@ christo8989 - "SQL'i bir API ile değiştirerek ne anlama geliyor?" Onu kod üssünüzün her yerinde bir metin sorgusu dili (bir SQL motoruna iletilen) olmadığına göre yorumluyorum. Bunu, sorguları tanımlamak için yalnızca güvenli mekanizmalar ortaya çıkaran bir API'nin arkasına gizlersiniz. API şeye İç SQL motoru komutları oluşturmak zorundadır, ama bu vb vb parametresinin kullanımını bağlayıcı, zorunlu kılabilir ki daha küçük bir yüzey alanı, değişiklikler yapar kontrolü vardır
Andrew

42
Ama, ama, ama ... SQL olduğu bir API. Bir RDBMS için API'dir. Sadece kolayca kötüye kullanılabilecek çok güçlü bir API olarak ortaya çıkıyor.
Bart van Ingen Schenau

25
Eğer bir metinsel arayüze sahip olmayan bir DB API oluşturursanız, er ya da geç bazı kötü programcı kod yazmak edeceğini böyle görünüyor: eval(request.GET["table_name"] + ".get(pk=" + request.GET["pk"] + ")")). Gerçekten hatalı olan ama fakir, cahil programcılar olan SQL değil.
Yalan Ryan

6
@JimmyJames SQL bir dildir, ancak bu bir API olmadığı anlamına gelmez. SQL, bazı temel depolama alanlarına erişmek için bir API sağlayan bir dildir.
Kübik

5
@nocomprende SQL her zaman uygulamalar için kullanılmak üzere tasarlanmıştır. Aksi takdirde neredeyse işe yaramazdı. Önemli olan nokta, uygulamalara garip özel biçimlerle uğraşmadan ve hatta verilerin nasıl depolandığına dair çok fazla özen göstermek zorunda kalmadan verileri saklamak ve almak için bir yol sağlamaktı.
Kübik

Yanıtlar:


74

Bob Martin, noktasını daha net hale getirmek için açıkça abartıyor. Ama amacı ne?

Sadece insanların SQLi saldırıları nedeniyle SQL / İlişkisel Veritabanlarını kullanmayı bırakmasını mı istiyor?

Anladığım kadarıyla, o blog yazısında (ilk bağlantınız) Martin insanları SQL kullanmayı bırakmaya ikna etmeye çalışıyor, ancak ilişkisel veritabanlarını değil. Bunlar iki farklı şey .

SQL son derece güçlü bir dildir ve bir dereceye kadar standardize edilmiştir. Çok kompakt bir şekilde, okunabilir, anlaşılabilir, öğrenmesi kolay bir şekilde karmaşık sorgular ve komutlar oluşturmanıza olanak sağlar. Java, C, C ++, C #, Python, Ruby, JavaScript, Basic, Go, Perl, PHP veya başka bir şeyi tercih etmeleri farketmeksizin başka bir programlama diline bağlı değildir, bu nedenle çoğu uygulama programcısı için kullanılabilir.

Ancak, bu güç bir bedelle gelir : güvenli SQL sorguları / komutları yazmak, güvenli olmayanları yazmaktan daha zordur. Güvenli bir API, "varsayılan olarak" güvenli sorgular oluşturmayı kolaylaştırmalıdır. Potansiyel olarak güvensiz olanlar daha fazla zihinsel veya en azından daha fazla yazma çabasına ihtiyaç duymalıdır. Bu, IMHO'nun neden Martin’in şimdiki haliyle SQL’e karşı saldırdığını söylüyor.

Sorun yeni değil ve ilişkisel bir veritabanına erişmek için standart SQL'den daha güvenli API'ler var. Örneğin, tanıdığım tüm OR eşleştiricileri böyle bir API sağlamaya çalışıyor (tipik olarak diğer birincil hedefler için tasarlanmış olsalar da). Statik SQL değişkenleri, girdisiz girdi verileriyle herhangi bir dinamik sorgu oluşturmayı zorlaştırır (ve bu yeni bir buluş değildir: genellikle statik SQL kullanan gömülü SQL, yaklaşık 30 yaşındadır).

Ne yazık ki, esnek, standart, olgun, dilden bağımsız ve ayrıca SQL kadar güçlü, özellikle de dinamik SQL olan herhangi bir API bilmiyorum. Bu yüzden, Martin'in “SQL kullanmama” konusundaki önerisini, belirtilen sorunları çözmenin gerçekçi bir yolu olarak düşündüğüm konusunda bazı şüphelerim var. Öyleyse makalesini, doğru bir düşünceyle okudun, yarından itibaren kör bir şekilde takip edebileceğin "en iyi uygulama" olarak değil.


2
En azından ORM benzeri şeylerin sağladığı herhangi bir yazı işlemi için kullanmaktan kaçınabiliriz. Veritabanını sorgulamaya gelince, kendi SQL'inizi yazmadan zaten bazı şeyler yapabilirsiniz. Günümüzde, veritabanı özelliklerinin yalnızca "ileri düzeyde" kullanımı, SQL veya karmaşık veri tiplerinin kullanılmasını gerektirmelidir (grafik, coğrafi veriler, özyinelemeli).
Walfrat

7
Martin özellikle kullanılacak API'nin SQL kadar güçlü olmaması gerektiğini savunuyor ; SQL’in gücünün sorun değil, bir özellik değil. Savunduğu API uygulamaya özel olmalı ve yalnızca kesinlikle ihtiyaç duyduğu kadar esnek ve güçlü olmalı, daha fazlasını değil. Özellikle başka bir dize tabanlı sorgu dili icat etmeyi reddetti.
Kübik

3
@ Cubic: Martin tarafından belirtilen sorunlara herhangi bir çözüm muhtemelen SQL'den daha az güçlü ya da daha az kolay olması gerekir - bu onların nimeti ve lanetidir.
Doktor Brown

1
@Barmar: SQL alabildiğin kadar yüksek bir seviyede ve Bob'un açık bir şekilde güvensiz olduğunu iddia ediyor.
Robert Harvey

3
@ christo8989: Martin'in bir zamanlar kariyeri boyunca yazdığı ya da söylediği şeylere cevap olarak tek bir cevap yazmanın bir anlamı olduğunu sanmıyorum. Benim cevabım, başlığında verdiğiniz sorudan bir tanesiydi, çoğunlukla verdiğiniz ilk linkteki blog yazısının IMHO'nun nasıl yorumlanması gerektiğini açıklıyor.
Doktor Brown

57

Bob Martin'in düşüncesi tam olarak budur; bir adamın görüşü.

Bir programcının, güvenliği ve performansı hakkında makul bir özen gösterecek kadar iyi yazdığı sistemi anlaması beklenir. Bu, eğer bir SQL veritabanıyla konuşuyorsanız, Bobby Tables web sitesinin yapmasını istediğinizi yaparsınız: girdi verilerinizi dezenfekte edersiniz. Bu, SQL veritabanınızı yeterli performans vaat eden bir makineye koyduğunuz anlamına gelir. Bunları yapmanın çok iyi bilinen ve iyi anlaşılmış yolları vardır ve mutlak güvenlik veya ideal performansı garanti etmemelerine rağmen, başka hiçbir şey yapmaz.

Artık SQL'e ihtiyacımız olmadığı iddiası, çünkü artık SSD'lere sahibiz. Yüksek icatlı sabit diskler henüz mevcut olmadığından SQL icat edilmedi; icat edildi çünkü veri alma kavramlarını ifade etmek için endüstri standardı bir yola ihtiyacımız vardı. İlişkisel veritabanı sistemleri, iş operasyonları için ideal kılan hız ve güvenliğin yanı sıra birçok özelliğe sahiptir; özellikle, ACID . Veri bütünlüğü, en azından hız veya güvenlik kadar önemlidir ve eğer sizde yoksa, kötü verileri güvence altına almanın veya mümkün olduğunca çabuk almanın amacı nedir?

Bir erkeğin histerisini müjde olarak almadan önce, rastgele Internet makaleleri okuyarak değil, kendi şartlarıyla uygulama ve sistem güvenliği ve performansı hakkında bilgi edinmenizi öneririm. Güvenlik, performans ve sağlam sistem tasarımında "bu teknolojiden kaçınmaktan" daha fazlası var.

Mutfak bıçaklarını yasaklamıyoruz çünkü birkaç talihsiz kişi parmaklarını yanlışlıkla onlarla kesmeyi başarır.


16
Martin'in makalelerini, bıraktığım RDBMS'leri terk etmeyi savunan olarak yorumlamıyorum, bunun yerine kaynak kodumuzdaki SQL dizgilerini doğrudan kodlamak veya değiştirmek yerine, örneğin LINQ-SQL veya JPA Kriterleri API'sini kullanmak için alternatif yöntemler kullanıyorum.
Jules

27
Öyleyse söylediklerine kör bir şekilde uymamalıyız ... ama ne diyor ?
TRiG

33
Buradaki topluluktan gerçekten hoşlanmadığım bir şey , Temiz Kod / Bob Amcaya dair bir şeyler yapmakla ilgili bir soru sorduğunuzda , insanların nasıl farklı bir şey yapmanız gerektiğini söylemekten kaçınmalarıdır . "Van Gogh gibi boya nasıl?" - "Van Gogh yanlıştı, onun yerine Picasso gibi boyamalısınız".
R. Schmitz

21
Enjeksiyon saldırılarını önlemek için girdi verilerinin sterilize edilmesi, kodu girdiden ayırmak için parametreleştirilmiş yöntemler kullandıktan sonra yedekleme seçeneği olmalıdır .
cırcır ucube

17
Tüm teknoloji mahkumdur ve esasen kusurludur. Bu sadece bir zaman meselesidir. Bu arada, kusurlu ve mahkum teknolojilerimizle yapmamız gereken şeyler var.

15

Gerçekten ne söylüyor?

SQL'in yerini No-SQL teknolojisiyle mi değiştiriyor?

TL; DR: Evet (sırala)

Daha önce yaptığınız konuşmada, temelde aynı konuya bağladığınızdan daha fazla: "Veri tabanı bir ayrıntıdır. Neden veri tabanlarımız var?" .

Dönen disklerden veri erişimini kolaylaştırmak için veri tabanının geldiğini iddia ediyor, ancak gelecekte "[...] yeni teknoloji ve" kalıcı RAM "olarak adlandırdığı şey sayesinde diskler olmayacak ve bunun daha kolay olacağını söyledi. saklayıcılar veya ağaçlar gibi programcıların kullandığı yapıları kullanarak verileri depolar.

Bir bütün olarak ilişkisel veritabanlarının yeni rekabetlerinden dolayı büyük ölçüde kaybolacağını tahmin etmeye devam ediyor:

Eğer Oracle olsaydım, oldukça korkardım çünkü varlığımın nedeni altımdan buharlaşıyor. [...] Veritabanının var olmasının nedeni yok oluyor.

Muhtemelen hayatta kalan bazı ilişkisel tablolar olacak, fakat şimdi sağlıklı bir rekabet var .

Bu yüzden hayır, onun için sadece SQL enjeksiyonu ile ilgili değil, SQL'in bu konuda kendiliğinden kusurlu olduğunu iddia etmesine rağmen .


Yazarın notu:

Bu yazıda yer alan ifadeler, sadece Robert C. Martin'in bu konudaki görüşünü anlamak ve yazarın fikrini yansıtmamak için yapılan alıntılardır. Daha farklı bir bakış açısı için bkz. Robert Harvey'in cevabı .


2
'Kalıcı RAM' görünüşte sadece ileriye ya da geriye doğru uyumluluk gözetmeksizin mevcut uygulama durumunu serileştirmek için veritabanlarının kullanımını ele almaktadır. Tabii ki, bazı veritabanları bu şekilde kullanılır, ancak hiçbir şekilde hepsi yoktur (Martin'in bunu siz söylediğini biliyorum).
Kübik

7
Martin aslında veritabanlarının tek noktasının yavaş depolamaya devam ettiğini söylüyor. Vay. O zaman bu, Robert Harvey'in cevabını destekliyor: Onun düşüncesi, büyük miktarda tuzla alınmalı. Örneğin, bu bakış açısı bir DB'nin değerinin tutarlı ve kalıcı bir veri modelini koruduğunu düşünmekte başarısız olmaktadır. “Kalıcı RAM” deki (SSD'ler) veri yapıları konusundaki düşüncesi hem yavaş hem de veri kaybı olasılığını artırıyor, NoSQL DB'leri bile sürekli kayıtları güvenli bir şekilde güncellemek için günlük kaydı ve değişken veri yapılarını kullanıyor.
amon

3
@ amon Evet, Robert Harvey daha farklı bir bakış açısı sunuyor. Ancak OP, Robert C. Martin'in özellikle "yeni" konuşmasının bir kısmını kopyaladığımı söylemeye çalıştığını söyledi.
Søren D. Ptæus

3
@amon - yukarıdaki Doc Brown'in cevabının ilk cümlesine bakın. Martin sık sık onu aşmak için noktasında büyük abartı ifadeleri yapar. Tüm veritabanı işlemlerinin hafıza içi depolar ile değiştirilebileceği anlamına gelmez, yalnızca uygulamanızın bir şekilde SQL'e dokunan bir bileşenine sahip olmak anlamına geldiğinden, hepsinden kaçınılması gereken yeterince büyük bir güvenlik riski olduğu anlamına gelmez. Ancak, sözleri karşısında henüz söyleyerek yorumlanabilir. Ama tek yapmaya çalıştığı, herkesi durdurup düşündürmek: benim başvurum için SQL / RDBMS uygun mu?
Jules

12
@Jules Sık sık abarttığını anlıyorum. Ancak, erişimi ve itibarı göz önüne alındığında, “Bob Amca” nın abartırken ve gerçekte ne demek istediğini nerede söylediğini netleştirmemesi oldukça yararsızdır. Bir şey öğretmesi gerekiyorsa , özellikle fikirlerini kendisi yansıtmayacağı veya eleştirmediği için, bir şey ifade edene kadar söylediği her şeyi iki kez tahmin etmek ve yeniden yorumlamak mümkün değildir. Bir noktada, “onu dinlemeyin” demek daha kolay, hatta: Bob Amca Zarar Gördü .
amon

11

SQL bir detaydır. Bir detay bilgisi yayılmamalı.

SQL, kodunuzda gittikçe daha fazla yerde kullanıldığından, kodunuz ona daha fazla bağımlı hale gelir.

Gittikçe daha fazla SQL hilesi öğrenirken, SQL kullanarak daha fazla sorunu çözersiniz. Bu, devam etmek için başka bir API'ye geçmenin sadece çeviriden daha fazlasını gerektirdiği anlamına gelir. Karşılaştığınız problemleri çözmek zorundasınız.

Bunu, Veritabanları arasında bile geçiş yaparak geçiriyorsunuz. Biri fantezi whizzbang özelliği 5 sunar, bu yüzden sadece fantezi whizzbang özelliği 5'in tescilli olduğunu bulmak için bir çok yerde kullanırsınız ve şimdi çok paraya mal olacak bir lisanslama sorununa sahipsiniz. Böylece, özellik 5'i kullandığınız her yerde kazma ve sorunu kendi başınıza çözme, ancak daha sonra whizzbang özelliğini 3 kullandığınızı öğrenmek için çok fazla çalışma yaparsınız.

Java'yı bu kadar taşınabilir yapan şeylerden biri, işlemcinin bazı özelliklerinin kullanılamamasıdır. Mevcutlarsa onları kullanırdım. Birdenbire, Java kodumun çalışmayacağı CPU'lar var çünkü bu özelliklere sahip değiller. Veritabanı özellikleriyle aynı.

Farkında olmadan bağımsızlığınızı feda etmek kolaydır. SQL verilen bir seçim değil. SQL kullanmaya karar verirseniz, o zaman bir yerde yapın. Yapılmayacak şekilde yapın.

SQL’in güvenlik sorunları olması ve kalıcı bellek modellerine geçmemiz, SQL’in mahkum olduğu anlamına gelmiyor. Sadece bir seçim olduğu noktaya eve götürür. Bu seçimi yapma hakkını korumak istiyorsanız, işi yapmanız gerekir.


80'lerin ve Bob Amca'nın veritabanı hareketinin oldukça kötü bir geçmişe sahip olduğuna dikkat çekmek gerekebilir. Yönetim, bir veritabanı yöneticisini hayatına zorladığında, tüm problemlerini düz bir dosya sistemiyle çözdü. Bu olay onu yıldız danışmanlığı kariyerine itti. (Bu öyküyü ilk temiz kitaplarından birinde anlatır, hangisini unutur) DB'siz sorunları nasıl çözeceğini bilir ve bunları kullanmak gibi davrananlar için çok az sabrı vardır.

Ayrıca, bir müşterinin talep ettiği son dakikaya kadar bir uygulamaya DB eklemeyi bırakmasıyla ilgili bir hikaye anlatır ve isteğe bağlı bir özellik olarak bir günde ekler. Tahminimce, çoğumuzun bağımlılıkları olarak DB kullandığını görüyor. Bize alışkanlığı nasıl tekmeleyeceğimizi göstermeye çalışıyor.


1
Tanrım, Einstein, elbette.

1
Ah, Einstein’ın Bob’u tanıdığını bilmiyordum. Ya da Bob, Tanrı’ydı. Her ne kadar kulağa eğlenceli gelse de, eğlenceli bir stand-up bit yapısına sahip.
candied_orange

9
@ sürekli bir motivasyon posteri diyeti yaşamaya çalışıyor musunuz?
candied_orange

2
Ama Bob olduğunu Tanrısı. En azından bazıları için.
Peter Mortensen

3
Kamuya açık konuşmada Tanrı'nın bu kadar iyi olduğuna inanmayı reddediyorum.
candied_orange

5

İlk teklifinizden aldığınız teklif (benimki vurgusu),

Çözüm. Tek çözüm. Mı sistemden SQL ortadan tamamen. SQL motoru yoksa, SQLi saldırısı olamaz.

SQL'in yerine ne geçecek? Elbette bir API! Metin dilini kullanan bir API DEĞİL. Bunun yerine, uygun bir veri yapıları kümesi ve işlevi kullanan bir API gerekli verilere erişmek için çağırır.

Rant, uygulama programcılarının SQL kullanmasına izin vermemeye karşıdır.

Önerilen düzeltme, bunun yerine bir API kullanmasına izin vermektir: ki bu SQL değildir ve enjeksiyona izin vermez.

IMO, bu gibi API'lerin örnekleri şunları içerebilir:

  • http://bobby-tables.com/csharp , C # programcılarının ADO.NET API'sini kullanabileceğini ileri sürüyor.

    ADO.NET geniş veya derin (yani güçlü veya genel amaçlı) API, çünkü O mükemmel bir örnek değil , aynı zamanda giriş raw (veya çiğ-imsi) SQL için kullanıcılarına sağlar.

  • Bazı SQL geliştiricileri veya veritabanı yöneticileri, bir veritabanının (sınırlı sayıda uzmanlıkla yazılmış) saklı yordamlar yoluyla erişime izin verecek şekilde yapılandırılması gerektiğini ve uygulama geliştiricilerin kendi (tehlikeli) SQL sorgularını yazmalarına izin verilmemesi gerektiğini önermektedir.

  • "Sistemden SQL'i elimine etmenin" başka bir yolu, veritabanını (SQL'i ortaya çıkaran) başka bir sisteme, bir REST API'si veya benzeri bir şeyle erişmektir.

Bu nedenle, IMO, genel çözüm veya sistem [ler] hala bir veritabanı kullanabilir (özellikle bir veritabanı motorunun faydalı ACID özelliklerini uyguladığı ve iyi ölçeklendirdiği göz önüne alındığında, böyle bir şey yapmadan denemek veya yazmak uygulamaya özgü olanı).

Veritabanının SQL API'si uygulama geliştiricilerden, başka bir API'nin (örneğin, ADO, belki bir ORM, bir Web servisi veya her neyse) arkasına gizlenmişse rant'ın gereksinimleri karşılanır.

Daha genel olarak, uygulamaya özel bir DAL ("veri erişim katmanı" veya "veritabanı soyutlama katmanı") içerdiğini düşünüyorum. Bir DAL, uygulamayı verilerin nasıl ve nerede depolandığı ve / veya alındığı hakkındaki detaylarından izole eder. DAL, bir SQL veritabanı kullanılarak gerçekleştirilebilir veya uygulanmayabilir.


Bunu tam olarak 30 yıl önce yapan bir ürün üzerinde çalıştım. Ve, temel veritabanı bile SQL'i (henüz) desteklemedi. Ve ilgili tablolar seti bir veritabanında (bunun için bekleyin ...) saklandı. Bunu yapan adam çok akıllıydı. Artık bir programcı değil.

Bu cevabı beğendim ama sanırım bunu söylemiyor olabilir. Ayrıca “Çerçeveler sorunu çözmüyor…” diye de belirtiyor. Cevabınıza göre Linq-to-Sql kullanmanın uygun olduğu söyleniyor gibi görünüyor ama bu sorunu çözen bir çerçeve değil mi?
christo8989

@ christo8989 Bilmiyorum. Hazırda Bekletme konusuna değinmeyen bir çerçeve örneği olarak bahseder. Ve gerçekten de OWASP , "Hazırda Bekletme, SQL Injection'a bağışıklık sağlamıyor, kişi istediği gibi api'yi kötüye kullanabilir. HQL (SQL'i Hazırda Bekletme alt kümesi) özel ya da daha az hassas kılan özel bir şey yok." Bununla birlikte, bahsettiğim bazı API'ler, SQL'i açığa vurmak yerine daha iyi yalıtkanlar olurdu. Belki Hazırda Bekletme, bir DAL uygulamak için kullanabileceğiniz bir şeydir (ancak kendisi tam bir DAL değildir).
ChrisW

1
@ christo8989 augustl.com/blog/2016/… , Datomic'in bir (muhtemelen) SQL veritabanı çevresinde (sadece) başka bir sarmalayıcı / katman olduğunu öne sürer - "Datomic, doğrudan dosya sistemine yazmaz. Bunun yerine, bir sayı kullanabilirsiniz Datomic için bir depolama arka ucu olarak farklı veritabanlarının listesi: Herhangi bir SQL JDBC veritabanı, vb. "
ChrisW

ADO.NET'te SQL enjeksiyonundan kaçınmak için çözümün o kadar da karmaşık olmadığına dikkat edilmelidir - SQL'de yer tutucular kullanın, komuttaki parametreleri kullanın ve söz konusu parametrelerin değerini ayarlayın.
Zev Spitz

3

Herkes bu soruyu bir güvenlik bakış açısıyla veya bir SQL mercekle cevaplıyor gibi görünüyor.

Programcılar olarak özel programlarımız için en uygun olan birçok farklı veri yapısını kullandığımızı anlattığı bir Robert Martin dersi gördüm. Bu nedenle, tüm verileri evrensel olarak tablo halinde bir yapıya kaydetmek yerine, verilerimizi karma tablolara, ağaçlara vb. Depolamalıyız. Böylece verileri alabilir ve programa atlayabiliriz.

Onun mesajını sadece bir süredir mevcut depolama konusundaki varsayımlarımızı asırlık SQL tablo formatından başka gelecek olasılıklarını düşünmek için kullanmamız gerektiğini söyleyerek yorumladım. SSD aday bir çözümdür, ancak tek çözüm değildir.


Çok kullanıcılı eşzamanlı veri okuma / yazma hakkında ne düşünebilir?
ChrisW

1
@ChrisW Bunun kalıcı bir veri depolama yapmanın bir yolunu bulma konusunda üst düzey bir fikir değil, bunun bir uygulama sorunu olduğunu düşünmüyorum.
Keenan

@ChrisW Ayrıca işlem veritabanları hakkında konuşuyor. Kaynak kontrol teknolojisini kalıcılık aracı olarak kullanmak. Bununla, sadece işlem ve güncellemelerden çok daha fazla eşzamanlı olanı yaratır ve okursunuz.
christo8989

@Keenan Yani uygulama yoluyla bir çözüm sunmuyor. Sadece ne olabileceğini düşün, diyor mu?
christo8989

1
@ christo8989 Bilgisayar biliminde kalıcı depolama problemi için kişisel olarak aday çözümlerin geliştirilmesine öncülük edip etmediğini bilmiyorum. OP'nin sorusunun kapsamı dışında. Bob Amca tamamen eklenti mimarisi ile ilgili. Uygulama geliştirmenin mevcut endüstri standardı, bir veritabanına sıkı sıkıya bağlanıyor ve bunun etrafında uygulamayı oluşturuyor, uygulama db'nin uygulamaya bağlı olması gerektiğinde db'ye bağlı. Aksine, Bob Amca 'veri tabanı bir ayrıntıdır' ve ayrıştırılabilir ve değiştirilebilir olmalıdır.
Keenan

2

Aslında veritabanlarını ve SQL'i kullanmayacak - açık bir şekilde. İlk referans iyi bilinen bir konudur, ikinci referans bir rant gibi ses çıkarmaktadır. Bununla birlikte, veritabanlarını kullanmak ve SQL kullanmamak için iyi bir neden olduğunu yorumluyorum. Benim açımdan bu makul bir tavsiye bile değil.

Ne yazık ki, kullandığı örnek, daha sonra işaret ettiği iyi bilinen bir çözüme sahip iyi bilinen bir örnek. Genellikle bir programcı ne yaptığını anlamadığında ortaya çıkar. Örneğin, SQL benzeri dizgiler oluşturmak için:

    my $sql="select a from b where a=$ui_val;";
    prepare($sql)
    execute($sql)

aksine

    my $sql="select a from b where a=?;";
    prepare($sql)
    execute($sql,$ui_val);

Bu bir DBI perl gibi raylar kodunda yakut için bir örnektir. Sağladığı ray kodu, güvenli ile güvensiz arasında karışmak kolaydır. Pek çok ORM gibi, SQL'in altında ne olduğunu gizler ve bu yüzden sık sık sizin için sql'yi oluşturan ve çalıştıran bir arayüz ile uğraşırsınız. Bu ses neredeyse bir API'nin sizin için ne yapacağını sevmiyor mu?

İlk referansı yorumlamam, iyi bilinen bir çözümü olan iyi bilinen bir konuyu değiştirmemiz gerektiğini önerdiği yönündedir.

Ayrıca, doğru yapılırsa kodun yazılmasını kolaylaştıracağını ve okunabilir hale getireceğini söylemediği için talihsizdir, ancak iyi yapılırsa, yazması daha zor ve daha az okunabilir olabilir. Ek olarak, SQL'in okumasının gerçekten çok kolay olduğu ve genellikle yapmasını beklediğiniz şeyi yaptığı anlamına gelmediğinden bahsetmiyor.

Kısmen doğrudur, sonuçta sonsuz derecede büyük ve hızlı bir belleğe ve sonsuz derecede hızlı bir işlemciye sahip olacağız. Bilgisayarı kısıtlayan mevcut fizikten ayrılıncaya kadar doğru değil.

Evet dönen disk artık geçmişte kaldı ve şimdi SSD kullanıyoruz. Diskler, veri aktarımı başına yaklaşık ~ 10 milisaniye, SSD'ler ~ 0,5 milisaniye (500 mikrosn) veri erişim süresiyle çalışır. RAM, 100 nano saniyelik bir sıradadır, işlemciler 100'lerce pico saniyede çalışır. Veritabanlarına neden ihtiyaç duyduğumuzun kalbi budur. Veritabanları, dönen diskler veya SSD'ler arasındaki ana aktarımlı veri aktarımını yönetir. SSD'lerin ortaya çıkışı veritabanlarına olan ihtiyacı ortadan kaldırmamıştır.


4
"SQL'İ KULLANMAYI DURDUR" (ilk linke atıfta bulunularak), benim anladığım kadarıyla, SQL kullanmamayı söylediği gibi geliyor.
Doktor Brown

6
Bu bir kelime sırası meselesidir. Aslında bu aslında bir telgraftı: SQL

6
@nocomprende Yani sizce o bir yarış durumunun kurbanı mı? Oops. SQL işlemlerini kullanarak bundan kaçınabilirdi.
Konrad Rudolph

Belki de Visual Basic ve Fortran'ın çok kısa bir karışımıdır. Hepsi nerede sona erecek?

1
@KonradRudolph: Bence, neredeyse hiç kimsenin doğrudan TSX'i montajdan kullanmayacağı konusunda hemfikir oluruz. Daha yüksek seviyeli soyutlamalar olacak. Bu soyut işlemler SQL işlemleri olacak mı? Bence değil. Yorumlanmış bir dil olarak, SQL genel bir performans sergiliyor. Dönen sabit disklerle ilgili verilere eriştiğinizde bunun önemi yoktu. Ancak RAM'deki verilere erişirken bu uygun değildir.
MSalters

2

Cevap

sadece insanların SQLi saldırıları nedeniyle SQL / İlişkisel Veritabanlarını kullanmayı bırakmasını mı istiyor?

'Bobby Tables' makalesi, bunun, kendisinin ve SQL'in kullanılmaması için bir neden olduğunu öne sürüyor:

Çözüm. Tek çözüm. SQL sistemden tamamen ortadan kaldırmaktır. SQL motoru yoksa, SQLi saldırısı olamaz.

Başka bir yerde tartışması için başka nedenleri olabilir. Bilmiyorum, çünkü pek fazla bir şey okumam.

konu dışı söz

Bu kısım gerçekten bir cevap değil, fakat SQL değerinin sorusu çok daha ilginç (sanırım diğerleri gibi).

SQL kullanarak çok deneyime sahiptim ve onun güçlü ve zayıf yönlerini tam olarak anladığımı düşünüyorum. Benim kişisel hislerimin aşırı kullanılması ve kötüye kullanılması, ancak onu asla kullanmamamız gerektiği fikrinin saçma olması. 'Her zaman SQL' veya 'SQL asla' seçmemiz gerektiği fikri yanlış bir ikiliktir.

SQL enjeksiyonu, SQL kullanmamak için bir argüman olduğu sürece, gülünç olur. Bu oldukça basit bir çözüm ile iyi anlaşılmış bir sorundur. Bu argümanla ilgili sorun, SQLi'nin var olan tek güvenlik açığı olmamasıdır. JSON API'lerinin kullanılmasının sizi güvence altına aldığını düşünüyorsanız, büyük bir süpriz yapmaktasınız.

Her geliştiricinin "13'üncü Cuma: JSON'a Saldırı - Alvaro Muñoz ve Oleksandr Mirosh - AppSecUSA 2017" başlıklı bu videoyu izlemesi gerektiğini düşünüyorum.

İzleyecek vaktiniz veya eğiminiz yoksa, işte ana fikir: Pek çok JSON seri kaldırma kütüphanesinde uzaktan kod yürütme güvenlik açığı bulunmaktadır. XML kullanıyorsanız, endişelenecek daha çok şey var. SQL'i mimarinizden yasaklamak sisteminizin güvenliğini sağlamaz.


Kimse SQL'i yasaklamanın kendi başına sisteminizi güvenli hale getireceğini iddia etmedi. Bob Amca, sisteminizi daha güvenli hale getirdiğini iddia ediyor ve SQL enjeksiyonunun on yıldan fazla bir süredir web uygulaması güvenliğindeki en büyük risk olmaya devam ettiği göz önüne alındığında, sektörün veritabanları ile konuşma şeklini geliştirme ihtiyacını hafifçe reddetmemeniz gerektiğini düşünüyorum. .
meriton - grevde

@meriton Üzgünüz, ama "çözüm, tek çözüm" oldukça açık görünüyor. SQLi sorununun çözümü bilinmektedir ve oldukça basittir. Rahatsız edilemeyen insanlar, use cümleleri hazırlamayı, SQL kullanmayı bırakıp bırakmadıklarına bakılmaksızın, güvensiz sistemler yaratacaktır. Bunlar, temel iyi uygulamaları izlemeye başlaması veya yeni bir işe girmesi gereken profesyonel olmayan kişilerdir.
JimmyJames

2

Sadece kısa bir ifadeye değinmek istiyorum:

Yoksa sadece insanların SQLi saldırıları nedeniyle SQL / İlişkisel Veritabanlarını kullanmayı bırakmasını mı istiyor?

Hayır. Bu yanlış bir varsayımdır. Araba kullanmayı bırakmamız gerektiğini söyleyemeyiz, çünkü araba kazalarında ölen insanlardan sorumludurlar. Aynı şekilde, SQL / ilişkisel veritabanları (veya RDBMS gibi bu bağlamdaki herhangi bir şey), bir saldırganın web uygulamanızda gerçekleştirebileceği kötü niyetli SQL yükünden sorumlu değildir. Yazarın bunu kastetmediğinden eminim, çünkü bu amaçla bir SQL enjeksiyon önleme kopya kağıdı var .


2
Otomatik otomobiller, araba kazalarının yaklaşık% 98'ini önleyecektir. Makineye daha fazla güvenmeliyiz , he he he he he.

3
“Arabaları kullanmayı bırakmamız gerektiğini söyleyemeyiz [özel ve / veya dikkatle kontrol edilen koşullar dışında] çünkü araba kazalarında ölen insanlardan sorumludurlar.” - Uhm. Bunu kesinlikle söyleyebiliriz. Ve birçok makul insan yapar.
Konrad Rudolph

1
Temelde diyorsunuz: Java'da geliştirilen bir uygulama hacklendi, bu yüzden Java'yı kullanmayı bırakmalıyız . Aşağı oylama yeterli ve geri kalanı için, size sağduyu öğretmek için burada değilim. @KonradRudolph
Billal Begueradj

2
@BillalBEGUERADJ Bu biraz yanlış bir denklik (hiçbir şey hacklemeden güvenli olmadığı için) ancak tamamen uzak değil: daha iyi alternatifler olduğu için dengede kullanılması gereken diller var; Örneğin, C'yi sistem programlama bağlamı dışında kullanıyorsanız, yanlış yapıyorsunuzdur. Neyse, cevabınızı downvote etmedi ama olan yanlış: Eğer iddia ettikleri gibi çünkü aksine, (diğer cevaplar göstermek gibi) Bob Martin söylediğini tam olarak ne olduğunu.
Konrad Rudolph

2

Martin'in problemi , doğrudan kullanıcı girdisinden dinamik SQL inşa eden programcıların olduğu gibi gözüküyor (affet beni, öncelikle bir C ve C ++ programcısıyım):

sprintf( query, "select foo from bar where %s;", user_input );

Bu kesinlikle mide ekşimesi için bir reçetedir (bu nedenle Bobby Tables şeridi). Bir üretim sisteminde böyle bir kod koyan herhangi bir programcı paddlin'i hak eder '.

Hazırlanan ifadeleri kullanarak ve girdilerinizi uygun şekilde temizleyerek sorunu hafifletebilir (tamamen ortadan kaldıramazsanız). SQL'i bir API'nin arkasına gizleyebilirsiniz, böylece programcılar doğrudan sorgu dizeleri oluşturmazlar, (Martin'in savunuculuğunun bir parçasıdır) çok daha iyidir.

Fakat tamamen SQL'den kurtulmak için bunun pratik ya da arzu edilebilir olduğunu sanmıyorum. İlişkisel modeller kullanışlıdır , bu yüzden ilk etapta var olurlar ve SQL muhtemelen ilişkisel modellerle çalışmak için en iyi arayüzdür.

Her zaman olduğu gibi, iş için doğru aracı kullanmak meselesi. Alışveriş sepeti uygulamanızın eksiksiz bir ilişkisel modele ihtiyacı yoksa, ilişkisel bir model kullanmayın (yani, SQL kullanmanıza gerek kalmayacak). İlişkisel bir modele ihtiyaç duyduğunuz zamanlarda, o zaman neredeyse kesinlikle SQL ile çalışacaksınız.


İken sprintf, SQL gerektirdiğini sanitizasyona tür içermiyor, özellikle bu amaç için tasarlanmış işlevler yapmak, ve çok güvenli. Örnek: Entity Framework'te SqlQuery .
Robert Harvey,

@RobertHarvey: Durumun böyle olduğunu varsayardım. Benim açımdan, çoğunlukla C ve C ++ 'da sunucu tarafı çalışmaları yapıyorum, bu yüzden hala ara sıra sprintf, dinamik SQL olan insanlara (neyse ki nadir) örnekler görüyorum .
John Bode,

1

Bağladığınız iki kaynak farklı mesajlar iletir:

Blog yazısı, veri erişim mantığının çalışma zamanında metin olarak olmaması gerektiğini, güvenilmeyen kullanıcı girişi ile karıştırılmaması gerektiğini söylüyor. Yani blog yazısı, dizeleri birleştirerek sorgu yazmayı kınadı.

Ders farklı. İlk fark tonda: Ders spekülasyon yapıyor ve soru soruyor, ama kınıyor. Veritabanlarının kötü olduğunu söylemiyor, ancak bir veritabanı olmadan kalıcılığı hayal etmemize meydan okuyor. İlişkisel veritabanlarının yaygınlaşmasından bu yana geçen 30 yıl boyunca birçok şeyin değiştiğini ve ısrarcı teknoloji seçimimizi makul bir şekilde etkileyebilecek iki olayı vurguladığını savunuyor:

  • Depolama alanı yaklaşık 1 milyon faktörü artırdı - karşılaştırılabilir fiyatlarla! Sonuç olarak, depolama alanını korumak için daha az, özellikle de silmek artık gerekli değildir. Salt okunur depolama kullanılarak, okuma kilitleri gerekli olmadığından eşzamanlılık denetimi basitleştirilebilir. Bu işlem ihtiyacını ortadan kaldırabilir.
  • erişim zamanları düşmüştür, çünkü çoğu veri kümesi artık RAM'e sığmaktadır ve bu da okuma gecikmesini büyük ölçüde azaltmaktadır.

Değişen bu koşullar optimal sebat teknolojisini değiştiriyor mu? İlginçtir ki, Bob Amca söylemez - muhtemelen tüm cevaplar için hiçbir programın doğru olmayacağını düşünüyor. Bu yüzden ısrarlı teknoloji seçimimizi taş tabletler içine almaktan ziyade ayrıntılarıyla ele almamız ve akranlarımıza bilgelik olarak aktarmamızı sağlıyor.

Alternatifler var mı?

Dizgi olmadan veri erişim mantığını yazmak tamamen mümkündür. Java ülkesinde, sorguların veritabanı şemanızdan oluşturulan güvenli bir akıcı API kullanarak tanımlandığı QueryDSL'yi kullanabilirsiniz . Böyle bir sorgu aşağıdaki gibi görünebilir:

JPAQuery<?> query = new JPAQuery<Void>(entityManager);
Customer bob = query.select(customer)
  .from(customer)
  .where(customer.firstName.eq("Bob"))
  .fetchOne();

Gördüğünüz gibi, sorgu mantığı, sorgunun güvenilir yapısını güvenilmeyen parametrelerden açıkça ayıran bir Dize olarak ifade edilmez (ve tabii ki, QueryDSL parametreleri asla sorgu metnine dahil etmez, ancak sorguyu ayırmak için hazırlanmış ifadeleri kullanır. JDBC seviyesindeki parametreleri için). QueryDSL ile SQL enjeksiyonunu elde etmek için, bir dizgeyi ayrıştırmak ve bir sözdizimi ağacına çevirmek için kendi çözümleyicinizi yazmanız gerekir ve bunu yapsanız bile, muhtemelen kötü şeyler için destek eklemeyeceksiniz select ... into file. Kısacası, QueryDSL, SQL enjeksiyonunu imkansız hale getirir ve ayrıca programcı verimliliğini arttırır ve yeniden yapılandırma güvenliğini arttırır. Çalışan tıkaçlar doğuracak kadar uzun süredir var olan web uygulama güvenliği için en büyük riski önledive geliştirici verimliliğini artırdı? Sorguları hala dizge olarak yazarsanız yanlış yaptığınızı söylemeye cesaret ediyorum.

İlişkisel veri tabanlarına alternatifler söz konusu olduğunda, postgres'in çok versiyonlu eşzamanlılık kontrolünün aynen böyle bir sadece son ek veri yapısının olduğunu düşünüyorum, belki de daha fazla etkinlik mağazalarını ve etkinlik kaynağını düşünüyor olsa da Bob Amca'nın hakkında konuştuğunu bilmek ilginçtir. desen de RAM'de mevcut durumunu tutma kavramı ile güzel uygun genel olarak.

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.