从连接表重建表

时间:2017-11-29 18:18:09

标签: sql sql-server

我面临一个问题,即数据供应商正在一个表中生成多租户数据库的转储。重新创建原始表并非不可能,问题是我每天都会收到数百万行。每天重新创造一切都是不可能的。

到目前为止,我使用SSIS来执行此操作,使用查找密集型方法。在过去的一年里,我的虚拟机从2 GB的RAM变为128,并且仍然在增长。

让我解释一下耻辱:

想象一个用户有帖子的数据库,帖子有评论。在我的真实场景中,我说的是7个不同的表格。分析几行,我有以下内容:

+-----+------+------+--------+------+-----------+------+----------------+
| Id* | T_Id | U_Id | U_Name | P_Id | P_Content | C_Id |   C_Content    |
+-----+------+------+--------+------+-----------+------+----------------+
|   1 |    1 |    1 | john   |    1 | hello     |    1 | hello answer 1 |
|   2 |    1 |    2 | maria  |    2 | cake      |    2 | cake answer 1  |
|   3 |    2 |    1 | pablo  |    1 | hello     |    1 | hello answer 3 |
|   4 |    2 |    1 | pablo  |    2 | hello     |    2 | hello answer 2 |
|   5 |    1 |    1 | john   |    3 | nosql     |    3 | nosql answer 1 |
+-----+------+------+--------+------+-----------+------+----------------+
  • Id来自我的表
  • T_Id是“租户”ID,用于标识多个数据库

我想象了以下可能的解决方案:

我创建一个查询,为每个表选择不存在的ID,例如:

SELECT DISTINCT n.t_id, 
                n.c_id, 
                n.c_content 
FROM   mytable n 
WHERE  n.id > 4 
       AND NOT EXISTS (SELECT 1 
                       FROM   mytable o 
                       WHERE  o.id <= 4 
                              AND n.t_id = o.t_id 
                              AND n.c_id = o.c_id) 

这样,只要找到表的新Id,我就只能选择新的匹配项。虽然它有效但在处理数百万行时可能会表现不佳。

有人可以分享一个建议吗?我很失落。

提前致谢。

编辑&gt;我的问题很模糊

我的最终目的是逐步重建转储中的表,避免在数据库外部进行查找。我不时会运行一个脚本,选择新的租户,用户,帖子和评论,并将它们添加到相应的表格中。

我之前的解决方案如下:

  1. 缓存整个数据库
  2. 对于每个新行,搜索缓存中的列
  3. 如果它不存在,则插入
  4. 我知道这听起来很愚蠢,但作为一名使用ETL的新开发人员

    是有意义的

1 个答案:

答案 0 :(得分:0)

首先,如果您有一个完整的平面数据库转储,我建议您在将数据导入数据库之前处理您的文件(低级文件处理非常便宜且几乎是即时的)。

Removing lines in one file that are present in another file using python开始,您可以移除自上次运行以来已解析过的所有行。

with open('new.csv','r') as source:
    lines_src = source.readlines()
with open('old.csv','r') as f:
    lines_f = f.readlines()
destination = open('diff_add.csv',"w")
for data in lines_src:
    if data not in lines_f:
        destination.write(data)
destination.close()

这需要不到五秒的时间来处理900Mo =&gt; 1.2转储。有了这个,你只能使用真正改变你的新表格的行。

现在您可以将此平面数据库导入工作表。

由于您必须在每一行中搜索指针,id上的某些索引可能是一个好主意(转到首先使用您的Tenant_id的复合索引)。

对于最后一部分,我并不确切知道您的数据的外观,您可以进行一些更新吗?

Operators - EXCEPT and INTERSECT可以帮助您解决这类问题。