Mysql 数据库设计:使用复合键作为FK,标记数据以供共享?

Mysql 数据库设计:使用复合键作为FK,标记数据以供共享?,mysql,database,data-modeling,database-design,Mysql,Database,Data Modeling,Database Design,假设多个供应商销售相同的产品。每种产品都有多种可能的颜色。最后,假设数据库的初始状态是它不知道这些产品或其相应的颜色。供应商将添加产品和颜色信息 各表: TABLE: vendor ================================ | vendor_id | name | -------------------------------- | 1 | ABC Limited | ---------------------------

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

各表:

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保持唯一性,产品颜色映射表用于关联产品和颜色

在上面的示例中,小部件1可以是红色、白色或蓝色,而小部件2可以是红色、黄色或绿色

问题1:

我需要一个供应商产品表来列出供应商正在销售的实际产品。如何在数据库中存储ABC有限公司正在销售的红色小部件1?这张桌子看起来像这样吗:

TABLE: vendor_product
=====================================
| vendor_id | product_id | color_id |
-------------------------------------
| 1         | 1          | 1        |
-------------------------------------
                     Emerald Green
                     Emerald-Green
                     Emmerald Green
我遇到的问题是product_id和color_id是product_color_映射表中的复合键。我不确定使用复合键作为外键的正确方法是什么

问题2:

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

下次供应商1进入另一个产品时,我想向供应商1提供Widget 1作为可选项,基本上说,嘿,供应商1,您以前进入过这个产品。这是您再次尝试输入的产品吗?。然后,供应商1可以选择以前输入的产品或输入新产品。如果供应商1选择了小部件1,那么我想说嘿,供应商1,您将之前的小部件1标识为红色。这个新的小部件1也是红色的吗供应商1可以从中选择红色或输入新颜色

当供应商2出现时,我如何允许它也将小部件1添加到其库存中,而不会在数据库中有重复的小部件1

最后,我如何将Widget 1和Red标识为有效信息,并使其可供所有供应商使用,而不仅仅是首先输入信息的供应商1


注意:我并不是想为产品和颜色找到解决方案。产品将具有多个与之相关的属性,例如尺寸,如小型、中型或大型。颜色也可能有几个与之相关的属性——这些属性可能有自己的属性,以此类推。供应商将输入所有这些信息。

这是很多问题

我需要一个要列出的供应商产品表 供应商的实际产品是什么 销售。我如何储存在商店里 ABC有限公司正在出售的数据库 红色小工具1?这张桌子看起来怎么样 像这样:

TABLE: vendor_product
=====================================
| vendor_id | product_id | color_id |
-------------------------------------
| 1         | 1          | 1        |
-------------------------------------
                     Emerald Green
                     Emerald-Green
                     Emmerald Green
如果你只想处理身份证号码,是的,看起来就是这样。但由于供应商名称、产品名称和颜色名称都必须是唯一的,因此您也可以这样存储数据

vendor_name    product_name    color_name
--
ABC Limited    Widget 1        Red
我不知道正确的方法是什么 将复合键用作外键

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

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

组合框下拉框 列表框 单选按钮 多选按钮 智能补全文本框 具有以下任意组合的新窗口: 以上 等 在数据库方面,任何一个的底层查询都可能类似于SELECT。。。来自供应商的产品。可能使用产品颜色映射或产品

当供应商2出现时,我该怎么做 允许它也将小部件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 
这些都是独一无二的。就数据库而言。用户界面设计师面临的挑战是如何使产品入口易于正确操作,从而使供应商不会倾向于创建伪副本

最后,如何识别小部件1 红色为有效信息

通常,我会说使用外键创建product\u color\u映射表。但是看起来你的目标是有很多不同的表,这些表可能是你的目标。小部件1和红色我们已经知道了,但除此之外,还有小部件1和小部件,小部件1和红色,小部件1和豪华

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

这是在多个领域中需要解决的一个相当常见的问题,在这些领域中,多个客户对一个公共数据库结构做出贡献,但不需要 我不想看到彼此的数据。例如,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'
您可以创建复合键primary、foreign和alternate unique,如下所示[伪语法]:

             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')
