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

发布于 2024-10-17 20:50:03 字数 781 浏览 2 评论 0原文

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

在下面的中间表中,我添加了一个附加字段 shop_site_url。我的理解是,这是第二种标准化形式,因为 shop_site_url 字段对于特定客户和商店来说是唯一的(因此不会为不同的客户/商店重复) 。另外,由于这取决于客户和商店,我认为这是第三标准化形式。我只是不习惯使用“映射”表(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

谢谢

I have created a 'shops' and a 'customers' table and an intermediate table customers_shops. Every shop has a site_url web address, except that some customers use an alternative url to access the shop's site (this url is unique to a particular customer).

In the intermediate table below, I have added an additional field, shop_site_url. My understanding is that this is in 2nd normalised form, as the shop_site_url field is unique to a particular customer and shop (therefore won't be duplicated for different customers/shops). Also, since it depends on customer and shop, I think this is in 3rd normalised form. I'm just not used to using the 'mapping' table (customers_shops) to contain additional fields - does the design below make sense, or should I reserve the intermediate tables purely as a to convert many-to-many relationships to one-to-one?

######
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

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

梨涡 2024-10-24 20:50:03

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

What you are calling an "intermediate" table is not a special type of table. There is only one kind of table and the same design principles ought to be applicable to all.

梦在夏天 2024-10-24 20:50:03

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

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。要创建解析 am: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,这也是有用的数据。)现在我们如何处理替代 URL?这取决于几件事。

  • 客户是否通过以下方式访问网站
    只有一个 URL,或者他们可能使用更多
    比一个?

如果答案是“只有一个”,那么您可以向该表中添加一列以存储 URL,并使该列唯一。它是该表的候选键。

如果答案是“不止一个 - 至少是站点 url 和替代 url”,那么您需要对约束做出更多决定,因为更改此表以允许客户和商店的每种组合使用多个 url该要求的要点:

shop_site_url 字段是唯一的
特定顾客和商店
(因此不会重复
不同的顾客/商店)

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

  • 客户“n”已访问该网站
    对于使用 url 's' 的商店 'm',
  • 允许客户 'n' 访问
    使用备用的商店“m”的网站
    网址 's'

Well, let's create the table, insert some sample data, and look at the results.

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

Hmm. That doesn't look good. Let's ignore the alternative URL for a minute. To create a table that resolves a m:n relationship, you need a constraint on the columns that make up the m:n relationship.

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)
);

(I dropped the "id" column, because it tends to obscure what's going on. You can add it later, if you like.)

Insert some sample data . . . then

select customer_id as cust_id, shop_id
from customers_shops;

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

That's closer. You should have only one row for each combination of customer and shop in this kind of table. (This is useful data even without the url.) Now what do we do about the alternative URLs? That depends on a couple of things.

  • Do customers access the sites through
    only one URL, or might they use more
    than one?

If the answer is "only one", then you can add a column to this table for the URL, and make that column unique. It's a candidate key for this table.

If the answer is "more than one--at the very least the site url and the alternative url", then you need to make more decisions about constraints, because altering this table to allow multiple urls for each combination of customer and shop cuts across the grain of this requirement:

the shop_site_url field is unique to a
particular customer and shop
(therefore won't be duplicated for
different customers/shops)

Essentially, I'm asking you to decide what this table means--to define the table's predicate. For example, these two different predicates lead to different table structures.

  • customer 'n' has visited the web site
    for shop 'm' using url 's'
  • customer 'n' is allowed to visit the
    web site for shop 'm' using alternate
    url 's'
风月客 2024-10-24 20:50:03

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

Your schema does indeed make sense, as shop_site_url is an attribute of the relationship itself. You might want to give it a more meaningful name in order to distinguish it from shops.site_url.

会发光的星星闪亮亮i 2024-10-24 20:50:03

您还会将此信息放在哪里?它不是商店的属性,也不是顾客的属性。如果您想避免出现可以为 NULL 的列,您可以将其放在一个单独的表中,但最终您必须从这个新表中引用中间表,这可能看起来如下对你来说更奇怪。

Where else would you put this information? It's not an attribute of a shop, and it's not an attribute of a customer. You could put this in a separate table, if you wanted to avoid having a NULLable column, but you'd end up having to have a reference to your intermediate table from this new table, which probably would look even weirder to you.

鹿港巷口少年归 2024-10-24 20:50:03

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

实体属性进入实体表的列中。关系属性(至少对于多对多关系而言)位于关系表中。

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

Relationships can have attributes, just like entities can have attributes.

Entity attributes go into columns in entity tables. Relationship attributes, at least for many-to-many relationships, go in relationship tables.

It sounds as though, in general, URL is determined by the combination of shop and customer. So I would put it in the shop-customer table. The fact that many shops have only one URL suggests that there is a fifth normal form that is more subtle than this. But I'm too lazy to work it out.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文