我知道主键应该是唯一的。但我正在为一家房地产代理公司创建一个数据库,其中邮政编码是Address
表的主键。但是,如果一个物业是销售/出租,它是在一个街区的单位,许多物业将有相同的邮政编码。
我如何使它不唯一,同时保持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
3条答案
按热度按时间zsbz8rwp1#
主键在定义上是唯一的;更好的方法是使用代理键(如自动编号值)或包含多个列的复合键,如邮政编码和属性名称/编号。
当然要注意,在某些国家(如英国),特定房产的邮政编码可能会随着时间的推移而变化;正因为如此,我提倡使用代理键方法。
zwghvu4y2#
在数据库设计中,有两种不同的方面/类/风格。
1.第一种样式说主键应该是虚拟的,比如自动递增的整数或guid。不是存在于真实的世界中的东西,其原因是真实的世界中的一切都可以改变。
1.第二种风格是说,你应该只在你的表中包含确实存在的数据,主键由客户端所说的唯一标识一个表的内容组成。
如你所见,这是两个完全对立的方面。我个人会推荐第一个,但你可以自由选择。在数据库中坚持单一的风格是一件聪明的事情。
在您提到的问题中,主键被(客户)定义为邮政编码。现在您遇到了邮政编码不能唯一标识每一行的问题:结论:您的主键定义不正确。
解决方案:罗兰说:要么使用代理键(第一类),事实上你已经有一个了:属性ID。第二种选择:在键中添加一个或多个字段,这样它就可以唯一地标识每一行,例如门牌号/街道号。
8yoxcaq73#
设置PrimaryKey的主要原因是使每个记录都是唯一的。在你的情况下,邮政编码不唯一,我建议不要把它设置为PK。相反,您可以创建一个代理键。