Veritabanları ve Fonksiyonel Programlama karışık mı?


122

Bir süredir web geliştiricisiyim ve son zamanlarda bazı işlevsel programlamayı öğrenmeye başladım. Diğerleri gibi, bu kavramların birçoğunu profesyonel çalışmalarıma uygulamakta bazı önemli sorunlar yaşadım. Benim için bunun birincil nedeni, FP'nin vatansız kalma hedefi arasında bir çelişki görmem, yaptığım çoğu web geliştirme çalışmasının, çok veri merkezli olan veritabanlarına büyük ölçüde bağlı olduğu gerçeğiyle oldukça çelişkili görünüyor.

Beni nesnelerin OOP tarafında çok daha üretken bir geliştirici yapan şey, .Net için MyGeneration d00dads, perl için Class :: DBI, Ruby için ActiveRecord, vb. Gibi nesne-ilişkisel haritacıların keşfi oldu. Bu, uzak durmama izin verdi. tüm gün ekleme ve seçme ifadeleri yazmaktan ve verilerle nesneler olarak kolayca çalışmaya odaklanmaktan. Tabii ki, güçlerine ihtiyaç duyulduğunda hala SQL sorguları yazabilirim, ancak aksi halde perde arkasında güzelce soyutlanmıştı.

Şimdi, işlevsel programlamaya dönersek, Bağlantılar gibi FP web çerçevelerinin çoğunda, bu örnekte olduğu gibi, çok sayıda standart sql kodu yazmayı gerektiriyor gibi görünüyor . Web kilitleri biraz daha iyi görünüyor, ancak verilerle çalışmak için bir çeşit OOP modeli kullanıyor gibi görünüyor ve yine de bu örnekte olduğu gibi veritabanınızdaki her tablo için kodun manuel olarak yazılmasını gerektiriyor . Sanırım bu eşleme işlevlerini yazmak için biraz kod üretme kullanıyorsunuz, ancak bu kesinlikle lisp gibi görünmüyor.

(Not Web Bloklarına veya Bağlantılara çok yakından bakmadım, nasıl kullanıldıklarını yanlış anlıyor olabilirim).

Öyleyse soru şu ki, web uygulamasının veritabanı erişim bölümleri (oldukça büyük olduğuna inanıyorum) veya bir sql veritabanıyla arayüz gerektiren diğer geliştirmeler için aşağıdaki yollardan birine zorlanmış görünüyoruz:

  1. Fonksiyonel Programlama Kullanmayın
  2. Verilere, çok sayıda SQL veya SQL benzeri kodu manuel olarak yazmayı içeren sinir bozucu, soyutlanmamış bir şekilde erişin ala Links
  3. İşlevsel Dilimizi sözde OOP paradigmasına zorlayın, böylece gerçek işlevsel programlamanın zarafetini ve kararlılığını ortadan kaldırın.

Açıkçası, bu seçeneklerden hiçbiri ideal görünmüyor. Bu sorunları aşmanın bir yolunu buldunuz mu? Burada gerçekten bir sorun mu var?

Not: Kişisel olarak en çok FP cephesindeki LISP'e aşinayım, bu nedenle herhangi bir örnek vermek ve birden fazla FP dili bilmek istiyorsanız, lisp muhtemelen tercih edilen dil olacaktır.

Not: Web geliştirmenin diğer yönlerine özgü sorunlar için bu soruya bakın .



4
ClojureQL ve HaskellDB'ye göz atın. İlişkisel cebir kullanan soyutlama katmanlarıdır.
Masse

10
Yanlış önermeyle başlıyorsunuz. İşlevsel programlama, durumu açıkça ve makul bir şekilde yönetmekle ilgilidir. Aslında veritabanları ile çok iyi çalışıyorlar.
Lucian

3
SQL, işlevsel programlama odaklı en başarılı dillerden biridir, doğasında herhangi bir zorluk olduğunu düşünmüyorum.
Douglas

3
# 2 ve # 3 yanlış bir ikilemdir. Ham SQL yazmak kaçınılması gereken bir şey değildir ve bir veritabanı üzerindeki soyutlamaların mutlaka OOP-esque olması gerekmez.
Dan Burton

Yanıtlar:


45

Öncelikle CLOS'un (Common Lisp Nesne Sistemi) "sözde-OO" olduğunu söyleyemem. Birinci sınıf OO'dur.

