我有两张表,比如
Company( #id_company, ... )
addresses( address, *id_company*, *id_city* )
cities( #id_city, name_city, *id_county* )
countries( #id_country, name_country )
我想要的是:
这是一个很好的设计? (公司可以有很多地址)
重要的是,我注意到我没有为PK
表添加addresses
因为公司的每个地址都不同,我是对的吗?
我将永远不会在where
中指定一个地址{/ 1}}。
答案 0 :(得分:1)
没关系 - 您可能想在company_id上添加一些非唯一索引,以便加快公司地址查询。另一个选择是在公司和地址之间建立一个连接表,但如果地址存储了更多数据(因此搜索速度较慢),这可能只是合理的。
答案 1 :(得分:1)
这个设计很好。
(关系)表始终具有(候选)键。 (其中一个可以选择作为主键,但是候选键,也就是键,是重要的。)因为如果没有小于所有列的列的列的子集是唯一的,那么键是所有列的集合。
由于每个表都有一个,因此在SQL中你应该声明它。例如,在SQL中,如果要为此表的键声明FOREIGN KEY约束,则必须声明该列通过PRIMARY KEY,KEY或UNIQUE设置键。另外,告诉DBMS您了解的内容有助于优化您的使用。
确定键的重要性是列的子集,这些列是唯一的,没有较小的唯一子集。这些是关键。
A company, address or city is not unique since you are going to have multiple of each.
A (city,address) is not unique normally.
A (city,company) is not unique normally.
A (company,address) is not unique normally.
So (company,address,city) is the (only) (candidate) key.
请注意,如果只有一个城市,那么(公司,地址)就是关键。如果只有一家公司,那么(地址,城市)将成为关键。所以你的理由是“因为公司[?]的每个地址[+城市?]会有所不同”,除非我们假设其他事情,否则不合理。
答案 2 :(得分:1)
首先,我们应该区分自然键和技术键。至于自然键:
您决定使用技术密钥。没关系。但是你仍然应该确保名称是唯一的。你不希望法国和法国在你的桌子上,它必须只在那里一次。你不希望法兰克福和法兰克福在你的德国城市表中没有任何区别。并且您不希望为一家公司输入两次相同的地址。
根据您的说法,您似乎只想要查找地址。您不希望在任何其他表中使用它们,现在而不是将来。那么,你完成了。由于您需要对所有三列都有唯一约束,您也可以将其声明为主键,但您不必这样做。
请记住,要在任何其他未来的表中引用公司地址,您必须在该表中存储地址+ id_company + id_city。那时你肯定想要一个地址id。但您可以在需要时添加。现在你可以不用了。
答案 3 :(得分:1)
由于篇幅原因,我将此作为答案而不是评论。对于具有定义的主键的地址表,答案是肯定的。有几个很好的理由,但只考虑一下。
假设公司有多个地址,并且移动要求您删除其中一个地址。您不能删除where comp_id = x
,因为这会删除该公司的所有地址。您必须拥有where comp_id = x and something_else
其他必须将该地址与该公司的所有其他地址区分开来。因此,您必须让某人查看不同的地址以查看它们之间的区别,并选择正确标识一个地址的一个区别,然后将其正确写入where
子句。
每次要删除(或更新)地址时,都要做很多工作。
这也意味着编写可用于删除任何地址的参数化删除语句会更加困难。假设一家公司在同一栋楼内有多个地点:套房101运输,套房202营销和地下室(当然)IT。所以街道,城市,州,一切都是一样的,只有Suite_No
或用于改进地址的任何东西都不同。
然后考虑您的用户。大多数情况下,用户不会有兴趣查看您为公司列出的每个地址。他只对产品测试感兴趣。您应该能够为他们提供产品测试的地址,而不是其他。用户在每次进行查询时都会出现数据转储,并且不会因为耐心而闻名,而且他们可以选择他们正在寻找的数据转储。
它只是解决了很多问题,无法指定where addr_id = x
。
答案 4 :(得分:1)
地址是一个东西,应该有自己的表。
地址可以在没有公司的情况下存在,因此它不应该有公司的外键。另外,如果你开始向个人出售/购买会怎么样?
公司可以拥有零个,一个或多个地址。
两个或更多公司可以拥有完全相同的地址。你的假设是有缺陷的。
使用联结表:
company -< company_address >- address