数据库设计:使用复合密钥作为FK,标记数据进行共享?

时间:2011-04-02 06:15:01

标签: mysql database data-modeling database-design

假设多个供应商销售相同的产品。每种产品都有许多可能的颜色。最后,假设数据库的初始状态是它不知道这些产品或其相应的颜色。供应商将添加产品和颜色信息。

表格:

TABLE: vendor
================================
| vendor_id | name             |
--------------------------------
| 1         | ABC Limited      |
--------------------------------
| 2         | Acme Corporation |
--------------------------------

TABLE: product
=========================
| product_id | name     |
-------------------------
| 1          | Widget 1 |
-------------------------
| 2          | Widget 2 |
-------------------------

TABLE: product_color_mapping
=========================
| color_id | product_id |
-------------------------
| 1        | 1          |
-------------------------
| 2        | 1          |
-------------------------
| 3        | 1          |
-------------------------
| 1        | 2          |
-------------------------
| 4        | 2          |
-------------------------
| 5        | 2          |
-------------------------

TABLE: color
=======================
| color_id | name     |
-----------------------
| 1        | Red      |
-----------------------
| 2        | White    |
-----------------------
| 3        | Blue     |
-----------------------
| 4        | Yellow   |
-----------------------
| 5        | Green    |
-----------------------

为了使color.name保持唯一,product_color_mapping表用于关联产品和颜色。

在上面的示例中,Widget 1可以是RedWhiteBlue,而Widget 2可以是Red,{ {1}}或Yellow

问题1:

我需要一个Green表来列出供应商销售的实际产品。如何在vendor_product销售ABC Limited Red的数据库中存储?表格看起来像这样:

Widget 1

我遇到的问题是TABLE: vendor_product ===================================== | vendor_id | product_id | color_id | ------------------------------------- | 1 | 1 | 1 | ------------------------------------- product_idcolor_id表中的复合键。我不确定将复合键用作外键的正确方法是什么。

问题2:

如上所述,产品和颜色信息将由供应商提供。假设供应商1没有产品并输入其第一个产品:product_color_mapping。然后,供应商1为产品指定颜色Widget 1

  • 下次供应商1进入另一个产品时,我想向供应商1提供Red作为可选项目(基本上说,“嘿供应商1,您之前输入过此产品。这是你试图再次进入的产品?“)。然后,供应商1可以选择先前输入的产品或输入新产品。如果供应商1选择了Widget 1,那么我想说“嘿供应商1,您将之前的Widget 1标识为颜色Widget 1。这是新的Red {{1} }}?” - 供应商1可以从中选择Widget 1或输入新颜色。

  • 当供应商2出现时,我如何允许它在其库存中添加Red而数据库中没有重复Red

  • 最后,如何将Widget 1Widget 1识别为“有效”信息 - 并将其提供给所有供应商(而不仅仅是第一个输入信息的供应商1)地方)?

注意:我不是想找到产品和颜色的解决方案。产品将具有与其相关联的若干属性(例如,尺寸,例如“小”,“中”或“大”)。颜色也可能有几个与之关联的属性 - 这些属性可能具有自己的属性,依此类推。供应商将输入所有这些信息。

3 个答案:

答案 0 :(得分:0)

这是很多问题。

  

我需要列出vendor_product表   供应商的实际产品   抛售。我如何存储在   ABC Limited正在出售的数据库   红色小工具1?桌子看起来如何   像这样:

如果你只想处理id号码,是的,它会是这样的。但由于供应商名称,产品名称和颜色名称都必须是唯一的,您还可以存储这样的数据。

vendor_name    product_name    color_name
--
ABC Limited    Widget 1        Red
  

我不确定正确的方法是什么   使用复合键作为外键。

FOREIGN KEY (product_id, color_id) 
      REFERENCES product_color_mapping (product_id, color_id)

FOREIGN KEY (product_name, color_name) 
      REFERENCES product_color_mapping (product_name, color_name)
  

