数据库设计:需要唯一的行+关系

发布于 2024-10-30 08:42:10 字数 1077 浏览 1 评论 0原文

假设我有下表:

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,并被许多其他表引用。

我要求每一行都是唯一的。在示例中,一行被定义为 nameinvoice_pricemsrp 列。 (不同的表可能对哪些列定义“行”有不同的定义。)

问题:

  1. 在上面的示例中,我应该创建 nameinvoice_pricemsrp 一个组合键来保证每行的唯一性?
  2. 如果#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:

  1. In the example above, should I make name, invoice_price, and msrp a composite key to guarantee uniqueness of each row?
  2. 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 the product 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

堇年纸鸢 2024-11-06 08:42:10

当您有很多列需​​要创建唯一键时,请使用这些列中的数据作为源来创建您自己的“键”。这意味着在应用程序层创建密钥,但数据库将“强制”唯一性。一种简单的方法是使用记录的所有数据集的 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.

泪痕残 2024-11-06 08:42:10

首先,如果您可以轻松地做到这一点,那么您在数据库层中执行此操作的直觉是正确的。这意味着即使您的应用程序逻辑发生变化,您的数据库约束仍然有效,从而降低了出现错误的机会。

但是,您确定想要独一无二吗?我可以很容易地看到同一个小部件有不同的价格,比如出售物品或其他物品。

我建议不要强制执行唯一性,除非有真正的理由。

你可能有这样的东西(显然,不要在生产代码中使用 * )

# 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

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)

# 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
柏林苍穹下 2024-11-06 08:42:10

您可以定义复合主键和唯一索引。只要满足您的要求,定义复合唯一键并不是一个糟糕的设计。显然,您添加的列越多,更新键和搜索键的过程就越慢,但如果业务需求需要这样做,我不认为这是负面的,因为他们有非常优化的例程来执行这些操作。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文