说我有下表:
TABLE: product
============================================================
| product_id | name | invoice_price | msrp |
------------------------------------------------------------
| 1 | Widget 1 | 10.00 | 15.00 |
------------------------------------------------------------
| 2 | Widget 2 | 8.00 | 12.00 |
------------------------------------------------------------
在此模型中,product_id
是PK,并由许多其他表引用。
我要求每一行都是唯一的。在示例中,行被定义为name
,invoice_price
和msrp
列。 (不同的表可能对哪些列定义“行”有不同的定义。)
问题:
name
,invoice_price
和msrp
复合键以保证每行的唯一性吗?product_id
不会被定义为密钥;相反,它只是一个自动递增列。是否足以让其他表用于创建product
表中特定行的关系?请注意,在某些情况下,该表可能包含10个或更多列,这些列必须是唯一的。这将是定义复合键的很多列!这是件坏事吗?
我正在尝试决定是否应该尝试在数据库层或应用程序层中强制执行此类唯一性。我觉得我应该在数据库级别这样做,但我担心使用非密钥作为FK或有这么多列定义复合密钥可能会产生意外的副作用。
答案 0 :(得分:0)
首先,如果您可以轻松完成,那么您在DB层中执行此操作的直觉是正确的。这意味着即使您的应用程序逻辑发生更改,您的数据库约束仍然有效,从而降低了错误的可能性。
但是,你确定你想要独一无二吗?我可以很容易地看到相同的小部件有不同的价格,比如说是出售物品还是什么不是。
我建议不要强制执行唯一性,除非有真正的理由。
你可能有这样的东西(很明显,不要在生产代码中使用*)
# get the lowest price for an item that's currently active
select *
from product p
where p.name = "widget 1" # a non-primary index on product.name would be advised
and p.active
order-by sale_price ascending
limit 1
答案 1 :(得分:0)
您可以定义复合主键以及唯一索引。只要满足您的要求,定义复合唯一键并不是一个糟糕的设计。显然,你添加的列越多,更新密钥和搜索密钥的过程就越慢,但如果业务需求需要这个,我不认为它是负面的,因为它们有非常优化的例程来执行这些操作。
答案 2 :(得分:0)
当您需要创建一个唯一键时需要很多列时,请使用列中的数据作为源创建自己的“键”。这意味着在应用程序层中创建密钥,但数据库将“强制”实现唯一性。一种简单的方法是将记录的所有数据集的md5哈希值用作唯一键。那么你只需要在关系中使用一段数据。
md5不保证是唯一的,但它可能足以满足您的需求。