这个表结构可以工作还是应该改变

时间:2014-05-16 03:50:53

标签: sql sql-server database database-design

我有一个现有的表,预计可用于新的功能。我认为需要一个新的表来实现这个目标,如果它可以按原样运行,或者新表必须是一个意见吗?问题是查询返回的记录多于应有的数据,我相信这就是原因:

有一个名为postcodes的表。随着时间的推移,这实际上已成为一个城镇表,因为已输入不同的城镇名称,因此它具有多个邮政编码的多个记录。参考下面的查询,邮政编码表中的相关字段是:

postcode.postcode - 实际的邮政编码,如上所述,这不是唯一的 postcode.twcid - 是预测表的外键,这不是唯一的

预测表中的相关字段是: forecast.twcid - 表的标识符然而不是唯一的,因为表中有四天的预测值。只有四个,更新的,永不减少。

以下是查询:

select * from forecast 
LEFT OUTER JOIN postcodes ON forecast.TWCID = postcodes.TWCID 
WHERE postcodes.postcode = 3123 
order by forecast.twcid, forecast.theDate;

因为3123的邮政编码表中有两条记录,所以结果加倍。第1天的两个预测,第2天的两个等等......

鉴于邮政编码和预测之间的关系是多对多(邮政编码表中有多个记录,每个邮政编码和twcid。预测表中每个twcid有多个记录,因为它总是有四天的值预测)有没有办法重新编写查询,只能获得邮政编码的四个预测记录?

或者我想创建一个新的邮政编码表,其中每个邮政编码都有唯一的记录吗?

2 个答案:

答案 0 :(得分:0)

您遇到的问题是邮政编码可能位于多个城镇。城镇可以有多个邮政编码。在美国,美国人口普查局和美国邮政局为各种编码方案定义了非常广泛的地理区域。基本的想法是邮政编码有一个“主要”城镇。

我建议您创建一个单独的表,每个邮政编码和主要城镇一行。或者,在数据库中添加一个表示主要城镇的字段。您可以使用筛选索引保证此字段的唯一性:

create unique index postcode_postcode_maintown on postcodes(postcode) where IsMainTown  = 1;

IsMainPostcode可能需要相同的内容。

(过滤的索引在SQL Server中是一个非常好的功能。)

使用此构造,您可以将查询更改为:

select *
from forecast LEFT OUTER JOIN
     postcodes
     ON forecast.TWCID = postcodes.TWCID and postcodes.IsMainPostcode = 1
WHERE postcodes.postcode = 3123 
order by forecast.twcid, forecast.theDate;

答案 1 :(得分:0)

你真的永远不会有没有主键的表。根据定义,主键是唯一的。主键应该是外键的目标。

您遇到问题是因为您正在与糟糕的数据库设计作斗争。