it-roy-ru.com

Базы данных и функциональное программирование расходятся?

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

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

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

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

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

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

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

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

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

112
Tristan Havelick

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

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

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

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

43
Svante

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

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

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

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

78
HLGEM

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

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

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

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

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

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

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

23
J. Abrahamson

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

Если в момент времени 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
animal

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

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

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

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

14
Mendelt

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

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

12
ConcernedOfTunbridgeWells

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

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

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

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

6
Fried Brice

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

6
Honza Pokorny

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

например:

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: Schema-and-select

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

Печатание утки: Если это похоже на утку и крякает как утка, это должна быть утка.

Если модель данных clojure, такая как RMDB, средства clojure, такие как RMDB, и манипулирование данными clojure, такие как RMDB, clojure должен быть RMDB.

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

все RMDB

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

0
Lin Pengcheng