数据库多对多中间表:额外字段

时间:2011-02-15 13:15:24

标签: mysql database database-design normalization join

我创建了“商店”和“客户”表以及中间表customers_shops。每个商店都有site_url网址,但有些客户使用替代网址访问商店的网站(此网址对于特定客户而言是唯一的)。

在下面的中间表中,我添加了一个附加字段shop_site_url。我的理解是这是第二种规范化形式,因为the shop_site_url字段对于特定客户和商店是唯一的(因此不会为不同的客户/商店重复)。此外,由于它取决于客户和商店,我认为这是第三种标准化形式。我只是不习惯使用'mapping'表(customers_shops)来包含其他字段 - 下面的设计是否有意义,或者我应该保留中间表纯粹作为转换多个 - - 一对一的多种关系?

######
customers
######

id INT(11) NOT NULL PRIMARY KEY
name VARCHAR(80) NOT NULL

######
shops
######

id INT(11) NOT NULL PRIMARY KEY
site_url TEXT

######
customers_shops
######

id INT(11) NOT NULL PRIMARY KEY
customer_id INT(11) NOT NULL
shop_id INT(11) NOT NULL
shop_site_url TEXT //added for a specific url for customer

由于

5 个答案:

答案 0 :(得分:2)

您所谓的“中间”表不是特殊类型的表。只有一种表格,相同的设计原则应该适用于所有人。

答案 1 :(得分:1)

您的架构确实有意义,因为shop_site_url是关系本身的属性。您可能希望为其指定一个更有意义的名称,以便将其与shops.site_url区分开来。

答案 2 :(得分:1)

好吧,让我们创建表格,插入一些示例数据,然后查看结果。

id cust_id  shop_id  shop_site_url
--
1  1000     2000     NULL
2  1000     2000     http://here-an-url.com
3  1000     2000     http://there-an-url.com
4  1000     2000     http://everywhere-an-url-url.com
5  1001     2000     NULL
6  1001     2000     http://here-an-url.com
7  1001     2000     http://there-an-url.com
8  1001     2000     http://everywhere-an-url-url.com

嗯。 看起来不太好。让我们忽略一分钟的备用URL。要创建解析m:n关系的表,需要对构成m:n关系的列进行约束。

create table customers_shops (
    customer_id integer not null references customers (customer_id),
    shop_id integer not null references shops (shop_id),
    primary key (customer_id, shop_id)
);

(我删除了“id”列,因为它会掩盖正在发生的事情。如果你愿意,你可以稍后添加。)

插入一些示例数据。 。 。然后

select customer_id as cust_id, shop_id
from customers_shops;

cust_id  shop_id
--
1000     2000
1001     2000
1000     2001
1001     2001

那更接近了。您应该在此类表格中每个客户和商店组合只有一行。 (即使没有网址,这也是有用的数据。)现在我们如何处理替代网址?这取决于几件事。

  • 客户是否通过访问网站 只有一个URL,或者他们可能会使用更多 不止一个?

如果答案是“只有一个”,那么您可以在此表中为该列添加一列,并使该列唯一。这是该表的候选键。

如果答案是“不止一个 - 至少是网站网址和备用网址”,那么您需要对约束做出更多决定,因为更改此表以允许每个客户组合的多个网址和商店削减了这一要求:

  

shop_site_url字段对于a是唯一的   特别是客户和商店   (因此不会重复   不同的客户/商店)

基本上,我要求你决定这个表的含义 - 定义表的谓词。例如,这两个不同的谓词导致不同的表结构。

  • 客户'n'访问过该网站 使用网址'
  • 购买'm'
  • 客户'n'被允许访问 使用备用商店'm'的网站 url's'

答案 3 :(得分:0)

您还可以在哪里提供此信息?它不是商店的属性,也不是客户的属性。你可以将它放在一个单独的表中,如果你想避免使用NULLable列,但是你最终必须从这个新表中引用你的中间表,这可能是看起来甚至更奇怪了。

答案 4 :(得分:0)

关系可以有属性,就像实体可以拥有属性一样。

实体属性进入实体表中的列。关系属性,至少对于多对多关系,进入关系表。

听起来好像,一般来说,网址是由商店和客户的组合决定的。所以我会把它放在商店顾客桌上。许多商店只有一个URL这一事实表明存在第五种比这更微妙的正常形式。但是我懒得去解决它。