【问题标题】:Database Design: need unique rows + relationships数据库设计:需要唯一的行+关系
【发布时间】:2011-04-05 07:56:20
【问题描述】:

假设我有下表:

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

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

问题:

  1. 在上面的示例中,我是否应该将nameinvoice_pricemsrp 设为复合键以保证每一行的唯一性?
  2. 如果对#1 的回答是“是”,这意味着当前的PK product_id 不会被定义为密钥;相反,它只是一个自动递增的列。这是否足以让其他表用于创建与 product 表中特定行的关系?

请注意,在某些情况下,表可能有 10 个或更多列需要是唯一的。那将是很多定义复合键的列!这是一件坏事吗?

我正在尝试决定是否应该尝试在数据库层或应用程序层强制执行这种唯一性。我觉得我应该在数据库级别执行此操作,但我担心使用非键作为 FK 或有这么多列定义复合键可能会产生意想不到的副作用。

【问题讨论】:

    标签: mysql database data-modeling database-design


    【解决方案1】:

    当您有很多列需​​要创建唯一键时,请使用列中的数据作为源创建您自己的“键”。这意味着在应用层创建密钥,但数据库将“强制”唯一性。一个简单的方法是使用记录的所有数据集的 md5 哈希作为唯一键。然后,您只需要在关系中使用一条数据。

    md5 不保证是唯一的,但它可能足以满足您的需求。

    【讨论】:

    • 哦!我没有想到这一点。这可能是一个明显更好的解决方案。每次插入时都会产生散列成本,但这可能比拥有大量索引便宜。你怎么看?
    • 散列的成本是最低的,尤其是 md5。对于大型数据集中的查找,固定长度索引数据实际上更快。但您似乎不会为此使用大型数据集。
    【解决方案2】:

    首先,如果您可以轻松地做到这一点,那么您在 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
    

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-11
        • 2015-08-05
        • 2014-11-06
        • 1970-01-01
        • 2010-10-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多