How to implement IS_A relationship for different constrains - database

So IS_A relationship has two possible constraints: covering/non-covering and overlapping/non-overlapping. Implementing non-covering, overlapping IS_A relationship is trivial: we have a table for a superclass, and a table for each subclass, subclasses' PK are also FKs that reference the superclass table.
The question is, how to implement other possible combination of constraints?

Related

How to avoid problems with composite entity keys and constraints (Products, Options, Option Groups, Special Orders)

I am modeling a database for a webshop and have come across ad issue. Basically the question is whether to ignore database normalization rules for simplicity's sake.
Below is the relevant part of my diagram prior to the issue.
Database diagram
Basically, the product can have options (size, flavor, color) but only from one option group. Since an option group can have many options and a product that uses it can take a subset, a ProductOption table is created. Next we have a SpecialOffers table. Next, a special offer can have many products and products can belong to many special offers, hence the association table SpecialOfferProducts. All this works fine until the special offer includes a product that has options. This is where I run into problems. I have a couple of ideas.
First idea:
Create an association table between SpecialOfferProducts and ProductOptions. I don't like this idea since both tables have composite primary keys and creating a table that has a composite primary key composed of two composite primary keys seems really weird and I have never seen anything like it.
Second idea:
Create a association table between SpecialOfferProducts and Options. This seems wrong since Options is not directly tied to Product. Still this would work and the primary key would be a little simpler.
Third idea:
This is the one that I like the most but it violates a few rules. Change the SpecialOfferProducts table. Make it have its own primary key and have SpecialOffers, Products and Options as foreign keys. Simply make the Options foreign key nullable and problem solved. Of course the problems are that I am not making an association table where I should and am making a foreign key nullable. This would slightly complicate my code to deal with all of this but I still feel that this is much simpler than the other approaches since I reduce the number of composite keys and I don't have to add another table in the case where the product in a special offer uses an option.
My question is, which one of this options is best? Is there a better option I have not mentioned?
Using Martin style notation
OptionGroups has (0,n) relationship with the table Options. Options has (1,1) relationship with the table OptionGroups. The purpose of these table is to store information like color, size, etc. An example wouldbe OptionGroups entry color that has Option entries black, white, etc.
Product table has (0,1) relationship with table OptionGroups. OptionGroups has (0,n) relationship with table Product. Product table has a (o,n) relationship with the table Options. Options table has a (o,n) relationship with the table Product. Many-to-many relation produces association table ProductOptions. ProductOptions has a composite PK ProductID, OptionsID. The purpose of these tables is to allow product to have (but does not have to have) options from a certain option group but does not need to have all options from that group.
Example 1. Product does not have any options, hence FK Product_OptionGroups is null. In this case the product does not have any entries in the ProductOptions table.
Example 2. Product has options (lets say color) and so the FK Product_OptionGroups is not null (has the ID of the coresponding option group). Option group color can have many colors and the product is allowed to use one or many of those colors. The colors in use by the product are entries in the table ProductOptions.
SpecialOffer table has a (1,n) relation to the table Products. Products table has a (0,n) relation to the table SpecialOffer. Many-to-many relation creates the association table SpecialOfferProducts. This table has a PK SpecialOfferID, ProductID. The table has a Quantity attribute indicating the quantity of the product.
Example. SpecialOffer A includes one instance of Product A and two instances Product B.
Lets say that the Product A has options. Now SpecialOfferProducts table must reference the correct option.(maybe the product can be blue and red and the special offer only includes the red product). This is where the current schema does not work and either an additional table must be introduced (idea 1 and 2) or the existing tables changed (idea 3).
Maybe you have some relation(ship)/association not representable in terms of your first three:
-- special offer S offers the pairing of P and option O
SpecialOfferProductOption(S, P, O)
-- PK (S, P, O)
-- FK (S, P) to SpecialOfferProducts, FK (P, O) to ProductOptions
You don't seem to understand the use of composite keys, CKs (candidate key), FKs (foreign keys) & constraints. Constraints (PKs, UNIQUE, FKs, etc) arise after you design relation(ship)s/associations sufficient to clearly describe your business situations (represented by tables), per the situations that can arise.
From an ER point of view, you are not properly applying the notions of participating entity (type), entity (type) key & associative entity (type).
You are needlessly & vaguely afraid of composite CKs. Even if you wanted to reduce use of composite keys, you should first find a straightforward design. If you don't want to use composite keys, introduce id PKs along with other CKs. But note that when you use ids as FKs that doesn't drop the obligation to properly constrain the tables that they appear in to agree where necessary with other ids or columns per the constraints you would have needed if you had used the composite CKs instead.
First idea:
Create an association table between SpecialOfferProducts and ProductOptions. I don't like this idea since both tables have composite primary keys and creating a table that has a composite primary key composed of two composite primary keys seems really weird and I have never seen anything like it.
It's not clear what you mean by this. Maybe you mean the above (good) design. Maybe you mean having duplicate product columns; but that's not what good design suggests.
From an ER perspective: You may be thinking of this as a relation(ship)/association on special orders & products. But then the entity keys would not be composite, they would identify special orders & products, and also options would participate. Or we can use the ER concept of reifying relation(ship)s/associations SpecialOfferProducts & ProductOffers to associative entities that are the two participants. That would use composite keys. (If options weren't considered entities then ER would call this a weak relation(ship)/association entity with special orders & products as identifying entities.) Regardless, special orders & products must agree on options, and if that isn't enforced via FKs then it still needs constraining.
If you have (been) read(ing) some published text(s) on information modeling & database design (as you should) you will see many uses of composite keys.
Second idea:
Create an association table between SpecialOfferProducts and Options. This seems wrong since Options is not directly tied to Product. Still this would work and the primary key would be a little simpler.
It's not clear what you mean by "directly tied", "seems" or "wrong".
Relational tables relation(ship)s/associations are among values, certain subrows of which may identify certain entities. Just use the relevant columns & declare the relevant constraints.
From an ER perspective: Considering that you seem to be confused about participant entities (special offer vs SpecialOfferProduct), maybe this is moot, but: Maybe if you tried to express yourself only using technical terms & without the confusion then you would be trying to say that this design needs a constraint that product-option pairs appear in ProductOptions and that it's messy that the constraint involves a relation(ship)/association whose associative entity ProductOption isn't one of the participating entities. I'd agree, but such a design is not "wrong".
Third idea:
This is the one that I like the most but it violates a few rules. Change the SpecialOfferProducts table. Make it have its own primary key and have SpecialOffers, Products and Options as foreign keys. Simply make the Options foreign key nullable and problem solved.
Besides just being needlessly complex, this design is bad. It involves a complex table meaning & complex constraints. When settting the table value you need to decide when to use & not use nulls. When reading you need to figure out what a row means based on whether it has a null. Introducing an id or nulls, possibly while dropping columns, does not remove the obligation to constrain remaining columns if that's not handled by remaining FK constraints. Normally we combine tables while introducing nulls in columns that are not part of every CK--not your case. Here your adding ids doesn't even obviate the need to constrain pairs of products and non-null option column values to be in ProductOptions. And when there is a NULL option column value there should still exist certain rows in ProductOptions and sometimes not certain rows in SpecialOfferProducts. Also this design must be used with complex queries dealing with the presence of NULL. (Which you address.) Justifying this as an ER design is similarly problematic.
PS 1 Please explain your business relation(ship)s/associations with less generic terms than the essentially meaningless "has", "with", "uses", "in" & "belong to"--as you would with a client buying your products & special offers. They refer to relation(ship)s/associations & sets, but they don't explain them. (Similarly, cardinalities are properties of relation(ship)s/associations, but don't explain/characterize them.)
PS 2 ER reasoning about designs involves what (possibly associative) entities are participating in relationships, whereas in the relational model view tables just capture n-ary relation(ship)s/associations for any n. So the ER view is adding needless distinctions. That is why ER-based information modeling & database design approaches are not as effective as fact-based approaches:
This leads to inadequate normalization and constraints, hence redundancy and loss of integrity. Or when those steps are adequately done it leads to the E-R diagram not actually describing the application, which is actually described by the relational database predicates, tables and constraints. Then the E-R diagram is both vague, redundant and wrong.
PS 3 We don't need SpecialOfferProducts if it holds rows where "special offer S offers the pairing of P and some option", because it is select S, P from SpecialOfferProductOption. (This seems to be the case since your option 3 involves having only one table that you call SpecialOfferProducts but is like this table with an added id.) But if it holds rows where say "special offer S offers product P" and that can be so when not all of S's product-option pairs have been recorded then you need it. (Something similar arises re deciding when something is an entity, eg when there should be a table "S is a special option".)
PS 4
seems really weird and I have never seen anything like it
This is the story of life. But in a technical context if we learn and apply clearly defined basic definitions, rules & procedures then we "see" more, and more clearly. (And don't vaguely think we vaguely see things that aren't there.) And "weird" is a rare case where we can explicitly justify that our tools don't apply.

