1

我知道主键应该是唯一的。但我正在为房地产代理创建一个数据库,其中邮政编码是地址表的主键。但是,如果一个房产是出售/出租的,并且它位于一个公寓楼内,那么许多房产将有相同的邮政编码。在将 PostCode 保留为 PK 的同时,我如何使它不是唯一的?感谢你

到目前为止我的代码:

CREATE TABLE `Properties` (
  `PropertyID` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `Property Type` varchar(20) NOT NULL,
  `PostCode` varchar(8) NOT NULL,
  `Bedrooms` tinyint(2) DEFAULT NULL,
  `Bathrooms` tinyint(2) DEFAULT NULL,
  `Ensuite` tinyint(1) DEFAULT NULL,
  `Kitchen` tinytext,
  `LivingRoom` tinytext,
  `DiningRoom` tinytext,
  `UtilityRoom` tinytext,
  `Conservatory` tinytext,
  `Garage` tinytext,
  `Garden` tinytext,
  `Furnished` tinytext,
  `Type` char(15) NOT NULL,
  PRIMARY KEY (`PropertyID`),
  KEY `Property Type` (`Property Type`),
  KEY `PostCode` (`PostCode`),
  CONSTRAINT `Properties_ibfk_2` FOREIGN KEY (`PostCode`) REFERENCES `Address` (`PostCode`),
  CONSTRAINT `Properties_ibfk_1` FOREIGN KEY (`Property Type`) REFERENCES `PropertyType` (`Property Type`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1





 CREATE TABLE `Address` (
      `PostCode` varchar(8) NOT NULL,
      `HouseN` text NOT NULL,
      `AddL1` varchar(25) NOT NULL,
      `AddL2` varchar(25) DEFAULT NULL,
      `AddL3` varchar(25) DEFAULT NULL,
      `County` char(20) NOT NULL,
      PRIMARY KEY (`PostCode`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1
4

3 回答 3

9

主键在定义上是唯一的;更好的方法是使用代理键(如自动编号值)或覆盖多列的复合键,例如邮政编码和属性名称/编号。

请注意,某些国家(如英国)的特定物业的邮政编码会随着时间而变化;正因为如此,我提倡代理键方法。

于 2013-11-05T12:15:44.077 回答
7

在数据库设计中有 2 种不同的面/类/样式。

  1. 第一种样式表示主键应该是虚拟的,例如自动增量整数或 guid。不是现实世界中存在的东西,原因是现实世界中的一切都可以改变。
  2. 第二种风格说你应该只在你的表中包含确实存在的数据,主键由客户所说的唯一标识表的内容组成。

如您所见,这些是完全相反的两个方面。我个人会推荐第一个,但你当然可以自由选择。尝试在数据库中坚持单一样式是一件聪明的事情。

在您提到的问题中,主键(由客户)定义为邮政编码。您现在遇到了邮政编码不能唯一标识每一行的问题: 结论:您的主键定义不正确。

解决方案:Rowland 所说的:要么使用代理键(第一类),实际上你已经有一个:PropertyID。第二个选项:向键添加一个/多个字段,以便它唯一标识每一行,例如门牌号/街道号。

于 2013-11-05T13:13:31.960 回答
0

设置 PrimaryKey 的主要原因是为了使每条记录唯一。在您的情况下,邮政编码不是唯一的,我建议不要将其设置为 PK。相反,您可以制作代理键。

于 2013-11-05T12:16:35.387 回答