数据库设计:需要唯一的行+关系
假设我有下表:
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
一个组合键来保证每行的唯一性? - 如果#1 的答案是“是”,则意味着当前 PK
product_id
不会被定义为密钥;相反,它只是一个自动递增的列。这足以让其他表用来创建与product
表中特定行的关系吗?
请注意,在某些情况下,表可能有 10 个或更多需要唯一的列。这将是定义复合键的很多列!这是一件坏事吗?
我正在尝试决定是否应该尝试在数据库层或应用程序层中强制执行这种唯一性。我觉得我应该在数据库级别执行此操作,但我担心使用非键作为 FK 或让如此多的列定义复合键可能会产生意想不到的副作用。
Say I have the following table:
TABLE: product
============================================================
| product_id | name | invoice_price | msrp |
------------------------------------------------------------
| 1 | Widget 1 | 10.00 | 15.00 |
------------------------------------------------------------
| 2 | Widget 2 | 8.00 | 12.00 |
------------------------------------------------------------
In this model, product_id
is the PK and is referenced by a number of other tables.
I have a requirement that each row be unique. In the example about, a row is defined to be the name
, invoice_price
, and msrp
columns. (Different tables may have varying definitions of which columns define a "row".)
QUESTIONS:
- In the example above, should I make
name
,invoice_price
, andmsrp
a composite key to guarantee uniqueness of each row? - If the answer to #1 is "yes", this would mean that the current PK,
product_id
, would not be defined as a key; rather, it would be just an auto-incrementing column. Would that be enough for other tables to use to create relationships to specific rows in theproduct
table?
Note that in some cases, the table may have 10 or more columns that need to be unique. That'll be a lot of columns defining a composite key! Is that a bad thing?
I'm trying to decide if I should try to enforce such uniqueness in the database tier or the application tier. I feel I should do this in the database level, but I am concerned that there may be unintended side effects of using a non-key as a FK or having so many columns define a composite key.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
当您有很多列需要创建唯一键时,请使用这些列中的数据作为源来创建您自己的“键”。这意味着在应用程序层创建密钥,但数据库将“强制”唯一性。一种简单的方法是使用记录的所有数据集的 md5 哈希值作为唯一密钥。然后,您只需在关系中需要使用一条数据。
md5 不能保证唯一,但它可能足以满足您的需求。
When you have a lot of columns that you need to create a unique key across, create your own "key" using the data from the columns as the source. This would mean creating the key in the application layer, but the database would "enforce" the uniqueness. A simple method would be to use the md5 hash of all the sets of data for the record as your unique key. Then you just have a single piece of data you need to use in relations.
md5 is not guaranteed to be unique, but it may be good enough for your needs.
首先,如果您可以轻松地做到这一点,那么您在数据库层中执行此操作的直觉是正确的。这意味着即使您的应用程序逻辑发生变化,您的数据库约束仍然有效,从而降低了出现错误的机会。
但是,您确定想要独一无二吗?我可以很容易地看到同一个小部件有不同的价格,比如出售物品或其他物品。
我建议不要强制执行唯一性,除非有真正的理由。
你可能有这样的东西(显然,不要在生产代码中使用 * )
First off, your intuition to do it in the DB layer is correct if you can do it easily. This means even if your application logic changes, your DB constraints are still valid, lowering the chance of bugs.
But, are you sure you want uniqueness on that? I could easily see the same widget having different prices, say for sale items or what not.
I would recommend against enforcing uniqueness unless there's a real reason to.
You might have something like this (obvoiusly, don't use * in production code)
您可以定义复合主键和唯一索引。只要满足您的要求,定义复合唯一键并不是一个糟糕的设计。显然,您添加的列越多,更新键和搜索键的过程就越慢,但如果业务需求需要这样做,我不认为这是负面的,因为他们有非常优化的例程来执行这些操作。
You can define composite primary keys and also unique indexes. As long as your requirement is met, defining composite unique keys is not a bad design. Clearly, the more columns you add, the slower the process of updating the keys and searching the keys, but if the business requirement needs this, I don't think it is a negative as they have very optimized routines to do these.