What's the relationship between the two entities?

The ER diagram for a database is given below:
Now, what's the relationship between planes and flights entities?
I'd say one to many, but that'd be wrong because while one plane can have more than one flights, many flights can't have one (single) plane simultaneously.
So, what exactly is the relationship?
I'm new to databases. Please tell me if I'm wrong.
First, your diagram isn't an ER diagram, it's a table diagram. ER diagrams must be able to represent the ER model, which supports ternary and higher relationships, weak entity sets and identifying relationships, and other concepts for which table diagrams don't have notation. Proper ER diagram notation is generally referred to as Chen's notation.
Now, ER relationships are easily identified by looking for entity domains (columns that identify entity sets) that appear in the same table. These are usually indicated by PK and/or FK, but they need not be.
When you have a binary relationship (two entity domains in the same table), look at the unique constraints on these domains:
One-to-one relationships require two separate unique constraints, one for each domain.
One-to-many relationships require a unique constraint on the domain on the many side.
Many-to-many relationships require a composite unique constraint on both domains together.
One-to-many relationships can be denormalized into the entity relation of the entity on the many side, since the unique constraint required for the relationship matches the PK for the entity relation. One-to-one relationships can be denormalized into either entity relation. A many-to-many relationship requires a composite key, and must be represented as a separate relation since the composite key doesn't match either entity relation's PK.
In your example, (flight_num, planeID) represents the relationship, and since only flight_num is uniquely constrained (due to being the PK of the flights relation), this is a many-to-one relationship: each flight is associated with exactly one plane, while each plane can be involved in many flights.
Here's a visual reference in which unique constraints are indicated with underlining:
Many people still use terminology and concepts from the old network data model, such as conflating relationships with FK constraints and entity sets with tables (which is why table diagrams are often mistakenly called ERDs). I highly recommend reading Codd's paper "A Relational Model of Data for Large Shared Data Banks" and Chen's paper "The Entity-Relationship Model - Toward a Unified View of Data".
As you said the relation is One-To-Many because if it is a Many-To-Many relation it must have a junction table between these 2 tables (Tbl_Plane_Flight) , another thing is that Plane_Id is referenced in Flights table.
But there must be a validation rule (or a constraint in flights table) for this relation, that a plane cannot have many flight as the same time

