【问题标题】:Normalize data before loading to database or use database?在加载到数据库或使用数据库之前规范化数据?
【发布时间】:2019-01-17 07:11:14
【问题描述】:

我有一些数据要添加到现有的 mysql 数据库中。新数据可能包含已保存在 DB 中的条目。由于我的某些列是唯一的,因此如预期的那样,我收到了 ER_DUP_ENTRY 错误。

批量插入

假设我想使用以下语句将“A”、“B”和“C”保存在表 mytable 的列 names 中,并且“A”已经保存在那里。

insert into mytable (names) values ("A"), ("B"), ("C");

有没有办法直接使用bulk insert来保存“B”和“C”而忽略“A”?还是我必须为每个新行构建一个insert 语句?这就引出了另一个问题:

标准化数据

我是否应该保证在实际的insert 声明之前不上传重复条目?在我的情况下,我需要select 数据库中的数据,消除重复项,然后执行上面看到的insert。或者这是一个应该由数据库完成的任务?

【问题讨论】:

  • 大多数情况下,我相信这是由数据库服务器处理的。看看这个堆栈问题:stackoverflow.com/q/3164505/3148109
  • 如果我做对了,我不能使用批量插入来完成该任务吗?因为它在那里显示的方式,它会检查每个条目是否已经存在。

标签: mysql database-design relational-database


【解决方案1】:

如果您有阻止导入的 UNIQUE 约束,您有几种方法可以解决这个问题:

INSERT IGNORE INTO mytable ...

如果任何单独的行违反了 UNIQUE 约束,它们将被跳过。插入其他行。

REPLACE INTO mytable ...

如果任何行违反了 UNIQUE 约束,则删除现有行,然后插入新行。请记住这样做的副作用,例如,如果您有在删除时级联引用已删除行的外键。或者,如果 INSERT 生成一个新的自动增量 ID。

INSERT INTO mytable ... ON DUPLICATE KEY UPDATE ...

更灵活。这不会删除原始行,但允许您根据具体情况为您选择的任何列设置新值。另请参阅我对"INSERT IGNORE" vs "INSERT ... ON DUPLICATE KEY UPDATE"的回答

如果您想通过 mysqlimport 或等效的 SQL 语句 LOAD DATA INFILE 使用批量加载,则有一些选项匹配 INSERT IGNORE 或 REPLACE 解决方案,但不匹配 INSERT...ON DUPLICATE KEY UPDATE 解决方案。

阅读文档了解更多信息:

【讨论】:

    【解决方案2】:

    在某些情况下,我喜欢这样做:

    1. LOAD DATA 进入临时表
    2. 清理数据
    3. 根据需要进行标准化。 (每列需要规范化的 2 个 SQL——details
    4. 增强汇总表 (INSERT .. ON DUPLICATE KEY .. SELECT x, y, count(*), sum(z), .. GROUP BY x,y)
    5. 将干净的数据从临时表复制到真实表(“Fact”表)。 (INSERT [IGNORE] .. SELECT [DISTINCT] .. 或 IODKU 与 SELECT。)

    更多关于规范化:

    • 我在任何交易之外进行。这样做更好的原因有很多。
    • 在最坏的情况下(由于其他故障),我偶尔会在规范化表中抛出一个未使用的条目。没什么大不了的。
    • 不会烧毁AUTO_INCREMENT id(边缘情况除外)。
    • 非常快。

    由于REPLACEDELETE 加上INSERT,它几乎肯定会比IODKU 差。但是,当行存在时,两个都会刻录 id。

    如果可能,不要“循环”遍历行;而是找到 SQL 语句来一次性处理它们。

    根据详细信息,在第 2 步(如果有大量重复数据)或第 5 步(不常见重复数据)中删除重复数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-05-23
      • 2013-11-10
      • 2012-10-08
      • 2012-06-21
      相关资源
      最近更新 更多