İkincisi, ihtiyaçlarınıza uyan paradigmayı kullanmanız gerektiğine inanıyorum.

Bir işlev veri akışı olduğunda ve gerçekten duruma ihtiyaç duymadığında verileri durumsuz olarak depolayamazsınız.

Karıştırılmış birkaç ihtiyacınız varsa, paradigmalarınızı karıştırın. Kendinizi araç kutunuzun yalnızca sağ alt köşesini kullanmakla sınırlamayın.


3
sadece eğlence için, daha devletsiz bir veritabanı olmaya çalışan veri günlüğünden bahsetmeyi düşündüm. "kullanıcı 1233 gönderisini beğenir" gibi tüm eylemleri kaydeder. Bu eylemler, veritabanının gerçek durumuna çözümlenir. İşin püf noktası, sorguların mutasyondan çok gerçekler olmasıdır ...
Chet

80

Buna bir veritabanı kişisinin bakış açısından baktığımda, ön uç geliştiricilerin nesneye yönelik veya işlevsel olmayan ancak ilişkisel ve kullanan veritabanlarını kullanmanın en etkili yollarını düşünmek yerine veritabanlarını modellerine uydurmanın yollarını bulmak için çok uğraştıklarını gördüm. set teorisi. Bunun genellikle kötü performans gösteren kodla sonuçlandığını gördüm. Dahası, performans ayarlaması zor olan kodlar oluşturur.

Veritabanı erişimi düşünüldüğünde, üç ana husus vardır - veri bütünlüğü (neden tüm iş kurallarının kullanıcı arayüzü üzerinden değil veritabanı düzeyinde zorunlu kılınması gerekir), performans ve güvenlik. SQL, ilk iki hususu herhangi bir ön uç dilden daha etkili bir şekilde yönetmek için yazılmıştır. Çünkü bunu yapmak için özel olarak tasarlandı. Bir veritabanının görevi, bir kullanıcı arayüzünün görevinden çok farklıdır. Görevi yönetmede en etkili olan kod türünün kavramsal olarak farklı olması şaşırtıcı mı?

Ve veritabanları, bir şirketin hayatta kalması için kritik olan bilgileri tutar. İşletmelerin hayatta kalmaları söz konusu olduğunda yeni yöntemler denemeye istekli olmaması şaşırtıcı mı? Pek çok işletme, mevcut veritabanlarının yeni sürümlerine yükseltme yapmak bile istemiyor. Dolayısıyla, veritabanı tasarımında içsel bir ihtiyatlılık vardır. Ve kasıtlı olarak bu şekilde.

Kullanıcı arayüzünüzü oluşturmak için T-SQL yazmaya veya veritabanı tasarım konseptlerini kullanmaya çalışmazdım, veritabanıma erişmek için neden arayüz dilinizi ve tasarım konseptlerinizi kullanmayı deneyesiniz? SQL'in yeterince süslü (veya yeni) olmadığını düşündüğünüz için mi? Yoksa onunla rahat hissetmiyor musun? En rahat hissettiğin modele uymayan bir şey, kötü ya da yanlış olduğu anlamına gelmez. Meşru bir nedenle farklı ve muhtemelen farklı olduğu anlamına gelir. Farklı bir görev için farklı bir araç kullanıyorsunuz.


"SQL, ilk iki hususu herhangi bir ön uç dilden daha etkili bir şekilde yönetmek için yazılmıştır." Gerçekten? Neden sonra, o SQL kısıtlamaları hala gibi şeyler yapamaz ki bu ?
Robin Green

Ancak bir tetikleyici olabilir, bu, tetikleyicilerin karmaşık kısıtlamalarla baş edebilmesinin ana amaçlarından biridir.
HLGEM

2
Son paragrafınızı baştaki paragraf olacak şekilde taşırdım. Çok paradigmalı bir yaklaşım olan (tek beden herkese uyan değil), diğerlerinin de teşvik ettiklerini yansıtan çok iyi bir nokta.
pestophagous

31

Ben Moseley ve Peter Marks'ın "Out of the Tar Pit" adlı makalesine bakmalısınız: "Out of the Tar Pit" (6 Şubat 2006)

Fonksiyonel-İlişkisel Programlama adı verilen bir programlama paradigmasını / sistemini detaylandıran modern bir klasiktir. Veritabanlarıyla doğrudan ilgili olmasa da, dış dünyayla (örneğin veritabanları) etkileşimlerin bir sistemin işlevsel çekirdeğinden nasıl izole edileceğini tartışır.

