如何约束具有大量非唯一组合的组合键?

How do you constrain a composite key that has a large number of non-unique combinations?

所以给定一个看起来像这样的 table 结构:

 Order_date DATE
 Order_id   NUMBER
 State      VARCHAR2(16)
 ...
 other properties/attributes

请记住,我可以在此处使用整数序列并生成 PK,但是我对此不感兴趣,因为我在主应用程序中使用 table。

所以复合键是由Order_date、Order_id和State组成的。这种组合的问题是它不一定是唯一的,但它在某种程度上受到限制。

例如:

Order_date  |  Order_id  |  State
21-09-2014     7218821      Pending
22-09-2014     2771272      Pending
20-09-2014     3277127      Approved
13-08-2014     2218765      Done
13-08-2014     2218765      Cancelled

约束条件:

我对 Oracle 数据库实施这些约束的最佳方式是什么?

第一个由主键或唯一键处理。

第二个是棘手的。第二个可以用基于函数的唯一键来处理,因为 Oracle 允许 NULL:

的多个值
create unique index unq_order_date_id_done on 
    orders(order, order_date, order_id, 
           (case when state = 'DONE' then state end));

我认为第三个和第四个需要一个触发器来防止添加值。

逐个子弹:

  • 这很可能是真实的,不需要监控。尽管您没有显示它,但 DATE 字段包含精确到秒的时间。为了复制,同一订单的状态必须在同一秒内更改两次。
  • 存疑。除非您的处理允许同一订单在一秒内发生多个状态更改。
  • 您的示例数据显示“完成”状态。那是怎么到那里的?
  • 您的描述表明,在 APPROVED 之后,唯一允许的状态是 DONE 或 CANCELED 或 ERROR。您的示例数据显示从完成到取消的订单。这似乎是不允许的。实际上,您的第二个项目符号表明在任何情况下都不允许出现 ERROR 状态。

您可以拥有重复(订单、日期)值的唯一方法是状态变化发生得非常快——在同一秒内。或者...您截断日期字段中的时间值。这似乎不太可能,因为没有理由丢弃像记录状态更改的时间这样有价值的信息。您没有任何好处,处理变得更加困难:lose/lose.