【问题标题】:Database and program design数据库和程序设计
【发布时间】:2012-08-24 05:21:42
【问题描述】:

我正在制作网络应用程序来监控三个不同系统之间的文件移动,每个系统都会生成一个具有以下格式的日志文件:

Folder, Filename, DataTime, Filesize

要求确定System1生成的文件是否成功传输到3rd System。并且还可以识别失败点。

我正在使用 SQLite 数据库,因为我必须将失败的文件信息保存 7 天。

数据库设计:

Folder, Filename, DateTime, FileSize, FileSource

FileSource 可以是System1System2System3

这样我可以进行批量插入,但会减慢识别失败文件的速度,任何人都可以帮助我编写好的 SQL 来识别失败的文件。

例如:样本数据

folder1, file1, 2012-29-08 23:01:02, 10, S1
folder1, file1, 2012-29-08 23:03:02, 10, S2

上述ex数据表示S2到S3之间的folder1/file1传输失败。

注意:每天将传输超过 1 万个文件。

【问题讨论】:

  • 这不是家庭作业,我确实使用下面的 SQL
    SELECT folder, filename, count() from tab group by folder, filename with count() 找到了丢失的文件>)
  • 很公平,但是如果您尝试关注问题标题,然后找到真正的问题,它将帮助您获得一个好的答案。需求段落表明这里可能有六个问题。

标签: database sqlite database-design


【解决方案1】:

我不确定你能从这里到达那里。您最好从实际执行传输的程序中记录错误代码。

你现在的表有问题。

CREATE TABLE filelog (
  folder text, 
  filename text, 
  datatime timestamp, 
  filesize integer, 
  filesource text);

-- Your failed transfer . . .
INSERT INTO "filelog" VALUES('folder1','file1','2012-08-29 23:01:02',10,'S1');
INSERT INTO "filelog" VALUES('folder1','file1','2012-08-29 23:03:02',10,'S2');
-- . . . and a duplicate of it.
INSERT INTO "filelog" VALUES('folder1','file1','2012-08-29 23:01:02',10,'S1');
INSERT INTO "filelog" VALUES('folder1','file1','2012-08-29 23:03:02',10,'S2');

替换我的表名,你的查询是

select folder, filename, count() 
from filelog group by folder, filename having count() < 3;

使用上面的数据,即使有两次失败,您的查询也不会返回任何行。 (或一个故障的两个副本。)修复它的第一步是声明一个可防御的主键。

CREATE TABLE filelog (
  folder text, 
  filename text, 
  datatime timestamp, 
  filesize integer, 
  filesource text,
  primary key (folder, filename, datatime)
);

该主键约束将阻止您两次输入单个传输。它允许您每天多次传输同一个文件,这在第一次传输失败时可能有意义。

-- Your failed transfer . . .
INSERT INTO "filelog" VALUES('folder1','file1','2012-08-29 23:01:02',10,'S1');
INSERT INTO "filelog" VALUES('folder1','file1','2012-08-29 23:03:02',10,'S2');
-- . . . and an earlier transfer that also failed.
INSERT INTO "filelog" VALUES('folder1','file1','2012-08-23 23:01:02',10,'S1');
INSERT INTO "filelog" VALUES('folder1','file1','2012-08-23 23:03:02',10,'S2');

您的查询将再次不返回任何行。我们需要更好地定义成功和失败的转移。

看来成功的转会具有这些特点。

  • 它包括所有三个来源 - S1、S2 和 S3。
  • 用于单个路径名,其中路径名表示文件夹+目录分隔符+文件名。
  • 时间戳遵循文件源顺序。换句话说,S1 的“datatime”在 S2 的“datatime”之前,S2 的“datatime”在 S3 的“datatime”之前。
  • 对于任何唯一的 {folder, filename, datatime},所有三个文件源的字节数都是相同的。

还有*大而麻烦的特性。 . .

  • 单个文件传输的所有三行必须属于单个“批次”(因为没有更好的词)。这意味着我们不能让查询将下面的前两行(传输失败)与下面的最后一行(成功传输的一部分)组合在一起,即使时间戳的顺序正确并且传输的字节是正确的.

    folder1  file1  2012-08-29 23:01:02  10  S1
    folder1  file1  2012-08-29 23:03:02  10  S2
    folder1  file1  2012-08-29 23:45:02  10  S1
    folder1  file1  2012-08-29 23:48:02  10  S2
    folder1  file1  2012-08-29 23:53:02  10  S3
    

有点复杂。而且我可能完全误解了您成功转移的标准。

(您可能可以为“数据时间”列取一个更好的名称。)

【讨论】:

    【解决方案2】:

    你完全误解了我的情况

    CREATE TABLE filelog (
       folder       text, 
       filename     text, 
       transferTime     timestamp, 
       filesize     integer, -- what time the transfer occurs at this filesource 
       filesource   text,
       primary key (folder, filename, filesource)
       );
    

    每个来源都会生成一个日志文件,其中包含他们传输或处理的文件。

    案例: 如果在 S1 的日志文件中找到 file1.txt,而在 S2 的日志文件中丢失,则说明 S1 和 S2 之间的传输失败。

    如果在 S1 和 S2 日志文件中都找到了 file1.txt,并且不在 S3 日志文件中,则 S2 和 S3 之间的传输失败,或者 S3 没有处理该文件。

    通过这个查询,我可以找到在 S2 或 S3 中丢失的文件:

    select folder, filename, filesource, count(*) 
    from filelog 
    group by folder, filename, filesource
    having count() < 3;
    

    回复你的时候我得到了答案,如果 count 是 1 这意味着在 S1 和 S3 传输失败, 或者如果 count 为 2,这意味着 S2 和 S3 之间的传输失败。

    感谢您的回复。 @catcall

    【讨论】:

    • 不,我想我理解得很好。您似乎缺少的——可能是因为它不可能发生,但也可能是因为你不理解 SQL——是您的查询在许多合理的情况下不会识别丢失的文件。在我的答案中搜索“也失败的早期转移”。在 S2 和 S3 之间失败的单个路径名的两次传输会留下 4 行。您的 group by folder, filename having count() &lt; 3 不会返回这些失败,因为 4 不小于 3。
    • 由于文件源作为主键包含在内,这确保在任何给定时间只有一个文件夹/文件@文件源实例可用,传输失败只会更新重新传输日期。我用一些样本数据进行了测试,发现答案是准确的。
    • 我明白了。在您在几分钟前编辑您的回复之前,文件源不是主键的一部分。很高兴您找到了解决方案。
    猜你喜欢
    • 2012-07-29
    • 1970-01-01
    • 2011-12-07
    • 1970-01-01
    • 1970-01-01
    • 2018-01-31
    • 2013-06-19
    • 1970-01-01
    • 2015-11-03
    相关资源
    最近更新 更多