Makale ayrıca, uygulamanın iç durumunun ilişkisel bir cebir kullanılarak tanımlandığı ve değiştirildiği bir sistemin nasıl uygulanacağını tartışır, ki bu açıkça ilişkisel veritabanları ile ilgilidir.

Bu makale, veritabanları ile işlevsel programlamanın nasıl entegre edileceğine kesin bir cevap vermeyecek, ancak sorunu en aza indirecek bir sistem tasarlamanıza yardımcı olacaktır.


4
Ne harika bir makale. Verdiğiniz bağlantı koptu (geçici olarak?), Ancak makaleyi
shaffner.us/cs/papers/tarpit.pdf

2
@queque Orijinal bağlantı hala yok. Yeni bağlantıyı Kevin'in cevabına koydum.
David TONHOFER

25
  1. İşlevsel dillerin vatansız kalma hedefi yoktur, devlet yönetimini açık hale getirme hedefleri vardır. Örneğin Haskell'de Devlet monadını "normal" devletin kalbi olarak ve IO monadını programın dışında olması gereken bir devlet temsili olarak düşünebilirsiniz. Bu monad'lerin her ikisi de (a) durum bilgisi olan eylemleri açıkça temsil etmenize ve (b) referans olarak saydam araçlar kullanarak bunları oluşturarak durum bilgisi olan eylemler oluşturmanıza olanak tanır.

  2. Bir dizi ORM'ye atıfta bulunuyorsunuz, bunlar adlarına göre soyut veritabanları nesne kümeleri olarak. Doğrusu, ilişkisel bir veritabanındaki bilgilerin temsil ettiği şey bu değildir! İsmine göre ilişkisel verileri temsil eder. SQL, ilişkisel bir veri setindeki ilişkileri ele almak için bir cebirdir (dil) ve aslında oldukça "işlevsel" dir. Bunu, (a) ORM'lerin veritabanı bilgilerini haritalamanın tek yolu olmadığını, (b) SQL'in aslında bazı veritabanı tasarımları için oldukça güzel bir dil olduğunu ve (c) işlevsel dillerin genellikle ilişkisel cebire sahip olduğunu düşünmek için gündeme getiriyorum. SQL'in gücünü deyimsel (ve Haskell söz konusu olduğunda yazım denetimi yapılmış) bir biçimde ortaya çıkaran eşlemeler.

Çoğu lisp'in fakir bir adamın işlevsel dili olduğunu söyleyebilirim. Modern işlevsel uygulamalara göre tamamen kullanılabilir, ancak bunları gerektirmediğinden topluluğun bunları kullanma olasılığı daha düşüktür. Bu, oldukça yararlı olabilecek ancak saf işlevsel arayüzlerin hala veritabanlarını anlamlı bir şekilde nasıl kullanabildiğini kesinlikle belirsizleştiren bir yöntem karışımına yol açar.


15

Fp dillerinin devletsiz doğasının veritabanlarına bağlanmada bir sorun olduğunu düşünmüyorum. Lisp saf olmayan işlevsel bir programlama dilidir, bu nedenle durumla ilgili herhangi bir problemi olmamalıdır. Ve Haskell gibi saf işlevsel programlama dilleri, veri tabanlarını kullanmak için uygulanabilecek girdi ve çıktılarla başa çıkma yollarına sahiptir.

Sorunuzdan ana probleminiz, veritabanınızdan aldığınız kayıt tabanlı verileri çok fazla SQL yazmak zorunda kalmadan lisp-y (lisp-ish?) Olan bir şeye soyutlamanın iyi bir yolunu bulmak gibi görünüyor. kodu. Bu, dil paradigması ile ilgili bir sorundan çok araçlar / kitaplıklar ile ilgili bir sorun gibi görünüyor. Saf FP yapmak istiyorsanız belki lisp sizin için doğru dil değildir. Yaygın lisp, saf fp'den çok oo, fp ve diğer paradigmalardan gelen iyi fikirleri entegre etmekle ilgili görünüyor. Saf FP rotasına gitmek istiyorsanız, belki Erlang veya Haskell kullanmalısınız.

