one direction • The world exists as a series of discrete, ordered states • The past is immutable • You cannot know the state of another process/ system instantaneously
thing as sharing current data, only the possibility of sharing consistent data • Current only exists on a single machine, on a single core, within a single thread • Or, you stop the world to emulate this
as stale data if it is part of a historical state (e.g., versioned/timestamped). • If consistency is a requirement for some datasource, then you need: • A single Source of Truth • Linearized writes
else?) conditional, yields `then` or `else` (do exprs*) evaluate expressions, return last (let [bindings* ] exprs*) lexical context (quote form) yields an unevaluated form (unquote form) unquotes a quoted form (var symbol) the var object named by a symbol (fn name? ([params*] cond-map? exprs*)+) defines a function (loop [bindings* ] exprs*) like let, but provides a recursion target (recur exprs*) evaluates expressions and rebinds at recur point (throw expr) evaluates expr and throws result (try expr* catch-clause* finally-clause?) try/catch/finally semantics . new set! java[script] interop
a remote database (def conn (d/connect "datomic:ddb://us-east-1/my-db")) ;; Fetch the current database value (def db (d/db conn)) ;; Evaluate a query (d/q <some query> db) ;; Join across multiple databases (d/q <some query> db1, db2) ;; Retrieve an entity (d/entity db <identifier>)
(def db-before (d/as-of db <1 week ago>)) ;; Or, pretend to transact new data (def db-later (d/with db <proposed tx data>)) ;; History of a db, in its entirety (d/history db) ;; Listen for new changes (d/tx-report-queue conn) ;; Or, process old ones (d/tx-range (d/log conn) <1 week ago> nil)
Process App Results Strings DDL + DML Traditional (SQL) Database • Query, indexing, transactions, I/O, and storage all colocated • Queries must be performed eagerly, for consistency • e.g., MVCC is transient historical state isolation only during query • Updates performed in-place • Complects reads and writes
Peer App Process Peer Lib Query Cache App Live Index Comm Storage service (DynamoDB) Segment storage Standby Peer App Process Peer Lib Query Cache App Live Index Comm Peer App Process Peer Lib Query Cache App Live Index Comm elasticache cluster (optional) Data Segments Datomic Operational Model • Read/Query scales with the number of peers • Every peer sees completed transactions as of a particular point in time • Peers always see all transactions up to their time basis, in order, with no gaps • Peers can, optionally, coordinate on a time basis
customers-who-bought [db product-id] (d/q '[:find ?customer :in $ ?id :where [?customer :customer/orders ?order] [?order :order/items ?item] [?item :product/id ?id]] db product-id)) Database value as an argument to the function
entity id. • Attribute: Names a piece of data associated with an entity, has schema. • Value: A scalar or reference (type defined by the attribute's schema). • Tx: A transaction id. Refers to a transaction entity! • Added?: A boolean declaring whether this Datom is asserting or retracting a fact about its entity.
:user/email string 1 Identity :user/votes ref Many {:db/ident :user/email :db/valueType :db.type/string :db/cardinality :db.cardinality/one :db/unique :db.unique/identity …} Could also be db.unique/value
Peer App Process Peer Lib Query Cache App Live Index Comm Storage service (DynamoDB) Segment storage Standby Peer App Process Peer Lib Query Cache App Live Index Comm Peer App Process Peer Lib Query Cache App Live Index Comm elasticache cluster (optional) Data Segments Peers • Local query • High performance • Use arbitrary functions in query • "Heavy" peers • Peers are part of the database • Peers must run on the JVM
Peer App Process Peer Lib Query Cache App Live Index Comm Storage service (DynamoDB) Segment storage Standby Peer App Process Peer Lib Query Cache App Live Index Comm Peer App Process Peer Lib Query Cache App Live Index Comm elasticache cluster (optional) Data Segments
clients scale separately • Good fit for lightweight / ephemeral clients • "Warm" caches on peer server(s) • Option for generic web-servers and specialized peer servers (e.g., products vs analytics) to increase cache hits • Scale up/down web-servers w/o sacrificing cache hits • Clients can be written in/for any language/ runtime