我正在创建一个用于出售房屋的数据库。
我有一个要调用的location
父表,该表有三列:
locationLat
和locationlong
组成此表的复合主键。
然后我有一个名为houseToLet
的子表,该表仅存储用于出租的房屋。我有类似的不同表houseToBuy
,fullyFurnished
,landtoSell
等。houseTolet
的表具有一个复合主键,例如上面的位置表,即locationLat
,{ {1}}和引用位置表的外复合键locationLong
和location_locationLat
。
然后我有另一个名为location_locationLong
的表。该表存储了我所出售的所有物业的一般功能。因此generalFeatures
是generalFeatures table
和houseTolet
以及Housetobuy
表的子表,
当我在Fullyfurnished
表中插入行时,我发现没有问题,因为它是父表。当我在location
表中插入行时,我发现没有问题,因为它是子表,并且已经插入了父位置表。但是,当我插入houseTolet
表时,由于它是generalFeatures
的子表以及包括housetoBuy
在内的其他表,因此会遇到问题。
请帮助我了解我该怎么做。
Fullyfurnished
我希望能够在要出租的房屋的 CREATE TABLE IF NOT EXISTS `foreign`.`location` (
`locationLat` DECIMAL(10,8) NOT NULL,
`locationLong` DECIMAL(11,8) NOT NULL,
`locationName` VARCHAR(35) NOT NULL,
PRIMARY KEY (`locationLat`, `locationLong`))
ENGINE = InnoDB
CREATE TABLE IF NOT EXISTS `location`.`housetolet` (
`locationLat` DECIMAL(10,8) NOT NULL,
`locationLong` DECIMAL(11,8) NOT NULL,
`type` ENUM('gatedCommunity', 'standalone', 'apartment') NOT NULL,
`location_locationLat` DECIMAL(10,8) NOT NULL,
`location_locationLong` DECIMAL(11,8) NOT NULL,
PRIMARY KEY (`locationLat`, `locationLong`),
INDEX `fk_housetolet_location_idx` (`location_locationLat` ASC, `location_locationLong` ASC))
CREATE TABLE IF NOT EXISTS `foreign`.`generalfeatures` (
`locationLat` DECIMAL(10,8) NOT NULL,
`locationLong` DECIMAL(11,8) NOT NULL,
`livingAreaAndSize` INT NOT NULL,
`bedrooms` TINYINT(4) NOT NULL,
`bathrooms` TINYINT(4) NOT NULL,
`masterEnsuite` TINYINT(1) NOT NULL,
`bedroomsWithBathrooms` TINYINT(4) NOT NULL,
`kitchenAndSize` TINYINT(4) NOT NULL,
`parkingAndSlots` TINYINT(4) NOT NULL,
`swimmingPool` TINYINT(1) NOT NULL,
`liftsAndNumber` TINYINT(4) NOT NULL,
`CCTV` TINYINT(1) NOT NULL,
`sizeOfLand` INT(11) NOT NULL,
`borehole` TINYINT(1) NOT NULL,
`housetobuy_locationLat` DECIMAL(10,8) NOT NULL,
`housetobuy_locationLong` DECIMAL(11,8) NOT NULL,
`housetolet_locationLat` DECIMAL(10,8) NOT NULL,
`housetolet_locationLong` DECIMAL(11,8) NOT NULL,
`fullyfurnished_locationLat` DECIMAL(10,8) NOT NULL,
`fullyfurnished_locationLong` DECIMAL(11,8) NOT NULL,
PRIMARY KEY (`locationLat`, `locationLong`),
INDEX `fk_generalfeatures_housetobuy1_idx` (`housetobuy_locationLat` ASC, `housetobuy_locationLong` ASC),
INDEX `fk_generalfeatures_housetolet1_idx` (`housetolet_locationLat` ASC, `housetolet_locationLong` ASC),
INDEX `fk_generalfeatures_fullyfurnished1_idx` (`fullyfurnished_locationLat` ASC, `fullyfurnished_locationLong` ASC),
CONSTRAINT `fk_generalfeatures_housetobuy1`
FOREIGN KEY (`housetobuy_locationLat` , `housetobuy_locationLong`)
REFERENCES `foreign`.`housetobuy` (`locationLat` , `locationLong`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_generalfeatures_housetolet1`
FOREIGN KEY (`housetolet_locationLat` , `housetolet_locationLong`)
REFERENCES `foreign`.`housetolet` (`locationLat` , `locationLong`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_generalfeatures_fullyfurnished1`
FOREIGN KEY (`fullyfurnished_locationLat` , `fullyfurnished_locationLong`)
REFERENCES `foreign`.`fullyfurnished` (`locationLat` , `locationLong`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
表中插入行,而又不会得到需要先更新其他表(例如generalFeatures
或houseTobuy
的外键约束,这是因为在特定情况下,我将仅更新特定类型的房屋,但没有太多选择。就我而言,要出租的房屋不能同时成为要买的房屋。
答案 0 :(得分:1)
您的数据库设计存在缺陷。即,您正在多个表中存储可以表示为单个记录的信息。实际上,看起来所有表都可以合并到主表locations
中:
house*
表(houseToLet
,houseToBuy
,...)就在那里存储位置的当前状态(用于让我们来购买...):这可以表示为ENUM
表中的location
字段(如果一次可以启用多个状态,则可以表示为多个布尔列)
generalFeatures
表似乎还包含每个位置的一条记录,因此它的所有字段都可以移到location
表中。
使用单个表似乎是针对您的用例的正确设计(它肯定会避免出现外部约束问题...)。
其他注意事项:使用自动递增的整数作为主键而不是组合键(为此,您可以创建UNIQUE
约束)。
这是您的表的示例DDL:
CREATE TABLE IF NOT EXISTS `foreign`.`location` (
-- primary key
`id` INT AUTO_INCREMENT,
PRIMARY KEY (`id`),
-- original columns
`locationLat` DECIMAL(10,8) NOT NULL,
`locationLong` DECIMAL(11,8) NOT NULL,
`locationName` VARCHAR(35) NOT NULL,
-- house status
`status` ENUM('toLet', 'houseToBuy', 'fullyFurnished', 'landtoSell') NOT NULL,
-- columns from `generalfeatures`
`livingAreaAndSize` INT NOT NULL,
`bedrooms` TINYINT(4) NOT NULL,
`bathrooms` TINYINT(4) NOT NULL,
`masterEnsuite` TINYINT(1) NOT NULL,
`bedroomsWithBathrooms` TINYINT(4) NOT NULL
-- other columns from `generalfeatures`...
)ENGINE = INNODB;