Datomic

Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 16:18, 24 декабря 2017.
Datomic
Datomic Logo.png
Создатели: Рич Хики, Стюарт Хэллоуэй, Джастин Гетланд
Выпущена: 2012; 9 years ago (2012)
Написана на: Clojure, Java
Лицензия: Проприетарное программное обеспечениe
Веб-сайт www.datomic.com

Datomic - это распределенная база данных, предназначенная для создания масштабируемых, гибких и интеллектуальных приложений, работающих на облачных архитектурах нового поколения. Это новый вид СУБД, который включает в себя его идеи о том, как работают сегодняшние базы данных с поддержкой транзакций ACID и JOIN.

Основные аспекты, вокруг которых вращается технология Datomic:[Источник 1]

  • Новая архитектура. Peers, Apps и Transator;
  • Фактическая модель данных;
  • Мощный, декларативный язык запросов - "Datlog".

Команда Datonic заинтересована в том, чтобы её СУБД обеспечила первую, "реальную" реализацию записи: записи в компьютерах сохраняли информацию о прошлом, в то время как в сегодняшних базах старые данные переписываются новым. Datonic изменяет, сохраняет и дифференцирует информацию, делая время неотъемлемой частью системы.


Реконструкция базы данных

Подавляющее большинство баз данных сегодня отражают проекты десятилетия прошлого, когда память и диски были очень маленькими и очень дорогими. Теперь они в миллион раз более емкие и дешевые. Самое главное, базы данных прошлого были определены с точки зрения обновления мест, в целях экономии дискового пространства и памяти.

Традиционная база данных

Традиционные базы данных (и многие новые!) сосредоточены на «сейчас» - множество фактов в настоящее время, но при этом они теряют информацию. Предприятия находят растущую ценность в исторической информации, и есть очень мало причин не сохранять ее. Это не просто вопрос сохранения истории, как с резервными копиями или журналами, но делает ее доступной для поддержки активного процесса принятия решений. Для бизнеса необходимо знать свой текущий адрес, чтобы отправить что-то, но «какие клиенты часто перемещаются и откуда?» могут быть очень интересны для их групп по маркетингу или разработке продукта. Они не хотят восстанавливать резервные копии или воспроизводить журналы, чтобы это выяснить.

Традиционная архитектура

В традиционные базы данных включены следующие компоненты:

  • Координация;
  • Консистенция;
  • Индексация;
  • Хранение;
  • Запросы;

Обновление на месте, даже если оно реализовано с использованием методов только для добавления, приводит к совместному размещению этих служб. Традиционный сервер СУБД отвечает за все это и часто становится хрупким, трудно масштабируемым компонентом архитектуры приложения. В некоторых распределенных архитектурах используются осколки или другие методы, позволяющие разделить данные. Разрушение этих сервисов - это именно то, что необходимо для создания более гибких архитектур и новых возможностей.

Существует несколько общих преимуществ независимости:

  • способность перемещать подсистемы;
  • способность отдельных служб заботиться о части работы;
  • упрощение системных компонентов.

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

Архитектура Datomic

Datomic делит традиционную модель на независимые роли:

Peers

Компонент peer - это библиотека, которая внедряется в приложения.

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

Clients

Библиотека клиентов может использоваться для подключения легких процессов к Datomic.

  • Отправляет транзакции и запросы к серверу Peer.
  • Поддерживает все возможности запросов, доступные для Peer.
  • Не берет на себя никакой издержки на память полной библиотеки Peer, не выполняет локальное кэширование в рамках легкого процесса.
  • Может поддерживать языки, не поддерживающие JVM.

Peer Server

Peer Server - это процесс JVM, который предоставляет интерфейс для библиотеки Datomic Client.

  • Принимает запросы и транзакции от Datomic Clients.
  • Отправляет транзакции и принимает изменения от транзакции.
  • Предоставляет доступ к данным, кеширование и запрос к подключенным Клиентам, чтение из службы хранения по мере необходимости.

Transactors

  • Принимать транзакции.
  • Обработать их серийно
  • Перенести результаты в службу хранения.
  • Все записи синхронизируются с избыточным хранилищем.
  • Передавать изменения Peers.
  • Индекс в фоновом режиме, указание индексов в службе хранения.