Lisp'deki 'sözde-oo' fikirlerin de hak sahibi olduğunu düşünüyorum. Onları denemek isteyebilirsiniz. Verilerinizle çalışmak istediğiniz şekilde uymazlarsa, verilerinizle istediğiniz şekilde çalışmanıza olanak tanıyan Weblock'ların üzerinde bir katman oluşturmayı deneyebilirsiniz. Bu, her şeyi kendiniz yazmaktan daha kolay olabilir.

Sorumluluk reddi: Lisp uzmanı değilim. Çoğunlukla programlama dilleriyle ilgileniyorum ve Lisp / CLOS, Scheme, Erlang, Python ve biraz Ruby ile oynuyorum. Günlük programlama hayatında hala C # kullanmak zorunda kalıyorum.


3
Erlang, kelimenin herhangi bir tanımına göre saf FP değildir. Örneğin smalltalk'taki nesneler gibi birbirine mesajlar gönderen (hepsi paralel çalışan) çok sayıda işlem oluşturarak erlang yazarsınız. Dolayısıyla, üst düzey bir perspektiften bakıldığında, bir şekilde OO-benzeri görünebilir ve kesinlikle durumu vardır. Yakınlaştırırsanız (bir işlemin içinde çalışan koda) daha işlevsel görünür, ancak istediğiniz herhangi bir yerden mesaj gönderebildiğiniz (ve dolayısıyla G / Ç vb. Yapabildiğiniz için) ve depolayabildiğiniz için hala tamamen işlevsel değildir. " küresel değişkenler "(süreç için küresel," süreç
diktesi

