我们如何使用单个SQL查询连接两个数据库?我更喜欢在这里使用sql,以提高性能。
配置/ database.yml的
SELECT example_dev.*, example_report_dev.*
FROM example_dev.myTable AS firstdb
INNER JOIN example_report_dev.myTable AS seconddb
ON firstdb.id = seconddb.id
现在在我的一个模型中,我想编写一个查询来从这两个数据库中获取数据
package de.fluxparticle.lab;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.ObservableSet;
import javafx.collections.SetChangeListener;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.stage.Stage;
import javafx.util.Duration;
import java.util.Collections;
import java.util.Random;
import java.util.TreeSet;
import static javafx.collections.FXCollections.observableSet;
/**
* Created by sreinck on 23.01.17.
*/
public class Set2List extends Application {
private final ObservableSet<Integer> setModel = observableSet(new TreeSet<Integer>());
@Override
public void start(Stage primaryStage) throws Exception {
TableView<Integer> tableView = new TableView<>();
addColumn(tableView, "Number");
ObservableList<Integer> list = convertSetToList(setModel);
tableView.setItems(list);
Random rnd = new Random();
scheduleTask(Duration.millis(1000), () -> setModel.add(rnd.nextInt(10)));
primaryStage.setScene(new Scene(tableView, 800, 600));
primaryStage.setTitle("Set2List");
primaryStage.show();
}
private static void scheduleTask(Duration interval, Runnable task) {
Timeline timeline = new Timeline(new KeyFrame(interval, event -> task.run()));
timeline.setCycleCount(Timeline.INDEFINITE);
timeline.play();
}
private static ObservableList<Integer> convertSetToList(ObservableSet<Integer> set) {
ObservableList<Integer> list = FXCollections.observableArrayList(set);
set.addListener((SetChangeListener<Integer>) change -> {
if (change.wasAdded()) {
Integer added = change.getElementAdded();
int idx = -Collections.binarySearch(list, added)-1;
list.add(idx, added);
} else {
Integer removed = change.getElementRemoved();
int idx = Collections.binarySearch(list, removed);
list.remove(idx);
}
});
return list;
}
private static void addColumn(TableView<Integer> tableView, String text) {
TableColumn<Integer, String> column = new TableColumn<>(text);
column.setCellValueFactory(param -> new SimpleStringProperty(param.getValue().toString()));
tableView.getColumns().add(column);
}
public static void main(String[] args) {
launch(args);
}
}
谢谢
答案 0 :(得分:2)
一种方法是使用postgres的dblink
。
来自文档:
dblink执行查询(通常是SELECT,但它可以是任何SQL 在远程数据库中返回行的语句。
首先,您需要在数据库中启用dblink
:
CREATE EXTENSION dblink;
然后,在您的应用程序中,您可以使用ActiveRecord::Base.connection.execute
执行原始查询语句。
我在这里创建了测试设置:
db1
包含tbl
和field1
的表field2
列。 db2
包含tbl
和field1
的表格field2
database.yml
列。两者都有 5行。
我的development:
adapter: postgresql
encoding: unicode
database: db1
:
rails console
来自ActiveRecord::Base.connection.execute("
SELECT * FROM tbl
UNION ALL
SELECT * FROM dblink('dbname=db2','SELECT * FROM tbl') AS tbl2(field1 varchar, field2 int);
").to_a
# [{"field1"=>"one", "field2"=>1}, {"field1"=>"two", "field2"=>2}, {"field1"=>"three", "field2"=>3}, {"field1"=>"four", "field2"=>4}, {"field1"=>"five", "field2"=>5}, {"field1"=>"one", "field2"=>1}, {"field1"=>"two", "field2"=>2}, {"field1"=>"three", "field2"=>3}, {"field1"=>"four", "field2"=>4}, {"field1"=>"five", "field2"=>5}]
:
'dbname=yourdb port=5432 host=yourhost user=youruser password=yourpwd
这只是一种可行的方法。您可以将dblink连接字符串设置为指向远程服务器(例如:conn1 = {
adapter: 'postgresql',
encoding: 'utf8',
database: 'db1'
}
conn2 = {
adapter: 'postgresql',
encoding: 'utf8',
database: 'db1'
#, more config here - other host, for instance #
}
arr1 = ActiveRecord::Base.establish_connection(conn1).connection.execute("select * from tbl").to_a
# => [{"field1"=>"one", "field2"=>1}, {"field1"=>"two", "field2"=>2}, {"field1"=>"three", "field2"=>3}, {"field1"=>"four", "field2"=>4}, {"field1"=>"five", "field2"=>5}] => [{"field1"=>"one", "field2"=>1}, {"field1"=>"two", "field2"=>2}, {"field1"=>"three", "field2"=>3}, {"field1"=>"four", "field2"=>4}, {"field1"=>"five", "field2"=>5}]
arr2 = ActiveRecord::Base.establish_connection(conn2).connection.execute("select * from tbl").to_a
# => [{"field1"=>"one", "field2"=>1}, {"field1"=>"two", "field2"=>2}, {"field1"=>"three", "field2"=>3}, {"field1"=>"four", "field2"=>4}, {"field1"=>"five", "field2"=>5}] => [{"field1"=>"one", "field2"=>1}, {"field1"=>"two", "field2"=>2}, {"field1"=>"three", "field2"=>3}, {"field1"=>"four", "field2"=>4}, {"field1"=>"five", "field2"=>5}]
)
请注意这不是铁路方式。原始查询与模型无关。我建议您仅为特定任务选择此项,例如运行报告。
如果您想为每个数据库创建一个查询,并且不想将其链接到您的模型,则可以使用ActiveRecord::Base.establish_connection
,如下所示:
arr1
您将获得两个数据arr2
和Var workItem=witClient.GetWorkItemAsync(id: [work item id], expand: Microsoft.TeamFoundation.WorkItemTracking.WebApi.Models.WorkItemExpand.Relations).Result.
数组。
答案 1 :(得分:0)
您可以尝试章鱼宝石:https://github.com/thiagopradi/octopus。
Octopus是在ActiveRecord中进行数据库分片的更好方法。 Sharding允许同一rails应用程序中的多个数据库。虽然有几个项目实现了Sharding(例如DbCharmer,DataFabric,MultiDb),但每个项目都有其自身的局限性。章鱼项目的主要目标是提供更好的数据库分片方法。