Reputation: 1555
I'm busy with a project and one of the stumbling blocks I've come across has been the following:
I have a bookings table, which may or may not result in an invoice being issued (because of some irrelevant stuff such as cancellations). How would I enforce a one (on the bookings side) to zero-or-one (on the invoice side) relationship? Here's what I have thus far:
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 ;
And then, later on:
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
is just something else I use in the system. The invoice_number
is also generated in the PHP, so this is irrelevant.
Any help would be greatly appreciated!
Upvotes: 4
Views: 3317
Reputation: 52117
This is more-less just a systematization of what @thaJeztah already suggested in his comments, but here you go anyway...
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...
);
Minimal cardinality: There can be a booking without an invoice. There cannot, however, be an invoice without the booking (due to the FK on the non-NULL field invoice.booking_id
).
Maximal cardinality: A booking cannot be connected to multiple invoices due to the UNIQUE constraint on invoice.booking_id
. An invoice cannot be connected to multiple bookings, simply because one field (in one row) cannot contain multiple values.
So, the resulting relationship between booking and invoice is "one to zero or one".
Alternatively, put everything in just one table with NULL-able fields that get progressively filled as the booking advances.
Upvotes: 5