@Amadiro "kesinlikle devlet var". Tabii ki öyle. Hep devletimiz var. Sorun durum değil, değişebilir durumdur . "İşlevsel programlamanın" iyi bir kısmı, kırılgan durum temsillerinden kurtulmakla ilgilidir (örneğin, yaralanmaya hakaret eklemek için işlemsel olmayan bir şekilde onlara bir referans tutarken diğer süreçler tarafından değiştirilen nesne örnekleri). Erlang değişmez bir duruma sahiptir ve bu nedenle bu işlevsel programlama kriterlerine uygundur. Ve böylece: Ne türden olursa olsun veritabanları asla sorun değildir. Veritabanı güncellemeleri bir sorundur (ayrıca Prolog'daki kötü iddiaya da bakınız ).
David TONHOFER

15

Veritabanınız bilgileri yok etmezse, tüm veritabanının işlevlerinde bir değer olarak çalışarak "saf işlevsel" programlama değerleriyle tutarlı işlevsel bir şekilde çalışabilirsiniz.

T zamanında veritabanı "Bob'un Suzie'yi sevdiğini" belirtirse ve bir veritabanını ve beğeniyi kabul eden bir işleviniz varsa, o zaman veritabanını T zamanında kurtarabildiğiniz sürece, bir veritabanı içeren tamamen işlevsel bir programınız olur. . Örneğin

# Start: Time T
likes(db, "Bob")
=> "Suzie"
# Change who bob likes
...
likes(db "Bob")
=> "Alice"
# Recover the database from T
db = getDb(T)
likes(db, "Bob")
=> "Suzie"

Bunu yapmak için, kullanabileceğiniz bilgileri asla çöpe atamazsınız (ki bu pratikte bilgiyi atamazsınız), böylece depolama ihtiyaçlarınız monoton bir şekilde artacaktır. Ancak veritabanınızla, sonraki değerlerin işlemler yoluyla öncekilerle ilişkilendirildiği doğrusal bir dizi ayrı değerler olarak çalışmaya başlayabilirsiniz.

Örneğin, Datomic'in arkasındaki ana fikir budur .


Güzel. Datomic'i bilmiyordum bile. Ayrıca bakınız: Datomic için mantık .
David TONHOFER

12

Bir şey değil. Mnesia'nın belki de en erişilebilir örneği olduğu 'Fonksiyonel Veritabanları' olarak bilinen bir veritabanı türü vardır . Temel ilke, fonksiyonel programlamanın bildirime dayalı olmasıdır, bu nedenle optimize edilebilir. Kalıcı koleksiyonlarda Liste Anlamalarını kullanarak bir birleştirme uygulayabilirsiniz ve sorgu iyileştirici otomatik olarak disk erişiminin nasıl uygulanacağını hesaplayabilir.

Mnesia, Erlang dilinde yazılmıştır ve bu platform için en az bir web çerçevesi ( Erlyweb ) mevcuttur. Erlang doğası gereği paylaşılmayan bir iş parçacığı modeliyle paraleldir, bu nedenle belirli şekillerde ölçeklenebilir mimarilere katkıda bulunur.


1
Bunun bir çözüm olduğunu sanmıyorum. Nesneye yönelik veritabanları da vardır, ancak genellikle, düz ve eski bir ilişkisel SQL veritabanına bağlanmak istersiniz.
jalf

4
İşlevsel-SQL empedans uyumsuzluğuna çok benzer şekilde, OO dilleri ve veritabanları ile hala bir empedans uyumsuzluğunuz var.
ConcernedOfTunbridgeWells

1
@ConcernedOfTunbridgeWells Bu empedans uyumsuzluğunun, her şeyin çivi olmak için ihtiyacı olan çekiçli insanların hayal gücünün bir ürünü olduğunu keyfi olarak ifade edeceğim. Çok ince katmanlar ve SQL hakkında bilgi, zarif bir şekilde uzun bir yol kat edebilir, dolayısıyla jOOQ ve benzeri şimler.
David TONHOFER

6

Bir veritabanı, durum bilgisiz bir API'de durumu takip etmenin mükemmel bir yoludur. REST'e abone olursanız, hedefiniz bir veri deposu (veya başka bir arka uç) ile etkileşime giren, durum bilgilerini şeffaf bir şekilde takip eden, müşterinizin bunu yapmasına gerek kalmayan durumsuz kod yazmaktır.

Bir veritabanı kaydını bir nesne olarak içe aktardığınız ve sonra değiştirdiğiniz bir Nesne-İlişkisel Eşleştirici fikri, nesne yönelimli programlama kadar işlevsel programlama için de uygulanabilir ve kullanışlıdır. Bir uyarı, işlevsel programlamanın nesneyi yerinde değiştirmemesidir , ancak veritabanı API'si kaydı yerinde değiştirmenize izin verebilir . Müşterinizin kontrol akışı şuna benzer:

  • Kaydı bir nesne olarak içe aktarın (veritabanı API'si kaydı bu noktada kilitleyebilir),
  • Nesne ve şubeyi içeriğine göre istediğiniz gibi okuyun,
  • İstediğiniz değişikliklerle yeni bir nesneyi paketleyin,
  • Veritabanındaki kaydı güncelleyen uygun API çağrısına yeni nesneyi iletin.

Veritabanı, kaydı değişikliklerinizle güncelleyecektir. Saf işlevsel programlama , programınız kapsamında değişkenlerin yeniden atanmasına izin vermeyebilir, ancak veritabanı API'niz yine de yerinde güncellemelere izin verebilir.


5

Haskell ile çok rahatım. En önemli Haskell web çerçevesi (Rails ve Django ile karşılaştırılabilir) Yesod olarak adlandırılır. Oldukça havalı, tür açısından güvenli, çoklu arka uç ORM'si var gibi görünüyor. Kitaplarındaki Persistance bölümüne bir göz atın .


0

Veritabanları ve Fonksiyonel Programlama birleştirilebilir.

Örneğin:

Clojure, ilişkisel veritabanı teorisine dayanan işlevsel bir programlama dilidir.

               Clojure -> DBMS, Super Foxpro
                   STM -> TransactionMVCC
Persistent Collections -> db, table, col
              hash-map -> indexed data
                 Watch -> trigger, log
                  Spec -> constraint
              Core API -> SQL, Built-in function
              function -> Stored Procedure
             Meta Data -> System Table

Not: En son spec2'de, spec daha çok RMDB'ye benzer. bkz: spec-alpha2 wiki: Schema-and-select

Savunuyorum: NoSQL ve RMDB avantajlarının bir kombinasyonunu elde etmek için karma haritanın üstüne ilişkisel bir veri modeli oluşturmak. Bu aslında posgtresql'nin ters bir uygulamasıdır.

Ördek Yazma: Ördeğe benziyorsa ve ördek gibi şarlatansa ördek olmalı.

Clojure'un bir RMDB gibi veri modeli, clojure'ın RMDB gibi tesisleri ve clojure'un bir RMDB gibi veri manipülasyonu ise, clojure bir RMDB olmalıdır.

Clojure, ilişkisel veritabanı teorisine dayanan işlevsel bir programlama dilidir

Her şey RMDB

Karma haritaya (NoSQL) dayalı ilişkisel veri modeli ve programlamayı uygulayın

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.