您必须在颜色表中执行此操作:

            UNIQUE index on (color)
然而,如果颜色表中已经存在特定的颜色,这将阻止供应商B将“翡翠绿”添加到颜色表中用于其产品,但供应商B无法看到该颜色,因为如果虚拟专用数据库或类似方法生效,该行将从其视图中过滤出去

因此,如果您的目标是让多条数据支流流入一条公共数据河,可以说,每个供应商都可以在其中自由畅游,然后,您会遇到一个潜在的混乱情况,通常需要由集中维护的中心管理员维护颜色和PRODUCTCATEGORY等表,因为这种情况通常会导致如下数据:

TABLE: vendor_product
=====================================
| vendor_id | product_id | color_id |
-------------------------------------
| 1         | 1          | 1        |
-------------------------------------
                     Emerald Green
                     Emerald-Green
                     Emmerald Green

i、 几乎和支流一样多的变体,所以您的唯一索引变得相当无效。认为他们在站岗是不是很好。只有一条支流会出现此问题!在只有一个人添加数据的情况下保持这些表的正常运行是一个挑战!要消除这种slop,需要一个专门的数据管理员不断提高警惕,并对批量导入进行比大多数公司愿意进行的更多的清理

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

                   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
然后,当您用颜色描述产品时,OODMB将执行以下规则:

                   Product.ColorId IN (select colorid from master colors UNION select colorid from VendorAColors)
当然,您必须确保ID中没有冲突。ID不能是简单的自动递增整数。每个供应商可能被分配一定范围内的值,或具有一定的前缀,以区分其ID与彼此的ID和主ID,或作为GUID


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

我现在了解了如何将复合键用作FK。谢谢至于我的第2期,它不是一个真正的UI问题。我需要能够查询数据库中某个供应商输入的值,以便提供这些选项。无论如何,数据必须与供应商相关联。至于供应商2输入供应商1已经输入的Widget 1,我不想要一个重复的Widget 1,假设DB中没有拼写错误等-现在我想知道供应商2之前输入了Widget 1,所以我也可以对供应商2说嘿,您之前已经输入了此项。您的供应商\产品表将为您提供每个供应商输入的产品。产品名称上的唯一约束可防止重复的产品名称。@Tim-您完美地描述了我的问题!不过,当你开始谈论数据分支时,我有点不知所措。假设我让一个人查看数据,选择哪一个是好的,然后标记为是的,这是好的,其他供应商现在可以看到这一点-我需要对我的模型做什么?@Tim-还有,当我说供应商a的翡翠绿是数据的正确版本时会发生什么?如何处理供应商b的翡翠绿?谁有权编辑翡翠绿?我担心的是,大部分数据完整性必须由应用程序而不是数据库来处理;我不想这样。@StackOverflowNewbie:如果您向用户显示数据,以便用户可以标记数据的好坏,那么它已经在您的数据库中,并且已经通过了数据验证和引用完整性约束,就数据库而言,它是好数据。除非您考虑到一些包含好数据和坏数据的混合的初步暂存数据库,这些数据将被适当地标记,然后移动到生产数据库中。暂存区域通常不会像生产数据库那样具有有效的完整约束集。continuation。。。你脑子里想的是一个非此即彼的场景,在这个场景中,你试图得到一个系统范围内的翡翠绿。如果您有一个主颜色表,其中所有供应商都必须看到表中的所有颜色,而不仅仅是对他们重要的颜色子集,那么这将运行计数器t
o要求每个供应商必须能够引用自己的行。每个供应商都拥有行的子集,或者所有供应商都可以看到其他行。您不能同时拥有它。每个虚拟专用数据库都必须是自己的域。也就是说,vendorId必须包含在每个键中,这允许在颜色表中有多个翡翠绿实例。但复合键是Vendor1祖母绿和Vendor2祖母绿。不能仅在COLORS.colorname列上放置唯一索引。