Базы данных и функциональное программирование расходятся? - PullRequest
112 голосов
/ 01 декабря 2008

Я был веб-разработчиком в течение некоторого времени, и недавно начал изучать некоторое функциональное программирование. Как и у других, у меня были серьезные проблемы с применением многих из этих концепций в моей профессиональной деятельности. Для меня основная причина этого заключается в том, что я вижу, что конфликт между целью FP оставаться без гражданства кажется совершенно не соответствующим тому факту, что большая часть работы по веб-разработке, которую я выполнял, была тесно связана с базами данных, которые очень ориентированы на данные.

Одна вещь, которая сделала меня гораздо более продуктивным разработчиком на стороне ООП, это открытие объектно-реляционных картографов, таких как MyGeneration d00dads для .Net, Class :: DBI для perl, ActiveRecord для ruby ​​и т. Д. Это позволило мне держаться подальше от написания вставки и выбора операторов в течение всего дня, а также сосредоточиться на работе с данными как объектами. Конечно, я все еще мог писать SQL-запросы, когда требовалась их мощь, но в остальном это было просто закулисно.

Теперь, обращаясь к функциональному программированию, кажется, что для многих веб-фреймворков FP, таких как Links, требуется написать много шаблонного SQL-кода, как в в этом примере . Кажется, что веб-блокировки немного лучше, но, похоже, для работы с данными используется модель ООП, и все же требуется, чтобы код вручную записывался для каждой таблицы в вашей базе данных, как в в этом примере . Я предполагаю, что вы используете некоторую генерацию кода для написания этих функций отображения, но это явно не похоже на шутку.

(обратите внимание, я не очень внимательно смотрел на веб-блоки или ссылки, возможно, я просто неправильно понял, как они используются).

Таким образом, вопрос заключается в том, что для частей доступа к базе данных (которые я считаю довольно большими) веб-приложения или для другой разработки, требующей интерфейса с базой данных SQL, мы, кажется, вынуждены пойти по одному из следующих путей:

  1. Не использовать функциональное программирование
  2. Доступ к данным надоедливым, не отвлеченным образом, который включает в себя ручную запись большого количества SQL или SQL-подобного кода. Ссылки
  3. Внедрите наш функциональный язык в псевдо-ООП-парадигму, тем самым устраняя некоторую элегантность и стабильность настоящего функционального программирования.

Очевидно, что ни один из этих вариантов не кажется идеальным. Нашел ли способ обойти эти проблемы? Здесь действительно есть проблема?

Примечание: лично мне больше всего знакомы с LISP на фронте FP, поэтому, если вы хотите привести примеры и знать несколько языков FP, lisp, вероятно, будет предпочтительным языком выбора

PS: по вопросам, связанным с другими аспектами веб-разработки, см. этот вопрос .

Ответы [ 10 ]

78 голосов
/ 01 декабря 2008

Обращаясь к этому с точки зрения специалиста по базам данных, я обнаружил, что разработчики внешних интерфейсов слишком стараются найти способы привести базы данных в соответствие со своей моделью, а не рассматривают наиболее эффективные способы использования баз данных, которые не являются объектно-ориентированными или функциональными, но реляционная и использующая теорию множеств. Я видел это, как правило, приводит к плохой производительности кода. Кроме того, он создает код, который сложно настроить.

При рассмотрении доступа к базе данных существует три основных соображения - целостность данных (почему все бизнес-правила должны применяться на уровне базы данных, а не через пользовательский интерфейс), производительность и безопасность. SQL написан для более эффективного управления первыми двумя соображениями, чем любой язык интерфейса. Потому что он специально разработан для этого. Задача базы данных сильно отличается от задачи интерфейса пользователя. Стоит ли удивляться, что тип кода, который наиболее эффективен в управлении задачей, концептуально отличается?

А базы данных содержат информацию, необходимую для выживания компании. Не удивительно, что компании не хотят экспериментировать с новыми методами, когда их выживание поставлено на карту. Черт возьми, многие компании не хотят даже переходить на новые версии своей существующей базы данных. Так что в дизайне баз данных заложен консерватизм. И это намеренно так.

Я бы не стал писать T-SQL или использовать концепции дизайна базы данных для создания вашего пользовательского интерфейса. Почему вы пытаетесь использовать язык интерфейса и концепции дизайна для доступа к моей базе данных? Потому что вы думаете, что SQL не достаточно (или новый) недостаточно? Или вам не комфортно с этим? То, что что-то не соответствует модели, с которой вы чувствуете себя наиболее комфортно, не означает, что это плохо или неправильно. Это означает, что он отличается и, вероятно, отличается по законной причине. Вы используете другой инструмент для другой задачи.

