Veritabanı soyutlama - abartılı mı?


18

Çok sayıda veritabanı soyutlama katmanına maruz kaldıktan sonra, verilere erişmek için kendi farklı paradigmalarını icat eden her kütüphanenin amacının ne olduğunu merak etmeye başlıyorum. Yeni bir DAL seçmek, tekrar tekrar yeni bir dil öğrenmek gibi geliyor, genellikle tek yapmak istediğim, katmanı kafamda zaten yazdığım bir SQL sorgusu çıkarmaya ikna etmek olduğunda.

Ve bu gerçeğin ardından okunabilirliğe bile dokunmadan:

# Exhibit A:  A typical DAL
rows = db(db.ips_x_users.ip_addr == '127.0.0.1')
    .inner_join(db.ips_x_users.user_id == db.users.id)
    .select(order=(db.ips_x_users.last_seen, 'desc'), limit=10)

# Exhibit B:  Another typical DAL
rows = db.ips_x_users
    .join(db.users, on=db.ips_x_users.user_id == db.users.id)
    .filter(db.ips_x_users.ip_addr == '127.0.0.1')
    .select(sort=~db.ips_x_users, limit=10)

# Exhibit C:  A hypothetical DAL based on standard SQL syntax
rows = db('''SELECT * FROM ips_x_users
             INNER JOIN users ON
                 (ips_x_users.user_id = users.id)
             WHERE ips_x_users.ip_addr = ip
             ORDER BY last_seen DESC LIMIT 10''', ip='127.0.0.1')

Standart SQL sözdiziminde sorun nedir? Belirli bir amaç için yaratıldı ve bu amaca güzelce uyuyor. Belki de sadece benim, ama snippet C'yi ilk ikisinden çok daha kolay anlıyorum. Yeniden adlandırılan anahtar kelimeler ve sözdizimi hileleri sevimli, ancak IMO, hemen aşağı geldiğinde, kodlayıcı için satırları almayı daha kolay hale getirmiyor.

Bu muhtemelen uzun bir rant gibi görünüyordu, ama orada olduğunu burada bir gerçek soru. Her DAL, denenmiş ve doğru SQL'i ayrıştırmak yerine sorgular için yeni bir DSL icat ettiğinden, farklı sözdizimi kullanmanın yararları veya standart SQL sözdizimindeki eksiklerin orada olduğunu bilmemem gerekir. Birisi buraya baktığımı söyleyebilir mi?


2
Standart SQL ile ilgili en büyük sorun, veritabanına özgü bir dizi sorgu olmasıdır. Dış birleştirme sözdizimi ve "pencereli" bir sorgu alma işlemi çılgınca değişir. Bu, DAL'lerin başlaması için ihtiyaçtır. Şimdi, DAL tarafından kullanılan ve çeşitli SQL satıcılarının deyimiyle nasıl başa çıkılacağını bilen standart bir SQL varyantı varsa, bunu memnuniyetle karşılarım.
Berin Loritsch

Yanıtlar:


10

Ortak SQL kullanımının en temel sorunu, SQL sorgularının bir şekilde başka bir dilden oluşan dizeler olmasıdır. SQL enjeksiyonlarının ve diğer güvenlik açıklarının ve WTF'lerin geldiği yer burasıdır (örneğin, sorgunuzda herhangi bir parametre bulunmadığından örneğiniz oldukça zayıf seçilmiştir).

Sonraki sorun aslında bir sonuçtur: Eğer kodunuzda yazılı bir SQL varsa, derleyici bu konuda hiçbir şey yapamaz. Sütun adlarındaki yazım hataları gibi hatalar yalnızca çalışma zamanında ortaya çıkar. Temel olarak, sorgunuzun kaynak kodunuzda yalnızca dize olarak temsil edilmesini istemiyorsunuz, ancak derleyicinin tüm facepalm hatalarının% 95'ini önlemek için statik olarak analiz edebileceği bir şey.

Ve son sorun, ilişkisel bir veritabanını dil semantiğinize ve programlama modelinize eşleştirmeye çalıştığınızda oluşur: RDBMS'ler OOP (veya gezinti verisi alımı) ile birlikte iyi gitmez. Aslında, bu ikisini birleştiren oldukça korkunç bir fikir, ancak SQL veritabanları (yani ORM'ler) için tüm nesne yönelimli DAL budur. Ancak tüm bu soyutlama katmanları sızıntıya mahkemmdur. Bence bu yüzden bu kadar çok şey var: Onlarla çalıştığınız için, kusurlu olduklarını görüyorsunuz, bunu doğru yapan ve sonuçta başarısız olan bir DAL yazmaya başladınız.

Bu nedenle, bir ve iki problemler SQL'den kurtulmak için DAL'lere sahip olmayı önermekle birlikte, üçüncü problem, bir tane (en azından OOP için) için doğrudan bir çözüm olmadığı anlamına gelir ve bu nedenle her zaman farklı güçlü ve kısıtlı bir DAL denizi olacaktır. Sonunda, yapabileceğiniz tek şey dikkatlice birkaçını seçmek ve onlara bağlı kalmaktır.


3
"RDBMS'ler OOP ile birlikte iyi gitmiyor" - Yazılımdaki her şey OO olmalı mı?
quant_dev

