问题
关系数据库很棒。模式的归一化允许将用户的数据存储在您的应用程序中,比面向文档的NOSQL解决方案更便宜,更快。但是,如果您需要确定行的所有权并提取它们,那么复杂的,深度的模式可能会带来真正的痛苦。
您可能需要从数据库中提取一些用户和所有属于他的记录(例如地址,订单,评论等)的情况很少:
- 用于备份。将不活动的用户数据移至廉价,长期存储和免费的数据库空间。
- 出于法律目的。如果您需要确保用户的当前状态。
- 为更好的负载平衡。要在数据库碎片之间迁移用户。
- 销售。在应用程序中准备一些榜样模型用户,保存他的数据并将其加载到应用程序的演示实例中。
- 用于调试。如果您的应用程序行为不当,并且您想以孤立的方式分析用户数据并从生产到本地机器。
解决方案
我在大型模式下工作很多。每天有数百个数据库,每个数据库中的数百个表,深层关系链,每天多达几个架构。因此,我创建了一个工具自动化关系数据提取:UpRooted。
目标很简单:
-
完全自动化。我不想写一个
JOIN
。 - 最佳。应从数据库的角度以最有效的方式达到相关表中的数据。
-
智能。应该处理数据,以便允许将来加载到另一个数据库中,而不会破坏
FOREIGN KEY
约束。
例子
让我们假设您有MySQL数据库,您需要从users
表中提取用户,其中id
= 1,并从相关表中获得所有数据。
开始使用UpRooted的最简单方法是乘坐Docker容器。
为脚本和输出文件创建工作目录,例如:
mkdir /Users/me/uprooted
运行Docker并安装此目录:
docker run --interactive --tty --volume /Users/me/uprooted:/home/uprooted bbkr2/uprooted:latest
UpRooted是用Raku编写的,因此在此目录中创建example.raku
文件,并使用以下内容(请记住调整连接凭据):
use DBIish;
use UpRooted::Schema::MySQL;
use UpRooted::Tree;
use UpRooted::Reader::MySQL;
use UpRooted::Writer::MySQLFile;
my $connection = DBIish.connect(
'mysql',
host => '***', port => 3306, user => '***', password => '***', database => '***'
);
my $schema = UpRooted::Schema::MySQL.new( :$connection );
my $tree = UpRooted::Tree.new( root-table => $schema.table( 'users' ) );
my $reader = UpRooted::Reader::MySQL.new( :$connection, :$tree );
my $writer = UpRooted::Writer::MySQLFile.new;
$writer.write( $reader, id => 1 );
从容器中运行脚本:
raku example.raku
您的用户将被保存到/Users/me/uprooted
目录中的out.sql
文件。
更多信息
我强烈建议阅读UpRooted Readme,以解释UpRooted::
名称空间中的每个模块,更高级的用例和潜在的模式设计问题。
如果您发现了任何错误或有一些建议可以随意在GitHub上创建问题。
快乐数据提取:)