44 голосов
/ 01 декабря 2008

Прежде всего, я бы не сказал, что CLOS (Common Lisp Object System) является "псевдо-OO". Это первый класс ОО.

Во-вторых, я считаю, что вы должны использовать парадигму, которая соответствует вашим потребностям.

Вы не можете хранить данные без сохранения состояния, пока функция является потоком данных и в действительности не нуждается в состоянии.

Если у вас есть несколько смешанных потребностей, смешайте свои парадигмы. Не ограничивайте себя использованием только правого нижнего угла панели инструментов.

29 голосов
/ 08 мая 2012

Вам следует взглянуть на статью Бена Мозли и Питера Маркса «Из смоляной ямы», доступную здесь: «Из смоляной ямы» (6 февраля 2006 г.)

Это современная классика, в которой подробно описывается парадигма / система программирования, называемая функционально-реляционным программированием. Хотя это не имеет прямого отношения к базам данных, в нем обсуждается, как изолировать взаимодействия с внешним миром (например, базы данных) от функционального ядра системы.

В статье также обсуждается, как реализовать систему, в которой внутреннее состояние приложения определяется и модифицируется с использованием реляционной алгебры, которая, очевидно, связана с реляционными базами данных.

В этом документе не будет дан точный ответ о том, как интегрировать базы данных и функциональное программирование, но он поможет вам спроектировать систему, чтобы минимизировать проблему.

23 голосов
/ 08 мая 2012
  1. Функциональные языки не имеют целью оставаться без гражданства, они имеют целью сделать управление состоянием явным. Например, в Haskell вы можете рассматривать монаду State как сердце «нормального» состояния, а монаду IO - представление состояния, которое должно существовать вне программы. Обе эти монады позволяют вам (а) явно представлять действия с состоянием и (б) создавать действия с состоянием, составляя их с помощью ссылочно-прозрачных инструментов.

  2. Вы ссылаетесь на ряд ORM, которые по своему названию абстрагируют базы данных как наборы объектов. Правда, это не то, что представляет информация в реляционной базе данных! По своему названию он представляет реляционные данные. SQL - это алгебра (язык) для обработки отношений в реляционном наборе данных, и на самом деле она сама по себе довольно «функциональна». Я поднял этот вопрос, чтобы учесть, что (а) ORM не являются единственным способом отображения информации базы данных, (б) что SQL на самом деле является довольно хорошим языком для некоторых конструкций баз данных, и (в) функциональные языки часто имеют реляционную алгебру отображения, раскрывающие мощь SQL идиоматическим (и в случае с Haskell, проверенным типом) способом.

Я бы сказал, что большинство болтов - это функциональный язык бедняка. Он полностью пригоден для использования в соответствии с современными функциональными практиками, но поскольку он не требует их, сообщество с меньшей вероятностью будет их использовать. Это приводит к сочетанию методов, которые могут быть очень полезны, но, безусловно, затеняют то, как чисто функциональные интерфейсы могут все еще использовать базы данных осмысленно.

14 голосов
/ 08 мая 2012

Если ваша база данных не уничтожает информацию, то вы можете работать с ней функциональным образом, совместимым с «чисто функциональными» значениями программирования, работая с функциями всей базы данных как значения.

Если в момент времени T база данных гласит, что «Боб любит Сьюзи», и у вас была функция like, которая приняла базу данных и аналог, тогда, пока вы можете восстановить базу данных в момент T, у вас есть чисто функциональная программа, которая включает в себя базу данных. например,

# 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"

Для этого вы никогда не сможете выбросить информацию, которую можете использовать (что практически означает, что вы не можете выбросить информацию), поэтому ваши потребности в хранилище будут монотонно возрастать. Но вы можете начать работать с вашей базой данных как линейный ряд дискретных значений, где последующие значения связаны с предыдущими через транзакции.

Это основная идея Datomic , например.

14 голосов
/ 01 декабря 2008

Я не думаю, что природа языков fp без состояния - это проблема с подключением к базам данных. Лисп - это не чистый функциональный язык программирования, поэтому у него не должно быть проблем с состоянием. А чисто функциональные языки программирования, такие как Haskell, имеют способы обработки ввода и вывода, которые можно применять к базам данных.

