How to reverse the dependencies of a foreign key constraint? - sql

Suppose I have two concepts, Teacher and Class. They map nicely to two database tables, Teachers and Classes. To express the statement 'every Class has a Teacher' I add a foreign key to the Classes table pointing to the Teachers table. Now if I try and delete a Teachers row that is used in a Class, I get a nice error saying 'Can't do that' which is what I want.
So far so good. But what if I wanted to extend this behaviour onto Pupils? I.e. whenever I try to delete a Pupil that is part of a class I want the database engine to roar at me and say 'Can't do that'.
I could simulate what I want by creating 30 foreign keys in Classes: Pupil_1_ID, Pupil_2_ID, ... Pupil_30_ID. But what I'm really after is doing this for an arbitrary number of Pupils.
How can I achieve this?

Create a surrogate key table, PupilClass that has an FK to Class and another FK to Pupils. This way to you can't delete a pupil who's in a class, and neither can you delete a class that has pupils.
A surrogate table is a common design pattern when you need to model a many-to-many relationships: a class can have many pupils, a pupil can attend many classes.

Related

Class Diagram: In A Composition Relationship Should a Child Class Always Have An ID Field?

I'm having a hard time converting my database tables and foreign keys to a class diagram with classes and associations.
My question is:
"In in a composition relationship, should a child class always should have an ID field?".
In my CD, there are 2 compositor classes: PurchaseItem and PurchaseFinisher, which composite Purchase class. PurchaseItem already comes with an ID field from its table but, PurchaseFinisher doesn't because it is filtered by the id_purchase and id_payment_method foreign keys.
thanks in advance.
This is my DB diagram:
I can't see redundancy in between Purchase or Product, as you said. Could you, please, show me that based on my DB diagram? My tables are well modeled (hope so). My fault is in the classes definition.
In a class diagram, no class requires an id property: each class instance (aka object) has its own identity with or without explicit id property.
In a database, you need of course an explicit id property to uniquely identify the object among others in the database and find it back. By the way, you may annotate such properties with a trailing {id} . UML does not define any semantic for it, but it is in general sufficiently expressive to help database designers.
In the case of composition, the main question is whether a composed object can easily be identified by alternate means. There are several related ORM database techniques, for example:
you can use the owning object’s id together with another property if this is sufficient to identify the element. The two together would make a composite primary key in database.
you can use a unique id to identify the object (surrogate primary key) and use the id of the owning object as foreign key.
For PurchaseItem you have everything that is needed, although the diagram does not tell which of the two approaches you’ll use (e.g is the id unique globally, or unique within the purchase?).
But for PurchaseFinisher it is unclear if you could uniquely identify an occurence. If a payment method can only be used once per purchase, it’s fine as it may be used to identify the object.
If it would be allowed to pay two times the same amount (half of the overall price) in the same currency with the same payment methods, you’d have undistinguishable duplicates. So, some kind of identifier will be needed from the database point of view.

Questionable SQL Relationship

