Correct Database usage

171 views
Skip to first unread message

Alex Spencer

unread,
Nov 24, 2014, 11:35:30 AM11/24/14
to nod...@googlegroups.com
Hey.

Need some advice on an api application built using:
- express
- knexjs
- postgres

My question is if im handling database operations correctly or if im doing it completely wrong.. See example

var knex = require('knex');
app
.get('/example/:param',
loadWithParam
(),
updateWithParam
(),
render
.staticOK()

function loadWithParam() {
return function(req, res, next) {
var db = knex({conConfig});
db
(tableName).where(field, req.params.param).select().then(function(rows) {
db
.destroy(function() {
res.locals[tableName] = rows;
next();
});

}).catch(function(err) {
...
});
};
}

function updateWithParam() {
return function(req, res, next) {
if(res.locals[tableName].length === 0) {
return next();
}
var db = knex({conConfig});
db
(tableName).where(field, req.params.param).update({field: value}).then(function() {
db
.destroy(function() {
next();
});
}).catch(function(err) {
...
});
};
}


In short my question is if its good or bad practise opening up and closing database connections per operation required to run? Ive been told setting up a database connection on res.locals upon receiving a request is better, but i disagree..

Thanks

Matt

unread,
Nov 24, 2014, 7:35:58 PM11/24/14
to nod...@googlegroups.com
I'm not 100% sure about knex, but by default the node Pg library caches connections, so it's not an issue. Might be worth checking the docs or the source though to make sure it's using that code path.

--
Job board: http://jobs.nodejs.org/
New group rules: https://gist.github.com/othiym23/9886289#file-moderation-policy-md
Old group rules: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
---
You received this message because you are subscribed to the Google Groups "nodejs" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nodejs+un...@googlegroups.com.
To post to this group, send email to nod...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/nodejs/408d3fd6-dd6c-4621-9030-99ff2e3fe7d6%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Alex Kocharin

unread,
Nov 24, 2014, 7:36:44 PM11/24/14
to nod...@googlegroups.com
 
Opening and closing database connection per request is a very bad idea. Database connection should be opened permanently and re-used across many different requests, this way you save milliseconds establishing it.
 
knex allows connection pooling. Use it.
 
 
25.11.2014, 01:09, "Alex Spencer" <alex...@gmail.com>:
--

Tim Davis

unread,
Nov 24, 2014, 10:28:25 PM11/24/14
to nod...@googlegroups.com
You can load your config into Knex in, for example, db/client.js

Then export that knex instance out into your data access objects.

Alex Spencer

unread,
Nov 25, 2014, 12:38:45 AM11/25/14
to nod...@googlegroups.com, al...@kocharin.ru
Thanks for the replies. The reason I built it this way was beacuse of these reasons:

- Each user has its own Database with a list of schemes. (IE new connection every time, can't reuse a mass pool on a specific database)
- Spamming API requests would open up a massive amount of connections, that are never killed off, resulting in the postgres instance to eventually be smocked full.

This is why I thought opening and closing was good. How would you recommend handling the above issues?

TigerNassau

unread,
Nov 25, 2014, 10:25:05 AM11/25/14
to nod...@googlegroups.com
Any reason not using pg-native?

Sent from my LG Mobile

Alex Spencer

unread,
Nov 25, 2014, 10:41:11 AM11/25/14
to nod...@googlegroups.com
I prefer knexjs because of simplicity and the amount of features it supports. Also allows for neater code, in the sense that it's a lot easier to read.

For instance I've made an external JS file included in most of my routes that load data from the database. I simply call a function load(tableName) and that JS file will find a connection, parse all the req.params / req.query properties and add them to the whereclause, including other things as well like limit/offset/orderby/etc. All done in less than ~30 lines of code, which is great.

svante karlsson

unread,
Nov 25, 2014, 11:14:39 AM11/25/14
to nod...@googlegroups.com
Hmm, there are two things that feels funny here.

1) Each user has its own Database with a list of schemes
2) Spamming API requests would open up a massive amount of connection.

What do you think postgres says about millions of databases? Normally you share your users in a single database and selects the correct "view" using a "where" clause. I think you should log in to your database once and use connection pooling. Put a HAProxy infront of your outward facing servers and limit the number of simultaneous connections per ip.

/svante




Alex Spencer

unread,
Nov 25, 2014, 11:22:48 AM11/25/14
to nod...@googlegroups.com, sa...@csi.se
I guess I wasn't clear enough.

1) Each User has a Db (Master) containing schemes per user (UserScheme) all containing the same type of tables, and datastructure. This is to make sure all data is split correctly.
2) Limiting the IP is dumb, in my opinion. An API is an API, should work without applying limits in response to somewhat "broken" code. Hence the question above regarding my code snippet, whether it was right or wrong.

I rewrote most of it already and it's working much better now. I create pools for each User/Scheme that when idled for too long (5+min) will be destroyed. Everythings working flawlessly now so I guess this discussion can be considered solved.

Tim Davis

unread,
Nov 26, 2014, 10:27:03 AM11/26/14
to nod...@googlegroups.com

I'm really curious about why your data needs to be 'split correctly'. If the table structures are the same, couldn't you include everything together and just put Master/Userscheme info in WHERE clauses?

You received this message because you are subscribed to a topic in the Google Groups "nodejs" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/nodejs/N9NUKgjbdko/unsubscribe.
To unsubscribe from this group and all its topics, send an email to nodejs+un...@googlegroups.com.

To post to this group, send email to nod...@googlegroups.com.

Alex Spencer

unread,
Nov 26, 2014, 2:09:53 PM11/26/14
to nod...@googlegroups.com
Think of it this way.. Let's say you have and are maintaining 4 different hosted forums, but they all use the same source and structure (let's say vBulletin). Would you prefer to keep tables & data of all these forums on the same Database/Schema, or would you rather divide it into several databases?

I don't know how better to describe it. It may be similar structures, but the data is unique to each user, hence why I want to keep it divided. And it worked out in the end.

Christopher Rust

unread,
Nov 28, 2014, 1:48:10 PM11/28/14
to nod...@googlegroups.com

I can't speak for this person, specifically, but at my work we have legal requirements for keeping customer data separate. We also have SLAs for delivering analytics on this data and so keeping them on separate DB instances (and physical machines) allows us to actually fulfill these guarantees.

Sometimes there are valid reasons to split very similar databases.

John Fitzgerald

unread,
Nov 28, 2014, 1:48:13 PM11/28/14
to nod...@googlegroups.com
I'm not him, but I've used the split schema pattern before. It helps a lot in a few cases.
a) You want to provide a full export for the customer, you can dump the schema really simply.
b) You don't want the serial columns to jump drastically between users. Like an Order ID.
c) You want to upgrade customers on a rolling basis - you can apply migrations to each schema separately. 
d) You may move users to a dedicated server in the future, or shard them across more machines.

These can all be handled in other ways of course, but sometimes it makes it a lot simpler.

-John


For more options, visit https://groups.google.com/d/optout.



--
John R. Fitzgerald

Reply all
Reply to author
Forward
0 new messages