Из вашего вопроса кажется, что ваша основная проблема заключается в поиске хорошего способа абстрагирования основанных на записях данных, которые вы возвращаете из базы данных, в нечто, похожее на lisp-y (lisp-ish?), Без необходимости писать много кода SQL. Это больше похоже на проблему с инструментами / библиотеками, чем на проблему с языковой парадигмой. Если вы хотите использовать чистый FP, возможно, lisp не подходит для вас. Обычный шутник больше похож на интеграцию хороших идей из oo, fp и других парадигм, чем на чистый fp. Возможно, вам следует использовать Erlang или Haskell, если вы хотите пойти по чистой трассе FP.

Я думаю, что «псевдо-оо» идеи в lisp тоже имеют свои достоинства. Вы можете попробовать их. Если они не соответствуют тому, как вы хотите работать с вашими данными, вы можете попробовать создать слой поверх Weblocks, который позволит вам работать с вашими данными так, как вы хотите. Это может быть проще, чем писать все самостоятельно.

Отказ от ответственности: я не эксперт по Лиспу. Я в основном интересуюсь языками программирования и играю с Lisp / CLOS, Scheme, Erlang, Python и немного Ruby. В повседневной жизни программиста я все еще вынужден использовать C #.

12 голосов
/ 01 декабря 2008

Совсем нет. Существует жанр баз данных, известных как «Функциональные базы данных», из которых Mnesia является, пожалуй, наиболее доступным примером. Основной принцип заключается в том, что функциональное программирование декларативно, поэтому его можно оптимизировать. Вы можете реализовать объединение с помощью Списки для постоянных коллекций, а оптимизатор запросов может автоматически определить, как реализовать доступ к диску.

Mnesia написана на Erlang , и для этой платформы доступен хотя бы один веб-фреймворк ( Erlyweb ). Erlang по своей природе параллелен модели потоков без разделения ресурсов, поэтому в определенных отношениях он поддается масштабируемым архитектурам.

6 голосов
/ 29 августа 2015

База данных - это идеальный способ отслеживать состояние в API без сохранения состояния. Если вы подписаны на REST, то ваша цель - написать код без сохранения состояния, который взаимодействует с хранилищем данных (или каким-либо другим бэкэндом), который прозрачным образом отслеживает информацию о состоянии, так что вашему клиенту это не нужно.

Идея объектно-реляционного сопоставления, где вы импортируете запись базы данных как объект, а затем модифицируете ее, так же применима и полезна для функционального программирования, как и для объектно-ориентированного программирования. Единственное предостережение в том, что функциональное программирование не изменяет объект на месте, но API базы данных может позволить вам изменить запись на месте. Поток управления вашего клиента будет выглядеть примерно так:

  • Импортировать запись как объект (API базы данных может заблокировать запись на этом этапе),
  • Читайте объект и ветвь на основе его содержимого, как вам нравится,
  • Пакет нового объекта с желаемыми модификациями,
  • Передать новый объект соответствующему вызову API, который обновляет запись в базе данных.

База данных обновит запись с вашими изменениями. Чистое функциональное программирование может запретить переназначение переменных в рамках вашей программы , но API вашей базы данных все еще может разрешать обновления на месте.

6 голосов
/ 08 мая 2012

Мне наиболее комфортно с Хаскеллом. Самый известный веб-фреймворк на Haskell (сравнимый с Rails и Django) называется Yesod. Кажется, у него есть довольно крутая, безопасная для типов, мульти-бэкэнд ORM. Взгляните на главу Сопротивление в своей книге.

0 голосов
/ 11 мая 2019

Базы данных и функциональное программирование могут быть объединены.

например:

Clojure - это функциональный язык программирования, основанный на теории реляционных баз данных.

               Clojure -> DBMS, Super Foxpro
                   STM -> Transaction,MVCC
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

Примечание. В последней спецификации spec2 спецификация больше похожа на RMDB. см .: spec-alpha2 wiki: Схема и выбор

Я защищаю: построение реляционной модели данных поверх хэш-карты для достижения сочетания преимуществ NoSQL и RMDB. На самом деле это обратная реализация posgtresql.

Duck Typing: Если это похоже на утку и крякает как утка, значит, это утка.

Если модель данных clojure, такая как RMDB, средства clojure, такие как RMDB, и манипулирование данными clojure, такие как RMDB, clojure должен быть RMDB. Clojure - это функциональный язык программирования, основанный на теории реляционных баз данных

Все RMDB

Реализация реляционной модели данных и программирования на основе хэш-карты (NoSQL)

...