@quant_dev: Hayır. Ancak 'soyutlama' katmanları doğal olarak en azından 'soyutlamaya yöneliktir'. Ayrıca sağlanan kod parçacıkları, OO kodundan bahsettiğimizi göstermektedir.
back2dos

Ben her zaman SQL içine C ya da sadece akla gelebilecek en aptalca şey gömülü olduğunu düşündüm. Böyle bir şey yapmak zorunda kaldığında, tablolar arasındaki ilişkileri tanımlamak ve bunu bir veritabanında saklamak ve sonra veritabanıyla konuşmak için çalışma zamanında SQL oluşturmak için buradaki ilişkileri kullanmak için bir araç oluşturdum. C kodum şöyleydi: "Bu anahtarı kullanarak bu varlığı bul", "Değişiklikleri kaydet".

9

Tüm veritabanı platformlarının aynı SQL sözdizimini kabul etmediği açıktır, bu nedenle SQL deyimlerini uygulamanıza gömmek her veritabanı platformu için çalışmaz. Birden fazla veritabanı platformunu desteklemeniz gerekiyorsa, bu SQL ifadelerinin çoğunu (hepsi değilse de) yeniden düşünmeniz gerekecektir.


3
@Note - Ama sonra DAL'ın tam bir SQL ayrıştırıcısına sahip olması ve herhangi bir veritabanından farklı olacak kendi desteklenen lehçesine sahip olması gerekir. Ve sonra, uygun bir veritabanına özgü SQL ifadesi üretmenin tüm karmaşıklığına sahip olacaktı. Örneğin, örneğinizdeki LIMIT anahtar sözcüğü MySQL için geçerlidir ancak Oracle veya SQL Server için geçerli değildir.
Justin Cave

2
Şimdi sorunun etine ulaşıyoruz. Standart dışı bir yöntem adı ve operatör aşırı yüklenmesini, standart olmayan bir SQL lehçesinden daha üstün kılan nedir? SQL kullanmak en azından kodlayıcıya çerçeveyi öğrenmeye başlamak için tanıdık bir temel sağlayacaktır.
Kendine not - bir isim düşün

3
@Not to self: muhtemelen akıcı bir tarzda API yazmak, SQL'in bazı lehçelerinde bir SQL ayrıştırıcı yazmak ve daha sonra SQL'in diğer bazı lehçelerine çevirmekten daha kolaydır.
Dean Harding

1
Kayıt için ayrıca "yerli" SQL kullanmayı tercih ediyorum. Projelerimin çoğunun birden fazla veritabanını desteklemesi hiç gerekmedi, bu yüzden benim için hiçbir zaman sorun olmadı.
Dean Harding

3
"Tüm veritabanı platformlarının aynı SQL sözdizimini kabul etmediği gerçeğini gözden kaçırıyorsunuz" - evet, ama herhangi bir veritabanında çalıştırılacak kodu ne sıklıkla yazıyorsunuz ? Genellikle bir DB platformu önemli bir yatırımdır ve sıklıkla değiştirilmez. Ayrıca, sorgularınızı bilinen bir veritabanı türüne göre optimize etmekten önemli verimlilik kazanımları elde edilebilir.
quant_dev

5

SQL 10 yıl önce işaretçiler aynı büyük değişiklik yaşıyor gibi hissediyorum. SQL ile manuel işi ortadan kaldırmak ve daha yüksek bir soyutlama düzeyine çıkarmak için sürekli bir girişim vardır. Aynı şey yıllar önce işaretçiler ve manuel bellek yönetimi için de oldu.

Çalışma şu anda devam ettiği için önerilen, denenmiş, terk edilmiş ve entegre edilmiş birçok farklı yaklaşımı görmekten zevk alıyorsunuz. Eminim, kendini ortaya çıkarmak istiyorsanız, ortak bir yaklaşımdan veya bir endüstri standardından önce daha fazlasını göreceğiz.

Veri erişim kodunu aynı düzeyde ve uygulama kodunuzla çalışırken uyguladığınız aynı paradigma ile değiştirebildiğinizde kesinlikle bir avantaj sağlar.

Birkaç kelimeyle - basitleştirme, çeviklik, hızlılık, bunlar hedeflerdir.


4

Joel güzel bir yazı yazmıştı 10 yıl önce: Mimari Astronotların Sizi Korkutmasına İzin Verme

Bence durum böyledir. Bir desen bulduğumdan beri kendi uygulamalarımda soyutlama katmanı kullanıyordum ve bu şekilde yapmam kolaydı. Ama benim DAL'ımdı kaynak kodundaki her satırı biliyordum => tam kontrol. Ancak bu çerçeveyi ekibim / projelerim dışında kimseye kullanmanızı önermem.

Böyle bir şey kullandığınızda, nasıl uygulandığını bilmek önemlidir, yani kütüphane / aracı öğrenmek için çok zaman harcamanız gerekir. Öğrenmek için zamanınız yoksa - kullanmayın. En başından beri çok kolay görünse bile.


Evet, geçmişte çalıştığım bir şirket Hibernate'i coşkuyla kullanmaya başladı. Daha sonra, çerçeve tarafından oluşturulan sorguların ne kadar şaşırtıcı (garip bir şekilde) olabileceğini keşfettiler.
quant_dev

@quant_dev Evet, bu tuzak - Hibernate veya JPA ile basit şeyler yapmaya başlamak kolaydır.
m5ba
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.