I am going through a pluralsight course that is currently going through building an MVC application using an entity framework code-first approach. I was confused about the Database schema used for the project.
As you can see, the relationship between Securities and it's relating tables seems to be one-to-one, but the confusion comes when I realize there is no foreign key to relate the two sub-tables and they they appear to share the same primary key column.
The video before made the Securities model class abstract in order for the "Stock" and "MutualFund" model classes to inherit from it and contain all relating data. To me however, it seems that same thing could be done using a couple of foreign keys.
I guess my question is does this method of linking tables serve any useful purpose in SQL or EF? It seems to me in order to create a new record for one table, all tables would need a new record which is where I really get confused.
In ORM and EF terminology, this setup is referred to as the "Table per Type" inheritance paradigm, where there is a table per subclass, a base class table, and the primary key is shared between the subclasses and the base class.
e.g. In this case, Securities_Stock and Securities_MutualFund are two subclasses of the Securities base class / table (possibly abstract).
The relationship will be 0..1 (subclass) to 1 (base class) - i.e. only one of the records in Securities_MutualFund or Securities_Stock will exist for each base table Securities row.
There's also often a discriminator column on the base table to indicate which subclass table to join to, but that doesn't seem to be the case here.
It is also common to enforce referential integrity between the subclasses to the base table with a foreign key.
To answer your question, the reason why there's no FK between the two subclass instance tables is because each instance (with a unique Id) will only ever be in ONE of the sub class tables - it is NOT possible for the same Security to be both a mutual fund and a share.
You are right, in order for a new concrete Security record to be added, a row is needed in both the base Securities Table (must be inserted first, as their are FK's from the subclass tables to the base table), and then a row is inserted into one of the subclass tables, with the rest of the 'specific' data.
If a Foreign Key was added between Stock and Mutual Fund, it would be impossible to insert new rows into the tables.
The full pattern often looks like this:
CREATE TABLE BaseTable
(
Id INT PRIMARY KEY, -- Can also be Identity
... Common columns here
Discriminator, -- Type usually has a small range, so `INT` or `CHAR` are common
);
CREATE TABLE SubClassTable
(
Id INT PRIMARY KEY, -- Not identity, must be manually inserted
-- Specialized SubClass columns here
FOREIGN KEY (Id) REFERENCES BaseTable(Id)
);

Entity Framework: One to Many relationship

I have a design problem with regards to Entity Framework model relationship
I have this model in the edmx
Business Rule:
A Participant can have multiple Roles so I create a relationship table ParticipantRoles that has 1-to-Many relationship on the Participant and the Role table
The Problem:
In order to get the Participant's Role value, I have to drill down through Participant->ParticipantRole->Role (see JSON output below)
The Question:
In EF, how to design the table relationship to bypass the ParticipantsRole table. I want to access the Role in something like this Particant.Role and not Participant.ParticipantsRole.Role
You say A Participant can have multiple Roles. And of course, a Role can have multiple Participants. So basically this is a many-to-many association.
Entity Framework will only map pure many-to-many associations (without connecting class) when the junction table only has two foreign keys. In your case, if the table ParticipantsRole only would have had a primary key consisting of ParticipantId and RoleId at the time of generating the model the class ParticipantsRole would not have been created. You would have had Participant.Roles and Role.Participants as navigation properties.
However, the model has been generated with ParticipantsRole and you want to get rid of it. (Or not, I'll get back to that).
This is what you can do:
Remove ParticipantRoles from the class diagram.
Modify the database table ParticipantRoles so it only has the two FK columns, that both form the primary key.
Update the model from the database and select ParticipantsRole in the Add tab.
This should give you a model with a pure many-to-many association.
However, think twice before you do this. M2m associations have a way of evolving into 1-m-1association (as you've got now). The reason is that sooner or later the need is felt to record data about the association, so the junction table must have more fields and stops being a pure junction table. In your case I can imagine that one day participant's roles must have a fixed order, or one marked as default. It can be a major overhaul to change a m2m association into 1-m-1 in a production environment. - Something to consider...

Unique constraint across different classes/tables (TABLE PER SUBCLASS)

I have a class A and a class B that inherits from A. Class A has a certain attribute X. Class B adds another attribute Y. An instance of B is uniquely identified by its pair of attributes {X,Y}. So, {X,Y} is a candidate key for class B. Obviously this key doesn't exist at the class A level since attribute Y isn't there. I use a surrogate key for class A.
Now, I use Hibernate for the object-relational mapping. If I use the TABLE PER SUBCLASS inheritance strategy, I don't see a possibility for defining a UNIQUE constraint on multiple attributes that belong to different classes (and then in the DB, to different tables).
My question is how can I define a unique constraint for this candidate key using Hibernate and more generally in SQL? If it's not possible, what do you recommend?
Thanks
Here are two solutions:
Create a new table with one column which is its PK. This table should hold all the values which you want to make unique. Create foreign keys to this table which will ensure that the domain on the columns comes from the unique table.
Create triggers which raise an error if the condition is violated.

Difference between one-to-many and many-to-one relationship

What is the real difference between one-to-many and many-to-one relationship? It is only reversed, kind of?
I can't find any 'good-and-easy-to-understand' tutorial about this topic other than this one: SQL for Beginners: Part 3 - Database Relationships
Yes, it is vice versa. It depends on which side of the relationship the entity is present on.
For example, if one department can employ several employees then department to employee is a one-to-many relationship (1 department employs many employees), while employee to department relationship is many-to-one (many employees work in one department).
More info on the relationship types:
Database Relationships - IBM DB2 documentation
From this page about Database Terminology
Most relations between tables are one-to-many.
Example:
One area can be the habitat of many readers.
One reader can have many subscriptions.
One newspaper can have many subscriptions.
A Many to One relation is the same as one-to-many, but from a different viewpoint.
Many readers live in one area.
Many subscriptions can be of one and the same reader.
Many subscriptions are for one and the same newspaper.
What is the real difference between one-to-many and many-to-one relationship?
There are conceptual differences between these terms that should help you visualize the data and also possible differences in the generated schema that should be fully understood. Mostly the difference is one of perspective though.
In a one-to-many relationship, the local table has one row that may be associated with many rows in another table. In the example from SQL for beginners, one Customer may be associated to many Orders.
In the opposite many-to-one relationship, the local table may have many rows that are associated with one row in another table. In our example, many Orders may be associated to one Customer. This conceptual difference is important for mental representation.
In addition, the schema which supports the relationship may be represented differently in the Customer and Order tables. For example, if the customer has columns id and name:
id,name
1,Bill Smith
2,Jim Kenshaw
Then for a Order to be associated with a Customer, many SQL implementations add to the Order table a column which stores the id of the associated Customer (in this schema customer_id:
id,date,amount,customer_id
10,20160620,12.34,1
11,20160620,7.58,1
12,20160621,158.01,2
In the above data rows, if we look at the customer_id id column, we see that Bill Smith (customer-id #1) has 2 orders associated with him: one for $12.34 and one for $7.58. Jim Kenshaw (customer-id #2) has only 1 order for $158.01.
What is important to realize is that typically the one-to-many relationship doesn't actually add any columns to the table that is the "one". The Customer has no extra columns which describe the relationship with Order. In fact the Customer might also have a one-to-many relationship with ShippingAddress and SalesCall tables and yet have no additional columns added to the Customer table.
However, for a many-to-one relationship to be described, often an id column is added to the "many" table which is a foreign-key to the "one" table -- in this case a customer_id column is added to the Order. To associated order #10 for $12.34 to Bill Smith, we assign the customer_id column to Bill Smith's id 1.
However, it is also possible for there to be another table that describes the Customer and Order relationship, so that no additional fields need to be added to the Order table. Instead of adding a customer_id field to the Order table, there could be Customer_Order table that contains keys for both the Customer and Order.
customer_id,order_id
1,10
1,11
2,12
In this case, the one-to-many and many-to-one is all conceptual since there are no schema changes between them. Which mechanism depends on your schema and SQL implementation.
Hope this helps.
SQL
In SQL, there is only one kind of relationship, it is called a Reference. (Your front end may do helpful or confusing things [such as in some of the Answers], but that is a different story.)
A Foreign Key in one table (the referencing table)
References
a Primary Key in another table (the referenced table)
In SQL terms, Bar references Foo
Not the other way around
CREATE TABLE Foo (
Foo CHAR(10) NOT NULL, -- primary key
Name CHAR(30) NOT NULL
CONSTRAINT PK -- constraint name
PRIMARY KEY (Foo) -- pk
)
CREATE TABLE Bar (
Bar CHAR(10) NOT NULL, -- primary key
Foo CHAR(10) NOT NULL, -- foreign key to Foo
Name CHAR(30) NOT NULL
CONSTRAINT PK -- constraint name
PRIMARY KEY (Bar), -- pk
CONSTRAINT Foo_HasMany_Bars -- constraint name
FOREIGN KEY (Foo) -- fk in (this) referencing table
REFERENCES Foo(Foo) -- pk in referenced table
)
Since Foo.Foo is a Primary Key, it is unique, there is only one row for any given value of Foo
Since Bar.Foo is a Reference, a Foreign Key, and there is no unique index on it, there can be many rows for any given value of Foo
Therefore the relation Foo::Bar is one-to-many
Now you can perceive (look at) the relation the other way around, Bar::Foo is many-to-one
But do not let that confuse you: for any one Bar row, there is just one Foo row that it References
In SQL, that is all we have. That is all that is necessary.
What is the real difference between one to many and many to one relationship?
There is only one relation, therefore there is no difference. Perception (from one "end" or the other "end") or reading it backwards, does not change the relation.
Cardinality
Cardinality is declared first in the data model, which means Logical and Physical (the intent), and then in the implementation (the intent realised).
One to zero-to-many
In SQL that (the above) is all that is required.
One to one-to-many
You need a Transaction to enforce the one in the Referencing table.
One to zero-to-one
You need in Bar:
CONSTRAINT AK -- constraint name
UNIQUE (Foo) -- unique column, which makes it an Alternate Key
One to one
You need a Transaction to enforce the one in the Referencing table.
Many-to-Many
There is no such thing at the Physical level (recall, there is only one type of relation in SQL).
At the early Logical levels during the modelling exercise, it is convenient to draw such a relation. Before the model gets close to implementation, it had better be elevated to using only things that can exist. Such a relation is resolved by implementing an Associative Table at the physical [DDL] level.
There is no difference. It's just a matter of language and preference as to which way round you state the relationship.
Answer to your first question is : both are similar,
Answer to your second question is: one-to-many --> a MAN(MAN table) may have more than one wife(WOMEN table) many-to-one --> more than one women have married one MAN.
Now if you want to relate this relation with two tables MAN and WOMEN, one MAN table row may have many relations with rows in the WOMEN table. hope it clear.
One-to-Many and Many-to-One are similar in Multiplicity but not Aspect (i.e. Directionality).
The mapping of Associations between entity classes and the Relationships between tables. There are two categories of Relationships:
Multiplicity (ER term: cardinality)
One-to-one relationships (abbreviated 1:1): Example Husband and Wife
One-to-Many relationships (abbreviated 1:N): Example Mother and Children
Many-to-Many relationships (abbreviated M:N): Example Student and Subject
Directionality : Not affect on mapping but makes difference on how we can access data.
Uni-directional relationships: A relationship field or property that refers to the other entity.
Bi-directional relationships: Each entity has a relationship field or property that refers to the other entity.
This is an excellent question, according to my experience, in ERD diagrams and relational databases direction is implied. In RDBMS you always define Many-To->One (trivial case One-To->One) relationships. The Many side of the relationship, a.k.a children, references the One side, a.k.a parent and you implement this with a Foreign Key constraint. Technically speaking you have to access an index, fetch the Primary Key record of the One side and then visit this record to get more information.
You cannot do this the other way around unless we are speaking about Object-Relational DBMS such as Postgres, Intersystems Cache, etc. These DBMS allow you to define a bi-directional relationship between the two entities (tables). In that case accessing records the other way around, i.e. One--To-->Many is achieved by using an array of references (children). In ORMs you have classes that reference each other the same way we described here.
WARNING: Most RDBMS in the IT market are NOT relational database management systems in the strict sense, think about null values, duplicate records etc, many of these allowed features break the definition of what a Relation is.
There's no practical difference. Just use the relationship which makes the most sense given the way you see your problem as Devendra illustrated.
One-to-many and Many-to-one relationship is talking about the same logical relationship, eg an Owner may have many Homes, but a Home can only have one Owner.
So in this example Owner is the One, and Homes are the Many.
Each Home always has an owner_id (eg the Foreign Key) as an extra column.
The difference in implementation between these two, is which table defines the relationship.
In One-to-Many, the Owner is where the relationship is defined. Eg, owner1.homes lists all the homes with owner1's owner_id
In Many-to-One, the Home is where the relationship is defined. Eg, home1.owner lists owner1's owner_id.
I dont actually know in what instance you would implement the many-to-one arrangement, because it seems a bit redundant as you already know the owner_id. Perhaps its related to cleanness of deletions and changes.
---One to Many--- A Parent can have two or more children.
---Many to one--- Those 3 children can have a single Parent
Both are similar. This can be used according to the need. If you want to find children for a particular parent, then you can go with One-To-Many. Or else, want to find parents for twins, you may go with Many-To-One.
The easiest explanation I can give for this relationship is by piggybacking on evendra D. Chavan'sanswer.
Using the department and employee relationship
A department can have multiple employees, so from the employee side, it's one-to-many relationship, and from the department side it's many-to-one relationship
But if an employee can also belong to more than one department, we can also say from the employee side it's now many as opposed to one, so the relationship becomes many-to-many
In order words, a simple understanding would be, we can state that a relationship is many-to-many if one-to-many can be viewed from both sides
that is if;
one employee can belong to many departments (one-to-many)
one department can have many employees (one-to-many)
I am new to SQL and only have experience using SQLAlchemy. The documentation on relationships in SQLAlchemy does a good job explaining this, in my opinion.
You may find some clarity by reading this part
Also, I had to come up with my own example to think through this. I'll try to explain without writing a bunch of code for simplicity.
table Vehicle
column (name)
table Manufacturer
column (name)
A Vehicle can only have One manufacturer (Ford, Tesla, BMW etc.)
Manufacturers can make many Vehicles
Ford
Ford makes Mustang
Ford makes F-150
Ford makes Focus
Tesla
Tesla makes Model S
Tesla makes Model X
Tesla makes Roadster
When looking at the database rows you will want to decide if you want a column that references the other side of the relationship. This is where the SQLAlchemy documentation brings in the difference between backref vs. back_populates. I understand that is the difference between having a column in the table to reference the other side of the relationship or not having a column to reference the other side.
I hope this helps, and even more so, I hope I am accurate in the way I learned and understand this.
I have read most of the answer. The problem is not the relationship here at all. If you look at One to Many or Many to One conceptually, it is just a reversible relationship. HOWEVER, while implementing the concept in your software or application it differs a lot.
In case of Many to One, we often desire the table that has Many aspect to be written first and we desire it to associate with the table containing One aspect. If you convert Many to One concept into One to Many, you will have hard time writing the One aspect table first in your code. Since, the relationship is defined while you engineer the database, Many aspect table will seek for the One aspect table data for integrity. So if you are planning to do it by using foreign key -> unique key or foreign key -> primary key, Many to One implementation will be different even if you consider it as a One to Many.
I personally make associations without using actual relationship concepts in many cases. There is no such boundaries as to use Database concept to form relationship every time. Just make sure that your database integrity is maintained as you want, it is indexed properly for your search needs and is decently normalized.
one-to-many has parent class contains n number of childrens so it is a collection mapping.
many-to-one has n number of childrens contains one parent so it is a object mapping