Sql modifying relationships - sql

how do you change the relationship between two tables to a many to many to many relationship in sql. Im using oracle for the DB.
thanks

Relationships among tables are almost always, ONE-TO-MANY, or ONE-TO-ONE. There is no MANY-TWO-MANY relationship between two tables. If you want a MANY-TO-MANY you will need to create intermediate relation to hold the relationship.
For example, if you want a MANY-TO-MANY relationship between table A and B you will need to create an intermediate table C:
create table a (a_id number primary key);
create table b (b_id number primary key);
-- c will hold many-to-many relationship between a and b
create table c (
a_id number not null references a(a_id),
b_id number not null references b(b_id),
primary key(a_id, b_id)
);

Related

Simple database table design structure

I have a situation while database designing, A simple issue but needed a working suggestions
My database tables:
TableAees.
TableBees.
Aees can mapped/contain one or more records of table Bees or also can be without any Bees
Aees can also mapped with one or more records of table Aees itself
Here normal primary key and foreign key relationship/hierarchy won't solve the purpose and also worried that parent/child hierarchy may end up in forming a loop between tables and can give a duplicates records on various joins.
Need a better table mapping for above mentioned tables(a,b) which will satisfy 1 and 2 points.
So to avoid such a situation, how the table relationship/hierarchy will be a better approach?
Database used: SQL Server
Thanks for sharing your knowledge.
You seem to describe a many-to-many relationship. If so, you would create a thrid table to store that relationship, like so:
create table a (
a_id int primary key,
...
);
create table b (
b_id int primary key,
...
);
create table ab (
a_id int references a(a_id),
b_id int references b(b_id),
primary key (a_id, b_id)
)
Each a/b tuple is stored on a separate row in bridge table ab.

Handling many-to-many relationship in a sql query