How to determine relationship (1:1, 1:n, n:m) between tables when reverse engineering

I have some tables already created in my database and now I need to draw ER diagram for these tables.
Identified the primary key and foreign key between the
tables
Determined pk-fk relationship using the keys
Now I need to identify the cardinality between the tables. How do I
do this?? Please let me know if there is any set of rules which I
need to consider while evaluating 1:1, 1:M and M:M relationships.
Let me take an example of two tables where am struck at:
Table A has a composite key made of pid and identitytype.
Table B has a composite key made of pid and maritalid.
Table A and Table B are associated with each other using pid and pid
is not null in both the tables.
Let me know what could be the relationship type between Table A and Table B whether it is 1:1, 1:M or M:M. Also, please let me know the sequence of steps that you followed in arriving at type of relationship conclusion.
Thanks,
Dex.
Relationships in the entity-relationship model are very different from what you've got in mind. Relationships are not represented by foreign key constraints - that's the old network data model, and it's limited to binary relationships. The entity-relationship model represents n-ary relationships between entity sets in tables, not between tables.
Foreign key constraints restrict the values of a set of columns to be a subset of the values of another set of columns. They are effectively used to enforce entity sets (domains) - for example, to ensure that every person_id column is a subset of the one that represents all known persons in the system. FK constraints are only used during updates - you could delete all FKs from a database and your SELECT queries and JOINs would work exactly as before, further demonstrating that they don't represent relationships.
A relationship is an association among two or more entity sets, each represented by a suitable key. Relationship instances are always recorded in rows of a table. For example:
A 1:1 relationship between a driver's license and a person would be represented by having the license key and person key together as two columns of a table, and both (separately) uniquely constrained. Whether this is in a license table, a person table, or a separate driver's license table is an implementation detail.
A 1:N relationship between cars and their owners would be represented by having the car key and person key together as two columns of a table, and the entity set on the many side uniquely constrained. This is often implemented in the table recording the attributes of the entity on the many side.
The preceding relationships are simple enough that we can denormalize them and don't need to record the relationship in a separate table. For higher relationships, though, we need separate tables:
An M:N relationship between students and subjects would be represented by having the student key and the subject key together as two columns of a table, and the combination of the two uniquely constrained.
An M:N:P relationship between suppliers, products and regions would be represented by having the supplier key, product key and region key together as three columns of a table, and the combination of the three uniquely constrained.
An M:N:1 relationship between regions, products and suppliers (a sole mandate) would be represented by having the region key, product key and supplier key together as three columns of a table, and the combination of region and product keys uniquely constrained.
See the pattern?
Every role/component of a relationship can have a foreign key constraint defined if the characteristic predicate of that entity set (its required attributes) is represented in a different table. That means a single n-ary relationship can require n different FK constraints.
To determine the cardinality of a relationship from an existing table:
Determine the entity sets represented in the table. Not all columns represent entity sets - some represent value sets, meaning the values have meaning themselves as labels or measures.
Determine which combination of entity sets are uniquely constrained together. These are the many sides of the relationship, and we'll give them variables like M, N, P, etc.
Every other entity set is dependent on the previous combination and represented by a 1 in cardinality.
It's not quite that simple. It's possible for a table's key to involve value sets in addition to entity sets. In these cases, we've got a weak entity/identifying relationship/subtyping situation. These are usually (but not always) 1:N relationships in which the child entity's key partially overlaps with the parent entity's key.
For more information, I recommend Peter Chen's paper The Entity-Relationship Model - Toward a Unified View of Data.
You should look at this SO question:
postgresql-describe-table
In reality, without looking at the schema definition, without a contra-positive example, you have no way of knowing if the table is a 1:1, 1:n, or n:m relation if n = m = 1.
You can do a scan, but it is the constraints that determine that relationship.
If you don't have that data, then you can only demonstrate 1:n and n:m with examples, but it cannot be proven that 1:1 is not n:m without the constraint definitions.
A 1:1 relationship will look like this:
PK - PK
this can only by one-to-(zero or one), as both tables can only have unique keys, 1:n and n:m are not allowed. This would have to be constrained by software on some level to ensure the PK = PK for the separate tables, or more usually, if you really want 1:1 the data is stored, normalized, in the same table. Otherwise, you need to ensure key coordination by a transactional insert, or whatnot. Auto-generated keys are not advised.
A 1:n relationship will look like this:
PK - FK
the FK (foreign key) defines it to be constrained to a primary key in another table, but can be in multiplicity.
An n:m relationship will look like this:
PK - FK|FK - PK
where there are three tables. Two normalized tables with primary keys (the PKs) and a joining table with FK relationships defining the mapping n:m between the tables.
Of course, all of this could be constrained by code using the database, and hence, the table constraints are the only reliable definition of the data schema.
Foreign Keys must point to Primary Keys in another table, so you can't have FK:FK relationships, and there really is no PK:PK relationship defined by the database. That has to be constrained by transactional insert via code. The usual convention is to store data that is PK:PK in the same table, per a normalized data format.
Okay, so, to add a comment, directed at tables A and B; all you can say for certain is you have primary keys consisting of pid:identitytype and pid:maritalid, and if that is the case, for the sake of discussion, say identitytype and maritalid are ints, then you have int:int and int:int, and it tells you nothing. if identitytype has overlap with maritalid, then there is no way to reliably tell them apart. If you are only going to match on pid, then you have an N:M relationship as you have pid:N-pid:M different possibilities which would lead to an N:M relationship.

