Path of the NodeBases Jedi

Something something something StarWars.

Created by Bryce B. Baril / @brycebaril

A short time ago, in a continent

far, far away....

NODE BASESA New Database Paradigm

Episode VI

PATH OF THE JEDI

 

Node Developer has returned to his trusty runtime Node.js in an attempt to rescue his company Async IO from the clutches of the vile database Mongo the DB.

 

Little does Node know that the DATABASE COMMUNITY has secretly begun construction on a new monolithic database even more convoluted and packed with unnecessary features than Enterprise Oracle.

 

When completed, this ultimate weapon will spell certain doom for the small band of rebels struggling to keep their sanity in check...

Path of the NodeBases Jedi

But First...

What is a database?

Which of these is a database?

  • MongoDB
  • Cat
  • Filesystem
  • PostgreSQL

Which of these is a database?

  • MongoDB
  • Cat
  • Filesystem (almost!)
  • PostgreSQL... Yes, but...

NodeBases Goal:

Do for databases what NPM did for web applications.

Small, composable pieces of functionality.

LevelDB

Right now the "canonical" NodeBases back-end is LevelDB.

It is a simple key-value store with 5 primitives:

  • get
  • put
  • del
  • batch (put/del)
  • ordered iterator

LevelUP/LevelDOWN

LevelUP provides a consistent JS interface to Node.

LevelDOWN is the wrapper interface for DB engines.

Lots of options:

  • LevelDB
  • HyperLevelDB
  • RocksDB
  • LMDB
  • IndexedDB (browser!)
  • ... and more!

How to get it

Easiest:

npm install level

level provides a LevelUP/LevelDOWN bundle ready to use.

How to use it.


// var level = require("level")
var db = level("./vanilla")

// put  key    value
db.put("wow", "mom", function (err) {
  if (err) return alert("IO Error!?", err)

  // get  key
  db.get("wow", function (err, value) {
    if (err) return alert("Not found?")
    $("#vanilla .results").text("value: " + value)
  })
})
            

(press "r" to run example)

Using level-sublevel to add namespaces. (Think 'tables')


// var level = require("level")
// var Sublevel = require("level-sublevel")
var db = Sublevel(level("./namespaced"))
var stuff = db.sublevel("stuff")
var things = db.sublevel("things")

stuff.put("wow", "mom", function (err) {
  things.put("wow", "zzz", function (err) {
    stuff.get("wow", function (err, value) {
      $("#namespaced .results").text("value: " + value)
    })
  })
})
            

(press "r" to run example)

Using level-version to make writes versioned.


// var level = require("level")
// var Sublevel = require("level-sublevel")
// var Version = require("level-version")
var db = Sublevel(level("./versioned"))
var things = Version(db.sublevel("things"))

things.put("wow", "mom", {version: 0}, function (err) {
  things.put("wow", "zzz", function (err) {
    things.get("wow", {version: 0}, function (err, value, version) {
      $("#versioned .results")
        .text("value: " + value + " version: " + version)
    })
  })
})
            

(press "r" to run example)

Case Study: TimestreamDB

timestreamdb is a full time series database with a full Node streams-based query language.

How Timestreamdb Works

TimestreamDB itself is really simple, just 45 lines of code. All it actually does is combine level-version and timestream

Small, composable pieces of functionality.

Because of NodeBases

TimestreamDB is theoretically compatible with 100s of other features provided by other NodeBases modules.


// var level = require("level")
// var TimestreamDB = require("timestreamdb")
var db = TimestreamDB(level("./tsdb", {valueEncoding: "json"}))

var count = 0
var i = setInterval(function () {
  if (++count > 30) {
    clearInterval(i)
    db.ts("foo").mean().tail(function (r) {
      $("#tsdb .results").text(r.value)
    })
  }
  db.put("foo", {id: count, value: Math.random()})
}, 10)
            

(press "r" to run example)


var db = level("slidetimer", {valueEncoding: "json"})
window.SlideTimeDB = TimestreamDB(db)
function recordSlide(event) {
  SlideTimeDB.put("slide", {slide: event.indexh + "," + event.indexv})
}
            

var count = SlideTimeDB.ts("slide")
  .count()
  .rename("slide", "count")

var avg = SlideTimeDB.ts("slide")
  .elapsed()
  .numbers()
  .mean()
  .divide(1000)
  .round(1)

count.join(avg).tail(function(r) {
  $("#numslides").text(r.count)
  $("#avgtime").text(r.elapsed)
})
            

Bryce, you've visited ??? slides at an average of:

??? seconds per slide.

Episode II

ATTACK OF THE CODEROT

 

There is unrest in the NodeBases Community. Several thousand node developers have declared their intentions to use Enterprise Databases.

 

This separatist movement, under the leadership of the mysterious Count Coderot, has made it difficult for the limited number of NodeBase Knights to maintain compatibility and order in NPM.

 

Senator Vagg, the founder of the NodeBases Community, is returning to the NPM Senate to vote on the critical issue of creating and ARMY OF NODE DEVELOPERS to assist with the overwhelmed Jedi....

The Dark Side of NodeBases

  • Incomplete experiments
  • Competing efforts
  • Land grab
  • Over-promise
  • Combinatorial compatibility
  • Missing a solid Replication story

None of these things are evil or bad!

... but they can scare away potential users.

Help us realize the NodeBases potential

  • Use it, try it, push the limits!
  • Favor Science over Mad Science
  • Be a good citizen!
    • Label project status
    • Point to similar projects
    • Use the modules you write!!!
  • We need a rock-solid replication story
  • Published performance metrics

Hype Cycle

http://en.wikipedia.org/wiki/Hype_cycle

Thank you!

For more info: leveldb.org


@brycebaril



Star Wars crawl effect