假设多个供应商销售相同的产品。每种产品都有多种可能的颜色。最后,假设数据库的初始状态是不知道这些产品或其对应的颜色。供应商将添加产品和颜色信息。
表格:
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
可以是Red
、White
或 Blue
而 Widget 2
可以是 Red
、Yellow
或 Green
。
问题 1:
我需要一个 vendor_product
表来列出供应商销售的实际产品。我如何在数据库中存储 ABC Limited
正在销售 Red
Widget 1
?表格会像这样吗:
TABLE: vendor_product
=====================================
| vendor_id | product_id | color_id |
-------------------------------------
| 1 | 1 | 1 |
-------------------------------------
我遇到的问题是 product_id
和 color_id
是 product_color_mapping
表中的复合键。我不确定将复合键用作外键的正确方法是什么。
问题 2:
如前所述,产品和颜色信息将由供应商提供。假设供应商 1 没有产品并输入其第一个产品:Widget 1
。供应商 1 然后为产品指定颜色 红色
。
下次供应商 1 输入另一个产品时,我想将
Widget 1
作为可选项目提供给供应商 1(基本上是说,“嘿,供应商 1,你之前输入过这个产品.这是您再次尝试输入的产品吗?”)。供应商 1 然后可以选择以前输入的产品或输入新产品。如果供应商 1 选择Widget 1
,那么我想说“嘿供应商 1,您将之前的Widget 1
标识为颜色Red
。是这个新的Widget 1
也是Red
?” -- 供应商 1 可以从中选择红色
或输入新颜色。当供应商 2 出现时,我如何允许它也将
Widget 1
添加到其库存中,而不在数据库中有重复的Widget 1
?最后,我如何将
Widget 1
和Red
识别为“有效”信息 - 并使其对所有供应商(不仅仅是供应商 1)可用谁首先输入了信息)?
注意:我并不是要寻找产品和颜色的解决方案。产品将具有多个与之关联的属性(例如尺寸,如“小”、“中”或“大”)。颜色也可能有几个与之相关的属性——这些属性可能有自己的属性等等。供应商将输入所有这些信息。
最佳答案
I need to be able to query the DB for values that a certain vendor has entered so that I can offer those as options. Somehow, the data must be associated with the vendor.
这是一个相当普遍的问题,需要在多个领域中解决,在这些领域中,多个客户贡献了一个共同的数据库结构,但不想看到彼此的数据。例如,甲骨文有一种叫做虚拟专用数据库的东西。实际上,每个表都会添加一列,给定行的列中的值表示谁“拥有”该行。 View 可以基于此:
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 将“ Jade 绿”添加到 COLORS 表以用于其产品,但供应商 B 看不到该颜色,因为该行将被过滤掉如果“虚拟私有(private)数据库”或该方法的某种类似物生效,他们的观点,
因此,如果您的目标是让多个数据支流流入一条公共(public)数据河,每个供应商都可以在其中自由畅游,可以这么说,那么您的情况可能很困惑,通常需要像 COLOR 和 PRODUCTCATEGORY 这样的表来由中央管理员维护——集中维护是因为这种情况通常会导致数据看起来像这样:
Emerald Green
Emerald-Green
Emmerald Green
即几乎与支流一样多的“变体”,因此您的唯一索引变得相当无效。认为他们站岗是不是很漂亮。你可以只用一个支流来解决这个变体问题!在只有 一个 人添加数据的情况下保持这些类型的表是一个挑战!要消除这种浪费,需要专门的数据管理员时刻保持警惕,并且对批量导入进行更多的清理,这比大多数公司愿意从事的要多得多。
关于mysql - 数据库设计 : use composite key as FK, 标志数据共享?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5521541/