从关系数据库中提取用户数据树
#postgres #mysql #raku

问题

关系数据库很棒。模式的归一化允许将用户的数据存储在您的应用程序中,比面向文档的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上创建问题。

快乐数据提取:)