Constraining data based on related data in a different table. Should this be done on the database level or the application level? I am working on a database that contains our customer information as well as information about our vendors. Part of that includes matching our customers with our vendors, the account numbers those vendors provide to us for our customers and what we charge our customers to use those vendor's services.

Background

In the situation I'm working on now, I have a table that contains our customer's account number, the vendor ID and the account number assigned to our customer by that vendor.

I also have a table that contains all of our vendor's information and a related table that list's all of their services and a "base cost" for that service.

The Problem

The problem that I have is associating a customer with a vendor's service.

If I just create a table that has our customer's account number, a vendor's service ID and the cost of that service, then I could potentially run into issues where a service is assigned to a customer by a vendor that doesn't offer that service.

Here's a diagram of what I'm talking about (though crude):



Because there is no "check" between VendorServices and CustomerVendorServices, I could potentially insert a record where the VendorServiceID in the CustomerVendorServices table for a service that a vendor doesn't provide.

This is obviously a problem and I could prevent it from happening through the interface of the application that interacts with this database, but I would feel much more comfortable if there was a way for the database to "check" that the VendorServiceID being inserted into the CustomerVendorServices table matches a service that is offered by the vendor who is associated with the VendorAccountsID/VendorAccountNumber.

I'm sure this is beyond confusing and I'd honestly be surprised if anyone tried to understand it, but I thought I would give it a shot. :)

Any help and/or suggestions would be very much appreciated.
From my understanding of your question, I feel this might work.


Remove CustomerVendorServices table from your design.
Add ServiceID and CustomerCost in VendorAccounts table.
Remove the FK reference for VendorID in VendorAccounts table from Vendors table.
Add a FK reference for VendorID in VendorAccounts table from VendorServices table.
Also have a separate Services table identified by ServiceID having ServiceDescription and DefaultCost.
VendorServices will then have a composite primary key of VendorID and ServiceID.