这是一个两部分问题。
我有一些我想要读入数据库的日志文件。日志文件包含不必要的字段(因为它们可以从其他字段计算)。
方法1:我应该解析日志文件的每一行并将其插入数据库吗?
Con:日志条目必须是唯一的,因此我需要首先执行SELECT,检查LogItemID是否存在,然后检查是否存在。这似乎是一个很高的开销活动,在某些时候,这将每小时完成。
方法2:或者我是否使用LOAD DATA INFILE(我甚至可以在PHP中使用它?)并将日志文件加载到临时表中,然后将记录移动到永久表中?
Con:即使在这种方法中,我仍然需要经历SELECT循环,然后INSERT。
方法3:或者有更好的方法吗?是否有命令使用选定的字段将记录从一个表批量复制到另一个表?将REPLACE INTO ....在DUPLICATE UPDATE工作(如果项目存在,我不想更新,只是忽略),只要LogItemID设置为UNIQUE?无论哪种方式,我都需要抛弃无关的字段。哪种方法更好?不仅更容易,而且从编写优秀,可扩展的代码的角度来看?
P.S。不相关,但这里的架构问题的一部分是这个...... 如果我有StartTime,EndTime和Interval(EndTime-StartTime),我应该保留 - 前两个还是Interval?为什么?
编辑:澄清为什么我不想存储所有三个字段 - 问题当然是规范化,因此不是好的做法。出于审计原因,也许我会存储它们。也许在另一张桌子上? TIA
答案 0 :(得分:1)
您可以使用perl来解析要加载的csv字段的子集,然后使用命令' uniq'删除重复项,然后使用LOAD DATA INFILE加载结果。
通常将数据加载到临时表中,然后遍历比提前预处理数据要慢。对于LogItemID,如果将其设置为unique,则在加载后续匹配行时插入应该失败。
当决定存储StartTime + Interval(通常称为Duration)或StartTime和EndTime时,它实际上取决于您计划如何使用生成的数据库表。如果您存储持续时间并且不断计算结束时间,那么仅存储开始/结束可能会更好。如果您认为持续时间是常用的,请存储它。根据您可能决定只存储所有三个数据库的数据库的大小,再多一个字段可能不会增加太多开销。
答案 1 :(得分:1)
LOAD DATA INFILE
比运行单个插入要快得多。
您可以加载到单独的临时表,然后从临时表中运行INSERT ... SELECT
到您的实际商店。但不清楚为什么你需要这样做。到"跳过" CSV中的某些字段,只需将这些字段分配给虚拟用户定义变量即可。无需将这些字段加载到临时表中。
我定义了UNIQUE
键(约束),只使用INSERT IGNORE
;这比运行单独的SELECT
要快得多,并且比REPLACE
更快。 (如果您的要求是您不需要更新现有行,您只需要"忽略"新行。
LOAD DATA INFILE 'my.csv'
IGNORE
INTO TABLE mytable
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
( mycol
, @dummy2
, @dummy3
, @mm_dd_yyyy
, somecol
)
SET mydatecol = STR_TO_DATE(@mm_dd_yyyy,'%m-%d-%Y')
如果您有start
,end
和duration
,请继续存储这三个。那里有冗余,主要问题是性能和更新异常。 (如果您更新end
,是否还要更新duration
?)如果我不需要更新,我只会存储这三个。我可以从duration
和start_time
计算end_time
,但保存列可以让我添加索引,并在查找持续时间少于10分钟的查询中获得更好的性能,或者其他。如果没有该列,我将被迫评估表中每一行的表达式,并且在大型集合上会变得昂贵。