如何以编程方式创建一对一或一对关系 - MySQL?

时间:2013-04-14 14:53:42

标签: mysql sql database-design foreign-keys relational-database

我正忙于一个项目,我遇到的一个绊脚石如下:

我有一张预订表,可能会或可能不会产生发票(因为某些不相关的东西,如取消)。我如何强制执行(在预订方面)零(或在发票方面)关系?这就是我到目前为止所做的:

CREATE TABLE IF NOT EXISTS `booking` (    
   `booking_id` int(11) NOT NULL AUTO_INCREMENT,   
   `voucher_id` int(11) NOT NULL,  
   `pickup_date_time` datetime NOT NULL, ...  
   PRIMARY KEY (`booking_id`,`voucher_id`)  
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; 

然后,后来:

  CREATE TABLE IF NOT EXISTS `invoice` (  
  `booking_id` int(11) NOT NULL,  
  `voucher_id` int(11) NOT NULL,  
  `invoice_number` int(11) NOT NULL,  
  `paid` tinyint(1) NOT NULL,  
  PRIMARY KEY (`booking_id`,`voucher_id`),  
  UNIQUE KEY `invoice_number` (`invoice_number`),  
  KEY `voucher_id` (`voucher_id`)  
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; 

voucher_id只是我在系统中使用的其他内容。 invoice_number也是在PHP中生成的,所以这是无关紧要的。

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:5)

这更像是@thaJeztah在评论中已经建议的系统化,但无论如何你要去......

CREATE TABLE voucher (
    voucher_id int(11) PRIMARY KEY
   -- Etc...
);

CREATE TABLE booking (
    booking_id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
    voucher_id int(11) REFERENCES voucher (voucher_id),
    pickup_date_time datetime NOT NULL
   -- Etc...
);

CREATE TABLE invoice (
    invoice_number int(11) NOT NULL PRIMARY KEY,
    booking_id int(11) NOT NULL UNIQUE REFERENCES booking (booking_id),
    paid tinyint(1) NOT NULL
   -- Etc...
);

最小基数:可以预订没有发票。但是,如果没有预订,则不能发票(由于非空字段invoice.booking_id上的FK)。

最大基数:由于invoice.booking_id上的UNIQUE约束,预订无法连接到多张发票。发票无法连接到多个预订,只是因为一个字段(在一行中)不能包含多个值。

因此,预订和发票之间的关系是“一到零或一”。


或者,将所有内容放在一个具有NULL字段的表中,这些字段会随着预订的进行而逐渐填充。