下一次供应商1进入另一个   产品,我想提供   小部件1作为可选项   供应商1(基本上说,“嘿   供应商1,您输入了此产品   之前。

这是用户界面问题,而不是数据库问题。但是有很多方法可以将现有数据作为选择。

  • 组合框(下拉框)
  • 列表框
  • 单选按钮
  • 多选按钮
  • 智能完成的文本框
  • 新窗口(任意组合 以上)

在数据库方面,任何这些的基础查询都可能类似于SELECT ... FROM vendor_product。 (可以改用product_color_mapping或product。)

  

当供应商2出现时,我该怎么做   允许它也将Widget 1添加到其中   库存没有重复   数据库中的小部件1?

产品名称必须是唯一的,对吧?因此,第二个供应商无法使用现有产品的名称向表“product”添加另一行。这对您来说可能是一个持续存在的问题,因为供应商有可能输入这样的东西。

Canon Powershot A800 10 MP Digital Camera with 3.3x Optical Zoom 
Canon Powershot A800 10 M P Digital Camera with 3.3x Optical Zoom 
Canon Powershot A800 10 MP Digital Camera with 3.3x Otpical Zoom 
Canon Power Shot A800 10 MP Digital Camera with 3.3x Optical Zoom 
Canon Powershot A-800 10 MP Digital Camera with 3.3x Optical Zoom 
Canon Powershot A800 10 MP Digital Camera, 3.3x Optical Zoom 
Canon Powershot A-800 10 MP Camera, 3.3x Opt. Zoom 

这些都是独一无二的。 (就数据库而言。)用户界面设计者面临的挑战是如何使产品输入变得容易,供应商不倾向于创建伪重复。

  

最后,我如何识别Widget 1   和红色是“有效”信息

通常我会说使用product_color_mapping表的外键。但似乎你的目标是拥有许多可能成为目标的不同表格。我们已经知道“小工具1”和“红色”,但除此之外,你还将拥有“小工具1”和“小工具”,“小工具1”和“红色”以及“小工具1”和“豪华”。

答案 1 :(得分:0)

  

我需要能够查询数据库   某个供应商拥有的价值   进入,以便我可以提供那些   选项。不知何故,数据必须是   与供应商相关联。

这是一个相当普遍的问题,需要在多个域中解决,其中多个客户参与共同的数据库结构,但不希望看到彼此的数据。例如,Oracle就有一种称为虚拟专用数据库的东西。本质上,一列被添加到每个表中,并且给定行的列中的值指示谁“拥有”该行。视图可以基于此:

             CUSTOMERA : create view CUSTOMERAPRODUCTS as select * from products where products.user='CUSTOMERA'
             CUSTOMERB:  create view CUSTOMERBPRODUCTS as select * from products where products.user='CUSTOMERB'

您可以创建复合键(主要,外来和备用唯一),如[伪语法]:

             Table: COLORS
             vendorid INT
             colorid INT
             color  varchar(20)
             PK = (vendorid, colorid)
             UNIQUE index on (vendorid, color)

             Table: PRODUCTS
             vendorid INT
             productid INT
             product varchar(20)
             PK = (vendorid, productid)
             UNIQUE index on (vendorid, product)


             Table: PRODUCTCOLORS
             vendorid INT
             productid INT
             colorid INT
             PK = (vendorid, productid)
             UNIQUE index on (vendorid, color)

             FK (vendorid, productid) references PRODUCTS(vendorid, productid)
             FK (vendorid, colorid) references COLORS(vendorid, colorid)

但是,现在,如果您还想使这个特定规则(和类似规则)成为一项要求:

            Color values must be unique not only within the individual vendor's subset
            but unique system-wide (e.g. so that there is only one row containing 'Emerald Green')

您必须在COLORS表中执行此操作:

            UNIQUE index on (color)

然而,这会阻止供应商B将“Emerald Green”添加到COLORS表中,以便在表格中已存在特定颜色时使用其产品,但供应商B无法看到颜色,因为该行将被过滤掉如果“虚拟私人数据库”或该方法的某些模拟生效,他们的观点是什么,

所以,如果你的目标是让多个数据支流流入一个公共数据流,每个供应商都可以自由游泳,可以这么说,那么你有一个潜在的混乱局面,通常需要像COLOR和PRODUCTCATEGORY这样的表。由中央管理员维护 - 集中维护,因为这种情况通常会产生如下数据:

                     Emerald Green
                     Emerald-Green
                     Emmerald Green

即。几乎与支流一样多的“变种”,所以你的独特指数变得相当无效。认为他们站岗是不是很好。只有一个支流可以解决这个变种问题!只有一个的人添加数据才能保持这些类型的表格是一个挑战!要消除这种污点,需要专门的数据管理员保持警惕,并且批量进口的消毒程度远远超过大多数公司愿意参与的情况。

答案 2 :(得分:0)

解决问题的另一种方法是使用非关系或准关系OODBMS。您将具有声明性引用完整性的普通表单抛出窗口,并考虑类继承术语中的数据。您将拥有一个主颜色表,每个供应商都有自己的COLORS表,可以“扩展”主颜色表。您的OOBMBS可能会强制执行以下规则:

                   colorname cannot be added to Vendor A's COLORS table if it already exists in MasterColors
                   or if it already exists in Vendor A's colors table

然后,当您使用颜色描述产品时,您的OODMBS将强制执行此规则:

                   Product.ColorId IN (select colorid from master colors UNION select colorid from VendorAColors)

当然,你必须确保ids中没有碰撞。 ID不能简单地自动递增整数。可以为每个供应商分配特定范围内的值,或者具有特定前缀,以区分其ID与彼此的ID以及主ID,或者是GUID。

您当然可以在任何关系数据库中实现此功能,但它主要是数据存储区;使用声明性RI的机会很少....(编辑:当然,除非您的DBMS允许您针对具体化的视图声明此类约束。)