【问题标题】:Amazon Redshift Keys are not enforced - how to prevent duplicate data?未强制执行 Amazon Redshift 密钥 - 如何防止重复数据?
【发布时间】:2013-02-16 17:16:23
【问题描述】:

刚刚测试了 AWS Redshift,并在插入时发现了一些重复数据,我希望这些重复数据在键列中的重复时会失败,阅读文档显示主键约束不是' t “强制”。

任何人都想出了如何防止主键重复(根据“传统”期望)。

感谢所有 Redshift 先驱!

【问题讨论】:

  • 我认为无论您使用什么代码进行发布,都需要首先运行查询以验证具有该键的记录不存在。
  • 我希望避免这种情况。一个容易考虑的情况是细化到小时的时间维度。我希望只插入可能在维度查询中使用的行,但是如果我必须选择然后插入数据跨越的每个可能的小时,而这些小时被数百万行使用 - 这太疯狂了。事实表有一个时间键,yyyy_mm_dd_hh - 这个键链接到扩展数据的维度表(年,月,日,星期几,周,业务季度等)当然希望有一个替代...
  • Saeven,你有没有找到解决办法?
  • 我求助于在 diff 连接上使用 MySQL 表作为中介,在将数据添加到成为问题的维度表之前权衡一组因素。从清洁度的角度来看,这不是最佳选择,但是考虑到影响决策的商业因素,我别无选择。
  • 该死,我希望听到你想出一个纯粹的 AWS 解决方法。我可能最终也不得不做类似的事情。 :(

标签: sql amazon-web-services amazon-redshift


【解决方案1】:

我在创建记录时分配 UUID。如果记录本质上是唯一的,我使用类型 4 UUID(随机),如果不是,我使用类型 5(SHA-1 哈希),使用自然键作为输入。
然后,您可以非常轻松地关注 AWS 的 this instruction 来执行 UPSERT。如果您的输入有重复,您应该能够通过在暂存表中发出类似于以下内容的 SQL 来进行清理:

CREATE TABLE cleaned AS
SELECT
  pk_field,
  field_1,
  field_2,
  ...  
FROM (
       SELECT
         ROW_NUMBER() OVER (PARTITION BY pk_field order by pk_field) AS r,
       t.*
       from table1 t
     ) x
where x.r = 1

【讨论】:

  • 这可能是一种有趣的方式来恢复显着性以优化查询速度。感谢分享恩诺。我从没想过添加中间维护步骤——我不知道这会在非常大的数据步骤上产生什么样的节省。很容易实现自动化。
  • 嗨@Saeven!您在生产中使用过这种方法吗?你能分享你的反馈吗?或者你有没有找到更好的选择,谢谢
【解决方案2】:

如果添加标识列用作 rowid 为时已晚(ALTER 不允许您在 Redshift 中添加 IDENTITY 列),您可以这样做:

  • 将所有欺骗行提取到临时表(使用DISTINCT 消除欺骗)
  • 从主表中删除这些行
  • 将行重新插入到主表中

这是一个示例:(假设id 是您检查欺骗的关键,data_table 是您的表)

CREATE TEMP TABLE delete_dupe_row_list AS
    SELECT t.id FROM data_table t WHERE t.id IS NOT NULL GROUP BY t.id HAVING COUNT(t.id)>1;
CREATE TEMP TABLE delete_dupe_rows AS
    SELECT DISTINCT d.* FROM data_table d JOIN delete_dupe_row_list l ON l.id=d.id;
START TRANSACTION;
DELETE FROM data_table USING delete_dupe_row_list l WHERE l.id=data_table.id;
INSERT INTO data_table SELECT * FROM delete_dupe_rows;
COMMIT;
DROP TABLE delete_dupe_rows;
DROP TABLE delete_dupe_row_list;

【讨论】:

  • 这看起来应该可以工作(因此我猜测那些没有尝试过或在 Redshift 以外的数据库上使用过的人会投赞成票),但不幸的是它不是因为 DISTINCT在语句中 SELECT DISTINCT d.* FROM data_table d JOIN delete_dupe_row_list l ON l.id=d.id; Redshift 不接受 - 结果包含原始表中的所有重复项,这意味着它们都进入 delete_dupe_rows 表并稍后重新插入。
【解决方案3】:

确认,他们不强制执行:

唯一性、主键和外键约束是信息性的 只要;它们不是由 Amazon Redshift 强制执行的。尽管如此,初级 键和外键用作计划提示,它们应该是 如果您的 ETL 流程或您的应用程序中的某些其他流程声明 强制他们的完整性。

例如,查询计划器使用主键和外键 某些统计计算,以推断唯一性和参考性 影响子查询去相关技术的关系,以排序 大量的连接,并消除冗余连接。

计划者利用这些关键关系,但它假设所有 Amazon Redshift 表中的键在加载时有效。如果你的 应用程序允许无效的外键或主键,一些查询 可能会返回不正确的结果。例如,一个 SELECT DISTINCT 查询 如果主键不唯一,可能会返回重复的行。不要 如果您怀疑它们的有效性,请为您的表定义关键约束。在 另一方面,您应该始终声明主键和外键,并且 当您知道它们是有效的时,唯一性约束。

Amazon Redshift 确实强制执行 NOT NULL 列约束。

http://docs.aws.amazon.com/redshift/latest/dg/t_Defining_constraints.html

【讨论】:

    【解决方案4】:

    是的,你不能那样做。目前,我认为您应该只插入带有额外时间戳列的重复数据(基本上是重复的键)。因此它将包含该特定行的所有版本,因为更新也是一个插入,当您查询 Redshift 时,请确保选择最新的。

    【讨论】:

      【解决方案5】:

      一种快速而肮脏的方法是使用 group by

      select max(<column_a>), max(<column_a>), <pk_column1>, <pk_column2>
      from <table_name>
      group by <pk_column1>, <pk_column2>
      

      【讨论】:

      • 由于这个数据集的庞大,在输出数据时欺骗数据不是一种选择——这个问题真的与在输入的过程中保持干净是同心的。不过谢谢...欣赏整个方孔圆钉。
      【解决方案6】:

      我正在使用 IDENTITY 自动增加我的主键。

      这是我在 AWS 论坛上提出的一个问题:

      https://forums.aws.amazon.com/message.jspa?messageID=450157#450157

      【讨论】:

      • 这没有回答问题。
      猜你喜欢
      • 2013-03-20
      • 2013-02-22
      • 2018-04-22
      • 1970-01-01
      • 2018-09-12
      • 2015-08-14
      • 2016-09-25
      • 2021-12-11
      • 1970-01-01
      相关资源
      最近更新 更多