Bre*_*row 3 postgresql node.js node-postgres
node-postgres声明如下:
node-postgres支持'事件发射器'样式API和'回调'样式.回调样式更简洁,通常更受欢迎,但是公平的API可以派上用场.它们可以混合搭配.
使用事件发射器API,我可以执行以下操作:
var db = new pg.Client("insert-postgres-connection-info");
db.connect();
Run Code Online (Sandbox Code Playgroud)
然后我可以使用db在我的网络应用程序中执行查询db.query('sql statement here').使用回调样式,每次我想运行查询时都会执行以下操作:
pg.connect(conString, function(err, client) {
client.query("sql statement", function(err, result) {
// do stuff
});
});
Run Code Online (Sandbox Code Playgroud)
所以我的问题是为什么使用回调样式"通常更喜欢"?每次使用数据库执行某些操作时打开连接效率不高吗?使用回调样式有什么好处?
编辑
我可能会错误地认为他的意思是"回调风格"(我不是在开玩笑,我的JavaScript不是很强)但我的问题是关于连接方法.我假设以下是回调样式连接方法:
// Simple, using built-in client pool
var pg = require('pg');
//or native libpq bindings
//var pg = require('pg').native
var conString = "tcp://postgres:1234@localhost/postgres";
//error handling omitted
pg.connect(conString, function(err, client) {
client.query("SELECT NOW() as when", function(err, result) {
console.log("Row count: %d",result.rows.length); // 1
console.log("Current year: %d", result.rows[0].when.getYear());
});
});
Run Code Online (Sandbox Code Playgroud)
以下是EventEmitter API连接方法:
// Evented api
var pg = require('pg'); //native libpq bindings = `var pg = require('pg').native`
var conString = "tcp://postgres:1234@localhost/postgres";
var client = new pg.Client(conString);
client.connect();
Run Code Online (Sandbox Code Playgroud)
如果我只是在这里混淆了条款,我的问题仍然存在.pg.connect(do queries)每次使用它时都会打开一个新的连接(不是吗?)
var client = new pg.Client(conString);
client.connect();
Run Code Online (Sandbox Code Playgroud)
打开一个连接然后允许你client在必要时用来运行查询,不是吗?
EventEmitter样式更适用于此类事物:
var query = client.query("SELECT * FROM beatles WHERE name = $1", ['John']);
query.on('row', function(row) {
console.log(row);
console.log("Beatle name: %s", row.name); //Beatle name: John
console.log("Beatle birth year: %d", row.birthday.getYear()); //dates are returned as javascript dates
console.log("Beatle height: %d' %d\"", Math.floor(row.height/12), row.height%12); //integers are returned as javascript ints
});
Run Code Online (Sandbox Code Playgroud)
通过混合和匹配,您应该能够执行以下操作:
// Connect using EE style
var client = new pg.Client(conString);
client.connect();
// Query using callback style
client.query("SELECT NOW() as when", function(err, result) {
console.log("Row count: %d",result.rows.length); // 1
console.log("Current year: %d", result.rows[0].when.getYear());
});
Run Code Online (Sandbox Code Playgroud)
请注意,即使使用回调样式,每次要执行查询时也不会打开连接; 最有可能的是,您在应用程序启动时打开连接并在整个过程中使用它.
有利有弊,你选择的一个取决于你的用例.
如果您要以相同的方式将数据返回到客户端 - 逐行 - 那么您可以使用事件发射器样式来减少延迟,我在此定义为发出请求之间的时间并接收第一行.如果您使用回调样式,则延迟会增加.
如果您要以分层数据结构(例如JSON(当结果集是层次结构的平面表示时为了节省带宽)将数据返回到客户端),您应该使用回调样式,因为您可以在收到所有行之前不会返回任何内容.您可以使用事件发射器样式并累积行(node-postgres提供了这样的机制,因此您不必通过查询维护部分构建的结果的映射),但这将是毫无意义的浪费,因为您不能返回任何结果,直到收到最后一行.
返回分层数据结构数组时,如果使用回调样式,则会有很多行一次性完成.这会阻塞大量时间,这是不好的,因为您只有一个线程可以为许多客户端提供服务.因此,您应该将事件发射器样式与行累加器一起使用.您的结果集应该被排序,以便当您检测到特定字段的值的更改时,您知道当前行代表要返回的新结果的开始,到目前为止累积的所有内容代表现在完整的结果,您可以将其转换为您的结果分层形式并返回客户端.
| 归档时间: |
|
| 查看次数: |
2698 次 |
| 最近记录: |