Storage services

  • Обеспечить интерфейс для высоконадежного резервного хранилища.
  • Доступно от сторонних производителей (например, Amazon DynamoDB является поддерживаемой службой хранения).
Архитектура Datonic

Структура и представление

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

У Datom есть следующие компоненты:

  • Сущность;
  • Атрибут;
  • Стоимость;
  • Транзакция (время базы данных);
  • Добавить/Убрать;

Это представление имеет очевидное сходство с моделью данных субъекта / предиката / объекта операторов RDF. Однако, без временного представления или правильного представления ретракции, заявления RDF недостаточно для представления информации. Datom является минимальным и достаточным представлением факта.

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

Schemas

Все базы данных имеют схемы. Единственные различия в том, насколько они поддерживают (или требуют) схемы, являющиеся явными. В случае Datomic атрибуты должны быть определены до их использования.

Атрибуты - это сущности:

  • имя;
  • тип данных значений
  • уникальность
  • свойства индексирования

Нет ограничений на атрибуты, которые могут быть применены к объектам, поэтому сущности открыты и разрежены. Атрибуты могут быть разделены между сущностями, а пространства имен могут использоваться для предотвращения коллизий. Далее указывается

:person/name

атрибут:

{:db/ident       :person/name,
 :db/valueType   :db.type/string,
 :db/cardinality :db.cardinality/one,
 :db/doc         "A person's name"}

Схема, как и всякое взаимодействие с Datomic, представлена ​​данными, причем приведенное выше является представлением карты в формате edn. DDL отсутствует.

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

Операции

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

[[:db/add entity-id attribute value]
 [:db/add entity-id attribute value]...]

Все взаимодействие с Datomic представлено данными, причем приведенное выше является представлением списка списков в формате edn , каждый внутренний список, представляющий дату в

[op entity attribute value]

Транзакции - это обычные структуры данных (iejuLists, juMaps, массивы и т.д.), которые можно создать на своем языке. Первичным интерфейсом Datomic являются данные, а не строки и не DML.

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

Не каждое преобразование может быть выражено просто как утверждения или ретракции. Таким образом, Datomic поддерживает понятие функций базы данных. Это функции, написанные на обычном языке программирования (например, Java или Clojure), которые устанавливаются в базу данных (конечно же, как данные через транзакции). После установки функция «вызов» базы данных может быть частью транзакции:

[[:db/add entity-id attribute value]
 [:my/giveRaise sally-id 100]
 ...]

При использовании в качестве части транзакции функция базы данных считается транзакционной функцией и получает дополнительный первый аргумент, который является значением внутри транзакции самой базы данных . Таким образом, функция может выдавать запросы и т. l. Функция транзакции должна возвращать данные транзакции. Независимо от того, какие данные он возвращает, он заменяет его в транзакции. Этот процесс повторяется до тех пор, пока все функции транзакций не возвратятся с помощью простых добавлений / сокращений. Таким образом, в транзакции выше функция giveRaise может посмотреть текущую зарплату Sally, найти ее как 45000 и вернуть утверждение о новом значении, в результате чего полученные данные транзакций выглядят следующим образом:

[[:db/add entity-id attribute value]
 [:db/add sally-id :employee/salary 45100]
 ...]

Поскольку : сотрудник / зарплата - это мощность, добавив, что этот факт о зарплате Салли неявно убирает прежний факт. И поскольку функции транзакций выполняются атомарно и последовательно в транзакциях, их можно использовать для выполнения произвольных, бесконфликтных преобразований. [Источник 2]

Запрос

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

Библиотека Datomic peer поставляется с механизмом запросов на основе Datalog. Datalog - это декларативный язык запросов, основанный на логике, с паттерном соответствия шаблону, хорошо подходящим для запросов к датам и коллекциям в памяти.

Основная форма запроса:

{:find [variables...] :where [clauses...]}

Или эта альтернативная (более простая в использовании) форма списка:

[:find variables... :where clauses...]

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