So as you know in data modeling, the many-to-many relationships are handled by creating a bridge table. This will enable us to have foreign key constraints.
My question relating to query data from tables that have many-to-many relationships.
I will give an example. Let's say we have the following tables
Table 1
Column 1
Column 2
Column 3
Table 2
Column 1
Column 4
Column 5
Table 3 (bridge table)
Column 1
Ok, so when I tried to query data from table 1 and left joining with table 2 I got the same results as query data from table left joining with table 3 and left joining with table 2. And that makes me wonder if the bridge table is a necessary step to include in a SQL query!
Thank you in advance :)
Your bridge table has just one column, which suggests that you are confusing one-to-many relationships (or many one-to-one), and many-to-many relationships.
In a one-to-many relationship, the child table refers directly to the parent table, and there is no need for a bridge table:
create table orders (
order_id int primary key,
order_date date,
...
);
create table order_items (
order_item_id int primary key,
order_id int references orders(order_id),
...
)
In a many-to-many relationship, the bridge table has (at least) two columns, one for each of the referential table that come into play in the relation:
create table authors (
author_id int primary key,
name varchar(50),
...
);
create table books (
book_id int primary key,
title varchar(50),
...
);
create table book_authors (
author_id int references authors(author_id),
book_id int references books(book_id),
primary key (author_id, book_id)
)
Let's make your example less abstract. There are posts with dislikes and likes. Table 1 = likes, Table 2 = dislikes.
Table likes (post_id, who, why)
Table dislikes (post_id, who, why)
The bridge table is then
Table posts (post_id, content)
This is an example where two child tables are related by a parent table. You don't create the bridge table in order to get an m:n relation between the two child tables, but because the child tables make no sense without their parent table. The child tables are m:n related, but we don't usually call this an m:n relation, because the tables are only losely related (a like belongs to a post and a dislike belongs to a post, but the like doesn't really belong to the dislike).
When talking about m:n relations, we are usally not talking about parent/child relationship.
An example: An order can contain many products and a product can be in many orders.
Table orders (order_id, date)
Table products (product_id, name, price)
The bridge table is the position in the order:
Table order_detail (order_id, product_id, amount)
There is no parent/child relation between orders and products, but the two are related, because products get ordered. This is what we typically call an m:n relation. The bridge table establishes the relation between order and product.

many to many to many SQL schemas

I have 2 tables: A and B.
A many-to-many relation units them through a join table A_B.
Now, my needs evolve: an A and a B can be related by more than 1 way.
I don't know what is the more conventional way to do that.
Must I declare a new "relation_way" table that contains the different "ways" for a A to be connected to a B and use this to compose a ternary key in A_B?
I would simply add a column to a_b that states the type of the relationship, e.g. relation_type that stores e.g. owned_by or referred_to or however you want to describe that relation (your obfuscated table and column names do not help a bit in answering this).
create table a_b
(
a_id integer not null references a,
b_id integer not null references b,
relation_type text not null
);
If you allow multiple relations but with different types between two entities, then include the relation_type in the primary key of the a_b table.
If you want to restrict the possible relation types, you should create a lookup table:
create table relation_type
(
id integer primary key,
type_name varchar(20) not null unique
);
and reference that from the link table:
create table a_b
(
a_id integer not null references a,
b_id integer not null references b,
relation_type_id integer not null references relation_type,
primary key (a_id, b_id, relation_type_id)
);

query with SQL m:n relationships

I have a quick question with respect to many to many relationships in sql.
So theoretically i understand that if 2 entities in an ER model have a M:N relationship between them, we have to split that into 2 1:N relationships with the inclusion of an intersection/lookup table which has a composite primary key from both the parent tables. But, my question here is , in addition to the composite primary key, can there be any other extra column added to the composite table which are not in any of the 2 parent tables ? (apart from intersectionTableId, table1ID, table2ID) a 4rth column which is entirely new and not in any of the 2 parent tables ? Please let me know.
In a word - yes. It's a common practice to denote properties of the relationship between the two entities.
E.g., consider you have a database storing the details of people and the sports teams they like:
CREATE TABLE person (
id INT PRIMARY KEY,
first_name VARCHAR(10),
last_name VARCHAR(10)
);
CREATE TABLE team (
id INT PRIMARY KEY,
name VARCHAR(10)
);
A person may like more than one team, which is your classic M:N relationship table. But, you could also add some details to this entity, such as when did a person start liking a team:
CREATE TABLE fandom (
person_id INT NOT NULL REFERENCES person(id),
team_id INT NOT NULL REFERENCES team(id),
fandom_started DATE,
PRIMARY KEY (person_id, team_id)
);
Yes, you can do that by modeling the "relationship" table yourself explicitly (just like your other entities).
Here are some posts about exactly that question.
Create code first, many to many, with additional fields in association table
Entity Framework CodeFirst many to many relationship with additional information

Designing 1:1 and 1:m relationships in SQL Server

In SQL Server 2008, how does one design a 1:1 and 1:m relationship?
Any relationship requires that the "parent" table (the one side) have a Primary (or unique) Key (PK), that uniquely identifies each row, and the "child" table (the other side) have a Foreign Key column or columns, that must be populated with values that are the same as some existing value[s] of the Primary Key in the parent table. If you want a one to many (1-M) relationship then the Foreign Key should be an ordinary attribute (column or columns) in the child table that can repeat (there can be many rows with the same value)
If you want a one to one (1-1) relationship then the Foreign key should itself be a Primary Key or unique index in the child table that guarantees that there may be at most one row in the child table with that value.
A 1-1 relationship effectively partitions the attributes (columns) in a table into two tables. This is called vertical segmentation. This is often done for sub-classing the table entities, or, for another reason, if the usage patterns on the columns in the table indicate that a few of the columns need to be accessed significantly more often than the rest of the columns. (Say one or two columns will be accessed 1000s of times per second and the other 40 columns will be accessed only once a month). Partitioning the table in this way in effect will optimize the storage pattern for those two different queries.
Sub-Classing. The above actually creates a 1 to zero or one relationship, which is used for what is called a sub-class or subtype relationship. This occurs when you have two different entities that share a great number of attributes, but one of the entities has additional attributes that the other does not need. A good example might be Employees, and SalariedEmployees. The Employee table would have all the attributes that all employees share, and the SalariedEmployee table would exist in a (1-0/1) relationship with Employees, with the additional attributes (Salary, AnnualVacation, etc.) that only Salaried employees need.
If you really want a 1-1 relationship, then you have to add another mechanism to guarantee that the child table will always have one record for each record/row in the parent table. Generally the only way to do this is by enforcing this in the code used to insert data (either in a trigger, stored procedure or code outside the database). This is because if you added referential integrity constraints on two tables that require that rows always be in both, it would not be possible to add a row to either one without violating one of the constraints, and you can't add a row to both tables at the same time.
One-to-One Relationship
Create Table ParentTable
(
PrimaryKeyCol ... not null Primary Key
, ...
)
Create Table ChildTable
(
, ForeignKeyCol ... [not] null [Primary Key, Unique]
, ...
, Constraint FK_ChildTable_ParentTable
Foreign Key ( ForeignKeyCol )
References ParentTable( PrimaryKeyCol )
)
In this case, I can never have more than one row in the ChildTable for a given ParentTable primary key value. Note that even in a One-to-One relationship, one of the tables is the "parent" table. What differentiates a One-to-One relationship from a One-to-Many relationship purely in terms of implementation is whether the ChildTable's foreign key value has a Unique or Primary Key constraint.
One-to-Many Relationship
Create Table ParentTable
(
PrimaryKeyCol ... not null Primary Key
, ...
)
Create Table ChildTable
(
, ForeignKeyCol ... [not] null
, ...
, Constraint FK_ChildTable_ParentTable
Foreign Key ( PrimaryKeyCol )
References ParentTable( PrimaryKeyCol )
)
In this scenario, I can have multiple rows in the ChildTable for a given ParentTable primary key value.
A 1:1 relationship exists where table A and table B only exist once in regards to each other.
Example: A student has 1 master student record. The student would be table A and the record in table B. Table B would contain a foreign key to the student record in table A (and possibly vice-versa)
A 1:m relationship exists where table A can be referenced or linked to by many entries in table B.
Example: A student can take several books out from the library. The student again would be table A and the book could be the entry in table B. The entry in table B would contain a foreign key to who checked the book out, and many books could reference the same student.