我正在忙于一个项目,其中遇到的一个难题是:
我有一个预订表,可能会导致发票被开具,也可能不会(因为一些无关紧要的事情,比如取消)。我该如何强制执行一对零或一(在发票方面)的关系?到目前为止,我的做法如下:
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 中生成的,因此不相关。
非常感谢您的帮助!
invoice_number
不是主键,而booking_id
、voucher_id
是唯一的?这似乎有点不合逻辑,你的外键可能会指向invoice_number
吧? - thaJeztahbooking_id
?您应该将booking_id
作为PK,并添加一个UNIQUE约束条件到voucher_id
上,以强制执行一张凭证只能使用一次。或者将'booking_id'带到凭证表中(是的,这将是可空的)。即尚未使用的凭证将具有null
作为booking_id,一旦它们被使用,就会有现有的booking_id。 - thaJeztahinvoice_id
,现在预订的 PK 是booking_id
,您可以删除voucher_id
列。最后要考虑的一件事是,如果一个预订可以使用多个优惠券(例如,如果允许使用优惠券进行折扣并且可以组合使用),则将它们存储为 n:m 关系(HasAndBelongsToMany)在连接表bookings_vouchers
中。 - thaJeztah