@@ -53,6 +53,8 @@ var db = level('./whatever.db');
53
53
---
54
54
# put
55
55
56
+ set a value for a key with ` .put() `
57
+
56
58
``` js
57
59
var level = require (' level' );
58
60
var db = level (' ./whatever.db' );
@@ -64,6 +66,8 @@ db.put('key', 'value', function (err) {
64
66
---
65
67
# get
66
68
69
+ load a value for a key with ` .get() `
70
+
67
71
``` js
68
72
var level = require (' level' );
69
73
var db = level (' ./whatever.db' );
@@ -76,9 +80,30 @@ db.get('key', function (err, value) {
76
80
---
77
81
# del
78
82
83
+ delete a value at a key with ` .del() ` :
84
+
85
+ ---
86
+ # atomicity
87
+
88
+ either all transactions succeed
89
+ or all transactions fail
90
+
91
+ ---
92
+ # consistency
93
+
94
+ atomicity is important to enforce consistency
95
+
96
+ Suppose a user has just signed up.
97
+ We might need to create:
98
+
99
+ * a record for their
100
+ * a record for their login username and password
101
+
79
102
---
80
103
# batch
81
104
105
+ perform multiple
106
+
82
107
``` js
83
108
```
84
109
@@ -88,25 +113,196 @@ db.get('key', function (err, value) {
88
113
---
89
114
# thinking lexicographically
90
115
116
+ keys are sorted by their string values:
117
+
118
+ * aaaaa
119
+ * bb
120
+ * ccccc
121
+
122
+ ---
123
+ # numbers get converted into strings!
124
+
125
+ * "1"
126
+ * "12"
127
+ * "3"
128
+ * "4"
129
+ * "555"
130
+ * "6"
131
+
132
+ ---
133
+ # bytewise
134
+
135
+ a nicer way of handling lexicographic values
136
+
137
+ sorting for numbers happens as you might expect:
138
+
139
+ * 1
140
+ * 3
141
+ * 4
142
+ * 6
143
+ * 12
144
+ * 555
145
+
146
+ ---
147
+ # bytewise hierarchy
148
+
149
+ and there is also a hierarchy of types.
150
+ ` null ` is the first type to sort and ` undefined ` is the
151
+ last.
152
+
153
+ * null
154
+ * numbers
155
+ * strings
156
+ * arrays
157
+ * objects
158
+ * undefined
159
+
160
+ ---
161
+ # bytewise
162
+
163
+ Arrays are sorted component-wise, which means we can make
164
+ keys like:
165
+
166
+ [ 'user', 'substack' ]
167
+
168
+ and then to query all users we can do:
169
+
170
+ ``` js
171
+ db .createReadStream ({
172
+ gt: [ ' user' , null ],
173
+ lt: [ ' user' , undefined ]
174
+ })
175
+ ```
176
+
91
177
---
92
178
# organizing your keys
93
179
180
+ key/value structure we might use for
181
+ a user/post system:
182
+
183
+ ``` json
184
+ [{"key" :" user!substack" ,"value" :{"bio" :" beep boop" }},
185
+ {"key" :" user!maxogden" ,"value" :{"bio" :" cats." }},
186
+ {"key" :" post!substack!2015-01-04 11:45" ,"value" :" cool beans" }]
187
+ {"key" :" post!maxogden!2015-01-03 17:33" ,"value" :" soup." }]
188
+ ```
189
+
190
+ ---
191
+
192
+ This will let us efficiently query for a user's posts:
193
+
194
+ ``` js
195
+ db .createReadStream ({
196
+ gt: " user!substack" ,
197
+ lt: " user!substack!~"
198
+ })
199
+ ```
200
+
201
+ ---
202
+ # organizing keys with bytewise
203
+
204
+ or with bytewise:
205
+
206
+ ``` json
207
+ [{"key" :[" user" ," substack" ],"value" :{"bio" :" beep boop" }},
208
+ {"key" :[" user" ," maxogden" ],"value" :{"bio" :" cats." }},
209
+ {"key" :[" post" ," substack" ," 2015-01-04 11:45" ],"value" :" cool beans" }]
210
+ {"key" :[" post" ," maxogden" ," 2015-01-03 17:33" ],"value" :" soup." }]
211
+ ```
212
+
213
+ ---
214
+ # and querying with bytewise:
215
+
216
+ ``` js
217
+ db .createReadStream ({
218
+ gt: [" user" ," substack" ,null ],
219
+ lt: [" user" ," substack" ,undefined ]
220
+ })
221
+ ```
222
+
223
+ ---
224
+
225
+ In either case,
226
+ what if we want to get ALL the posts on the system?
227
+
94
228
---
95
229
# secondary indexes
96
230
231
+ We can use ` .batch() ` to create multiple keys for each post:
232
+
233
+ ``` js
234
+ var now = new Date ().toISOString ();
235
+ var id = crypto .randomBytes (16 ).toString (' hex' );
236
+ var subkey = now + ' !' + id;
237
+ db .batch ([
238
+ {type: ' post' ,key: ' post!substack!' + subkey,value: msg},
239
+ {type: ' post' ,key: ' post!' + subkey,value: msg},
240
+ ]);
241
+ ```
242
+
97
243
---
98
- # bytewise
244
+ # querying our indexes
245
+
246
+ now to get all the posts system-wide sorted by date,
247
+ we can do:
248
+
249
+ ``` js
250
+ db .createReadStream ({
251
+ start: " post!" ,
252
+ end: " post!~"
253
+ })
254
+ ```
99
255
100
256
---
101
257
# subleveldown
102
258
259
+ we can create nested sub-databases with subleveldown:
260
+
261
+ ``` js
262
+ var level = require (' level' );
263
+ var sublevel = require (' subleveldown' );
264
+ var db = level (' whatever.db' );
265
+
266
+ var catsdb = sublevel (db, ' cats' );
267
+ var robodb = sublevel (db, ' robots' );
268
+
269
+ catsdb .put (' msg' , ' meow' );
270
+ robodb .put (' msg' , ' beep boop' );
271
+ ```
272
+
273
+ and ` catsdb ` and ` robodb ` will each key a unique namespace
274
+ for a ` msg ` key.
275
+
103
276
---
104
277
# modularity
105
278
106
- * accountdown
107
- * subleveldown
108
- * cookie-auth
279
+ Instead of building in a lot of features, in leveldb you can
280
+ use npm to install packages:
281
+
282
+ * [ subleveldown] ( https://npmjs.org/package/subleveldown )
283
+ * [ cookie-auth] ( https://npmjs.org/package/cookie-auth )
284
+ * [ accountdown] ( https://npmjs.org/package/accountdown )
285
+ * [ forkdb] ( https://npmjs.org/package/forkdb )
286
+
287
+ ---
288
+ # accountdown
289
+
290
+ Making user accounts is actually surprisingly tricky!
291
+
292
+ You've got to remember:
293
+
294
+ * only create a user if the name hasn't been taken
295
+ * hash passwords with a unique salt for each user
296
+ * lock records to prevent account creation race conditions
297
+ * extensibility points for more login methods in the future
298
+
299
+ ---
300
+ # links
301
+
302
+ * [ levelup docs] ( https://github.com/rvagg/node-levelup )
303
+ * [ example leveldb website with accountdown] ( https://github.com/substack/example-user-website )
109
304
110
305
---
111
- #
306
+ # homework
112
307
308
+ http://nodeschool.io/#levelmeup
0 commit comments