How can I store an m:m realtionship into a database? - database

How can I store m:m relationship data in a database?
Suppose m knows knows m languages and m language can be known by any number of people.
i.e any number of people can known any number of language and any number of language can be known to different number of people.

A many to many relationship is best stored with a junction table.
http://www.tomjewett.com/dbdesign/dbdesign.php?page=manymany.php
In your case this would be called PersonLanguage
It would have Foreign Keys to both PersonId and LanguageId.
Both the Person and the Language tables would have a One to Many relationship with the PersonLanguage table.
Note you can either have a compound primary Key on PersonId and LanguageId or create a separate PersonLanguageId column that contains an auto-incrementing number.

3 tables..
Person (PersonId)
Language (LanguageId)
Person_Languages (Id,PersonId,LanguageId)

Usually something like this is done with three tables:
People(id, name, etc.)
Languages(id, name, etc.)
SpokenLanguages(peopleID, languageID)
...where SpokenLanguages is an association table that uses foreign keys to associate each person with the languages he/she speaks.

Related

How to choose (natural) primary key

Suppose there is a table keeping info about Vendors and Customers in one table named Partners (since one partner can be vendor at one point of time and customer at other).
Partners table have usual stuff: company name, short name, address, city, country. Now, for domestic partners there is DomesticVatNumber and for non-domestic there is InternationalVatNumber. Usually, vat number would be perfect candidate for primary key but the problem here is that not all domestic partners have InternationalVatNumber and international ones dont have DomesticVatNumber.
I am trying to see best ways to design this in db. Is surrogate key the only option in this case or should i maybe reconsider having domestic and international partners in same table? Should i maybe split them into 2 tables: DomesticPartners (which always have DomesticVatNumber) and InternationalPartners (which always have InternationalVatNumber) and then put primary key on DomesticVat and InternationalVat columns respectively?
What are pros/cons of each approach?
Personally, I would never make a primary key out of something assigned by an external party, nor would I use a value that the user would ever see. I would always use a meaningless key (either an identity column or a unique identifier).
Given what you are saying, I wouldn't split them into separate tables since you would then have to either have any table that referenced your partner table in a foreign key would either have to have two nullable columns setup to do this or have one column but no foreign key relationship (shudder...).
The best option is to have one table, have the domestic and international VAT numbers as separate fields in the table but not a primary key. Since they will both be nullable, you would have limited options for a unique constraint on them.
Just my 2 cents
As your business grows, your systems get more complex, and it makes more sense to have one table. An example can be an ENTITIES table which stores everyone and everything, including vendors and customers. This can include individuals, groups and businesses, clients and staff, etc. Later on you will be glad you did it this way, because it reduces the number of complex joins you are going to have with multiple tables. You can use ENTITY_NO as a surrogate key and ENTITY_TYPE to differentiate entities. VAT number fields can be indexed separately and made nullable.

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.

DataBase Analysis-junction table

This matter confuses me,
I have a College Information system the junction table between students table and subjects(curriculum) table, the primary key is composite key (StudentID, SubjectID) and both of them are Foreign keys but the student may be fail in exam and repeat the subject so we will have duplicate PK and we need to record all data. I have two ways to solve this matter but i don't know the best way?
Add new column as primary Key instead of composite key.
Join to the composite key Season Column and year column and the composite key will be(StudentID, SubjectID, Season, Year). I have to mention that i don't need this composite key as foreign key.
Which way is better for performance and DB integrity?
Subject and exam are separate (if related) concepts, so you should not try to represent them within the same table. Also, the fact that an exam has been held for the given subject is separate from the fact that any particular student took that exam. Split all these concepts into their own tables, and the model becomes more natural, for example:
Representing a student that took the same exam several times is just a matter of adding multiple rows to the STUDENT_EXAM table.
NOTE: STUDENT_SUBJECT just records the fact that the student has enrolled in the subject, but not when (which year/semester). Keeping semester-specific information may require additional tables and more complicated relationships within the model.
NOTE: There is a diamond-shaped dependency in this model. Since SUBJECT_ID was passed from the "top" (SUBJECT), down both "sides" (STUDENT_SUBJECT, EXAM) and then merged at the "bottom" (STUDENT_EXAM) of the diamond, a student cannot take an exam on a subject (s)he has not enrolled in.

Airline database prototype

I am designing an airline database (the outline of one anyway) for an assignment and seem to be running around in circles.
Three tables are concerned:
Customer Booking_Reference Flight
cust_id(pk) reference_id(pk) Flight_id(pk)
cust_id(fk)
A booking reference can have many flights.
A flight will have many booking references.
I am trying to break up the many to many relationship. Is it possible to have a relational table with the flight_id as the attributes (columns) and the booking_reference as the rows (data)? If so there can be no primary key, which is a no-go as I understand.
Alternatively I could make the booking_reference/flight relational table with 2 attributes and a compound primary key of booking_reference/flight, which would result in both entities being duplicated but the primary key being unique (half of it anyway). Is this acceptable design practice?
I was going to just list a max number of 8 flights as columns in the booking reference table (with NULL for the entries where there is less than 8 flights) and give customers with more than 8 flights a new reference_id, but this seems to be more ridiculous as i learn more about databases, resulting in more reference ids and more NULL data.
Any ideas on which route to take?
Rather than having eight (or any arbitrary number of) columns, create what's sometimes called a join table, with three columns:
Table: references_flights
id (Primary key)
reference_id (fk)
flight_id (fk)
You should then be able to query data across them with the right JOINs, but I'll leave that for someone with more database expertise.

How can I use arrays of references in SQLite?

I am implementing a system to represent a school schedule in SQL, and I want to have a table called Student which includes all of the student's classes. do i need to include references to a Class table as attributes class1,class2,class3,...,class12
or can I use a sort of array?
Since you are using relational database, it would be good to make a m:n relationship between Student and Class table. It would mean that you will have Student table with primary key student_id, Class table with primary key class_id, and one more table, called StudentClass with foreign keys fk_student_id and fk_class_id, plus some additional properties (depending on what do you want to achieve). That would be a good relational design.
You could have a field filled with a comma separated list, or you could keep a separate table of 'allowed classes', with associated data (unique ID number, name, description, teacher), then use foreign keys and an intermediate table to implement a many to many relationship of students to classes.
Many to many relationship
Foreign keys in SQLite
Support for foreign keys in SQLite is pretty good these days, and all the features you'll likely want are there.

Resources