Difference between one-to-one and one-to-many relationship in a database

When having a one-to-one relationship in a database the other table has a foreign key ID (in this example). And in a one-to-many relationship the table contains many foreign keys.
But does the database know whether this is a one-to-one or one-to-many relationship? Are the relationships that I make in an ER-Diagram only to indicate where there should be foreign keys when making the actual tables?
What is the difference between one-to-one and one-to-many relationship in a database?
In a sense, all the relationships we talk about are not known to the database, they are constructs we have invented to better understand how to design the tables.
The big difference in terms of table structure between one-to-one and one-to-many is that in one-to-one it is possible (but not necessary) to have a bidirectional relationship, meaning table A can have a foreign key into table B, and table B can have a foreign key into the associated record in table A. This is not possible with a one-to-many relationship.
One-to-one relationships associate one record in one table with a single record in the other table. One-to-many relationships associate one record in one table with many records in the other table.
To enable one-to-one relationship you need to add unique constraint to foreign key. It is not possible to have two foreign keys for each table as it will be impossible to create records.
Im having trouble understanding what the actual question is.
Your analysis is for the most part correct, in that if you have a 2 tables, and table2 has a foreign key to table one, it could be either a one-to-one or a many-to-one.
Your sentence "And in a one-to-many relationship the table contains many foreign keys."
The table of the 'many' side still contains one column that is a foreign key, its just that more than one row can have the same foreign key value (many rows point to one parent).
Also note that you can put the foreign key on the parent table, to the child, instead of the other way around. In this way, you can prevent one-to-many if you want to do that. Also note that in this way, more than one parent can share a child, which might or might not be what you want.
The database-level equivalent of a 1:1 vs. 1:m is having a unique index on the foreign key column. Note that this will only work for 1:1, NOT 1:0..1, as null is considered when evaluating uniqueness. There are workarounds for this restriction, but that's it at the basic level.
Similarly by example, a product has only one product code, so it's one-to-one relationship (product <-> ABC123), but a customer can purchase more than one product, so it's one-to-many relationship (person <->>>product).
well, you are right, this relation is important for you, but not for db itself. When you have two tables, one with your basic information, and another one with your detailed information.. for both tables you are you, so it is one-to-one relation, you can not map your data to somebody else.
Now add third table "cities" and one of your information points to city you live in - this is example of one-to-many (one city can be used, and should be used for many people).
one-to-many / one-to-one just show how your tables interact. And all the time, you want to "save" rows/columns in table not duplicating them you will use one-to-many relation with another table. Or many-to-many :)
Let's assume you have a table with two attributes A and B. If A is a candidate key and B is not then the relationship between A and B is 1 to many. If both A and B are candidate keys then the relationship is 1 to 1.
Given table A and B if
A and B have a strict 1 to 1 relationship
For every B instance, there will always be an A instance
The best approach is to make the primary key of B also a foreign key referencing A. This is also called "Table per Type Inheritance" and the "is a" relationship. There are other ways to enforce a unique foreign key, but using the primary key makes the relationship clear in the schema and in ER diagrams.
Of course there are always other scenarios, and if your design doesn't meet both of the criteria above, you'll have to use another approach.

on what basis relationship between tables are defined

I have a question, if two tables in database are from different entities then how we define relationship between them. i mean can we use some foreign key or any thing to define relationship between them. or we have to create a third table
It depends on what kind of relationship you have. If it´s a 1-1 or 1-N then you will only add foreign key column on the respective table. If you need a N-N (aka N-M) you will need a third table.
There is a design principle that states that a table either defines an entity or a relationship but not both. Therefore, use a third table to model the relationship between your two entities -- yes, even if it is 1-1 or 1-N -- noting that the relationship itself may have its own attributes.

Resources