Are there DBMS that allow a Foreign Key that References a View (and not only base tables)?
In Oracle, one way to enforce this sort of constraint in a declarative fashion would be to create a materialized view that is set to refresh fast on commit whose query identifies all the invalid rows (i.e. BookAspectRating
rows that have no match in BookAspect_view
). You can then create a trivial constraint on that materialized view that would be violated if there are any rows in the materialized view. This has the benefit of minimizing the amount of data that you have to duplicate in the materialized view. It can cause problems, however, since the constraint is only enforced at the point that you're committing the transaction-- many applications aren't written to expect that a commit operation might fail-- and because the constraint violation can be somewhat hard to associate with a particular row or a particular table.
This business rule can be enforced in the model using only constraints. The following table should solve your problem. Use it instead of your view:
CREATE TABLE BookAspectCommonTagLink
( BookID INT NOT NULL
, AspectID INT NOT NULL
, TagID INT NOT NULL
--TagID is deliberately left out of PK
, PRIMARY KEY (BookID, AspectID)
, FOREIGN KEY (BookID, TagID)
REFERENCES BookTag (BookID, TagID)
, FOREIGN KEY (AspectID, TagID)
REFERENCES AspectTag (AspectID, TagID)
) ;
I think you'll find that in a lot of cases, complex business rules cannot be enforced via the model alone. This is one of those cases where, at least in SQL Server, I think a trigger (preferably an instead of trigger) better serves your purpose.