Если у вас есть база данных, содержащая эти даты (где Sally, Fred и Ethel являются stand-ins для их идентификаторов сущностей):

[[sally :age 21]
 [fred :age 42]
 [ethel :age 42]
 [fred :likes pizza]
 [sally :likes opera]
 [ethel :likes sushi]]

Мы могли бы задать такой запрос:

;;who is 42?
[:find ?e :where [?e :age 42]]

И получите этот результат

[[fred], [ethel]]

:where позиции соответствуют позициям, а для источников базы данных каждый базис соответствует совпадению кортежа

[entity attribute value transaction].

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

Соединения неявны и встречаются всякий раз, когда вы используете переменную более одного раза:

;;which 42-year-olds like what?
[:find ?e ?x
 :where [?e :age 42]
        [?e :likes ?x]

который возвращает:

[[fred pizza], [ethel sushi]]

API для запроса - это функция, называемая q :

Peer.q(query, inputs...);

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

Объединяя все это:

//Подключаем
Connection conn = Peer.connect("a-db-URI");
//Захватываем текущее значение базы данных
Database db = conn.db();
//На даный момент строка,потому что в Java нет литералов
String query = "[:find ?e :where [?e :likes pizza]]";
//Кому нравится пицца?
Collection result = Peer.q(query, db);

Тот же запрос, различный базис

Все становится интересным, когда мы используем тот факт, что db имеет всю историческую информацию:

// кому понравилась пицца на прошлой неделе?
Peer.q (query, db.asOf (lastTuesday));

Метод asOf базы данных возвращает представление этой базы данных по состоянию на предыдущий момент времени, указанный по дате или времени. Обратите внимание, что мы не вернулись к соединению и не изменили запрос. Если вы когда-либо скатывали свои собственные временные метки, вы знаете, что запрос с временной квалификацией обычно отличается от одного для «сейчас». Существует соответствующий since метод

// что, если мы добавим всех из Бруклина?
Peer.q (query, db.with (eachFromBrooklyn));

Метод with принимает данные транзакции и возвращает локальное значение базы данных с добавленными данными. По этому соединению не производится никаких транзакций. Таким образом, вы можете делать какие-то запросы или проверять данные транзакции перед ее выпуском. Существует также метод filter, который возвращает базу данных, отфильтрованную некоторым предикатом. Опять же, мы не коснулись соединения, db или запроса.

Что делать, если мы хотим протестировать запрос без настройки базы данных? Мы можем просто предоставить данные в одной и той же форме:

//проверить запрос без базы данных
Peer.q(query, aCollectionOfListsWithTestData);

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

До сих пор все методы работали с определенной точкой в ​​прошлом или в будущем. Но многие интересные анализы захотят посмотреть во времени:

// кто когда-либо любил пиццу?
Peer.q (query, db.history ());

Метод history вернет все значения по времени. Это может быть объединено с, например, asOf и т. д. Этот запрос работает как есть, но часто запросы с переходом по времени будут разными.

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

Различные запросы, одинаковые основания

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

Прямой доступ к индексу

Значения базы данных предлагают высокопроизводительный API для итеративного доступа к базовым отсортированным датам из индексов (неизменяемых). Это сырье, из которого могут быть построены другие подходы к запросу. Например, через этот API вы можете запрашивать базы данных Datomic, используя Clojure's Prolog- подобную библиотеку core.logic.

Дополнение

Создатель языка программирования Clojure, диалекта языка Lisp, построенного на основе Java Virtual Machine - Ричард Хикки демонстрирует свой проект и рассказывает тонкости Datomic:

Rich Hickey рассказывает о Datomic, включая основы архитектуры и модели данных


  • Более подробно можно посмотреть видео-лекции и презентации про Datonmic на сайте:

http://alexott.net/ru/clojure/video.html

Источники

  1. Статья Datonic. //SitePoint. [2017—2017]. Дата обновления: 09.01.2013. URL: https://www.sitepoint.com/datomic/ (дата обращения: 20.12.2017).
  2. Документация Datonic. //Datomic Documentation. [2016—2017]. URL: http://docs.datomic.com/ (дата обращения: 20.12.2017).


Ссылки