如何复制 PostgreSQL 数据库中的数据量?

Posted

技术标签:

【中文标题】如何复制 PostgreSQL 数据库中的数据量?【英文标题】:How to duplicate the amount of data in a PostgreSQL database? 【发布时间】:2013-11-26 11:38:05 【问题描述】:

为了评估我们平台(django + postgresql)的负载,我想复制系统中的数据量。创建可以模拟不同类型对象的模拟有点复杂(因为我们有一个非常复杂的数据模型)。 有没有办法创建数据库的副本,覆盖未使用的主键和唯一字段并将其与原始字段合并?

【问题讨论】:

考虑自然键。要创建没有 pk 的夹具,请参阅:***.com/questions/9436954/… 您是否考虑过使用thisthis 等工具来生成模拟数据? 【参考方案1】:

(一)原理说明

为了清楚地说明原理,本说明假设如下:

每个表都有一个名为“id”的大序列主键列 对表没有唯一约束(主键除外) 外键约束只引用其他表的主键

将以下内容应用于您的数据库架构:

    确保架构中的表之间没有循环依赖关系。如果有,请选择会破坏这种依赖关系的外键约束并删除它们(稍后您将在手动处理受影响的字段后重新创建它们)。 按拓扑顺序对表进行排序,并按此顺序为每个表执行 (3) 中的脚本

    对于 (2) 中的每个表 . 执行:

    /*
    Creating a lookup table which contains ordered pairs (id_old, id_new). 
    For every existing row in table <table_schema>.<table_name>, 
    new row with id = new_id will be created and with all the other fields copied. Nextval of sequence <table_schema>.<table_name>_id_seq is fetched to reserve id for a new row.
    */
    CREATE TABLE _l_<table_schema>_<table_name> AS 
    SELECT id as id_old, nextval('<table_schema>.<table_name>_id_seq') as id_new
    FROM <table_schema>.<table_name>;
    
    /*
    This part is for actual copying of table data with preserving of referential integrity.
    
    Table <table_schema>.<table_name> has the following fields:
    id - primary key
    column1, ..., columnN - fields in a table excluding the foreign keys; N>=0;
    fk1, ..., fkM - foreign keys; M>=0;
    
    _l_<table_schema_fki>_<table_name_fki> (1 <= i <= M) - lookup tables of parent tables. We use LEFT JOIN because foreign key field could be nullable in general case.
    
    */
    INSERT INTO <table_schema>.<table_name> (id, column1, ... , columnN, fk1, ..., fkM)
    SELECT tlookup.id_new, t.column1, ... , t.columnN, tablefk1.id_new, ..., tablefkM.id_new
    FROM <table_schema>_<table_name> t
    INNER JOIN _l_<table_schema>_<table_name> tlookup ON t.id = tlookup.id_old
    LEFT JOIN _l_<table_schema_fk1>_<table_name_fk1> tablefk1 ON t.fk1 = tablefk1.id_old
    ...
    LEFT JOIN _l_<table_schema_fkM>_<table_name_fkM> tablefkM ON t.fkM = tablefkM.id_old;
    

    删除所有查找表。

(II) 描述我的实现

    为了检查循环依赖,我查询了传递闭包 (https://beagle.whoi.edu/redmine/projects/ibt/wiki/Transitive_closure_in_PostgreSQL) 我实现了拓扑排序功能(从一些博客的 t-sql 移植)。它对自动化非常有用。 我做了一个代码生成器(在 plpgsql 中实现)。这是一个将 作为输入参数并返回 (I.2) 中显示的该表的文本 (SQL) 的函数。通过按拓扑顺序连接每个表的函数结果,我生成了复制脚本。 我对脚本进行了手动更改以满足独特的约束和其他细微差别,而样板脚本没有涵盖这些。 完成。脚本准备好在一个事务中执行。

当我有机会时,我会将我的代码“匿名化”一点并将其放在 github 上并在此处放一个链接。

【讨论】:

以上是关于如何复制 PostgreSQL 数据库中的数据量?的主要内容,如果未能解决你的问题,请参考以下文章

来了!PostgreSQL 同步流复制原理和代码浅析,请签收

PostgreSQL 数据库中表中的空列有多宽? [复制]

PostgreSQL 中的本地时区偏移量

PostgreSQL如何删除不使用的xlog文件

如何使用插入查询而不是复制查询在 postgresql 中生成数据库的脚本文件?

我如何将本地 PostgreSQL 数据库复制到 Heroku for Spring Boot 应用程序