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.
Related
We have 2 tables with a 1:1 relationship.
1 table should reference the other, typically one would use a FK relationship.
Since there is a 1:1 relationship, we could also directly use the same Guid in both tables as primary key.
Additional info: the data is split into 2 tables since the data is rather separate, think "person" and "address" - but in a world where there is a clear 1:1 relationship between the 2.
As per the tags I was suggested I assume this is called "shared primary key".
Would using the same Guid as PK in 2 tables have any ill effects?
To consolidate info from comments into answer...
No, there are no ill effects of two tables sharing PK.
You will still need to create a FK reference from 2nd table, FK column will be the same as PK column.
Though, your example of "Person" and "Address" in 1:1 situation is not best suited. Common usage of this practice is entities that extend one another. For example: Table "User" can hold common info on all users, but tables "Candidate" and "Recruiter" can each expand on it, and all tables can share same PK. Programming language representation would also be classes that extends one another.
Other (similar) example would be table that store more detailed info than the base table like "User" and "UserDetails". It's 1:1 and no need to introduce additional PK column.
Code sample where PK is also a FK:
CREATE TABLE [User]
(
id INT PRIMARY KEY
, name NVARCHAR(100)
);
CREATE TABLE [Candidate]
(
id INT PRIMARY KEY FOREIGN KEY REFERENCES [User](id)
, actively_looking BIT
);
CREATE TABLE [Recruiter]
(
id INT PRIMARY KEY
, currently_hiring BIT
, FOREIGN KEY (id) REFERENCES [User](id)
);
PS: As mentioned GUID is not best suited column for PK due to performance issues, but that's another topic.
I'm trying to combine two tables in postgres - people and meetings. Each meeting can have multiple people. As a summary:
create table People (
id serial,
...
primary key (id)
);
create table Meets (
id serial,
...
primary key (id)
);
create table MeetsPeople (
meets_id integer references Meets(id),
people_id integer references People(id),
primary key(meets_id,people_id)
);
Is there a way to keep the meeting content but combine the people_ids (or even better all the info in the people table) into one attribute? An example output is below, l am basically looking to merge record 1 and 2, keeping the common attributes to notes and then keeping unique values for the people attributes.
Or am l best off just returning two seperate tables and combining this in the backend logic?
Hopefully that makes sense...
I have a column that sometimes will be null. This column is also a foreign key, so I want to know if I'll have problems with performance or with data consistency if this column will have weight
I know its a foolish question but I want to be sure.
There is no problem necessarily with this, other than it is likely indication that you might have poorly normalized design. There might be performance implications due to the way indexes are structured and the sparseness of the column with nulls, but without knowing your structure or intended querying scenarios any conclusions one might draw would be pure speculation.
A better solution might be a shared primary key where table A has a primary key, and there is zero or one records in B with the same primary key.
If table A can have one or zero B, but more than one A can refer to B, then what you have is a one to many relationship. This can be represented as Pieter laid out in his answer. This allows multiple A records to refer to the same B, and in turn each B may optionally refer to an A.
So you see there are two optional structures to address this problem, and choosing each is not guesswork. There is a distinct rational between why you would choose one or the other, but it depends on the nature of your relationships you are modelling.
Instead of this design:
create table Master (
ID int identity not null primary key,
DetailID int null references Detail(ID)
)
go
create table Detail (
ID int identity not null primary key
)
go
consider this instead
create table Master (
ID int identity not null primary key
)
go
create table Detail (
ID int identity not null primary key,
MasterID int not null references Master(ID)
)
go
Now the Foreign Key is never null, rather the existence (or not) of the Detail record indicates whether it exists.
If a Detail can exist for multiple records, create a mapping table to manage the relationship.
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)
);
What is the best way to translate the following problem in SQL table structure:
In a file transfer application, I have a master table with an "Upload type" field. Depending on the value of that field (FTP, SFTP, HTTPS, FS copy) the record is to be linked with other entries in the appropriate table (FTPsites, HTTPSSites, etc.) containing the relevant details.
This master table has several similar "switch" fields (upload, download, encryption, decryption, and a few application-related ones).
Currently, the table has a different field for each possible target table. This allows me to keep integrity constrains on the table but that's a lot of fields which are going to be NULL.
Is there a better schema for solving that problem ?
In case it's relevant, the target DB is MS SQL 2008
What you are describing is a database design issue akin to implementing table inheritance (where your master table is the parent and your type-specific tables are the children). You can see a really good explanation of how to implement table inheritance with SQL Server 2005/2008 here:
http://www.sqlteam.com/article/implementing-table-inheritance-in-sql-server
...but I will adapt the design pattern in that article to your specific case below.
First, you need a new table to hold your possible list of UploadTypes:
create table UploadType
(
UploadTypeID int primary key,
UploadTypeDesc varchar(50)
)
Now, make sure your MasterTable has a foreign key to the UploadType table and add an additional UNIQUE constraint to your master table on the fields MasterTableID and UploadTypeID:
create table MasterTable
(
MasterTableID int primary key,
UploadTypeID int references UploadType(UploadTypeID),
-- ...Other fields...
constraint MasterTable_AltPK unique (MasterTableID,UploadTypeID)
)
Assuming you have inserted values into the UploadType table so that HTTP uploads have an UploadTypeID = 1, FTP uploads have an UploadTypeID = 2, and SFTP uploads have an UploadTypeID = 3, you can set now up your upload-specific tables as follows (explanation at the end):
create table HTTPSites
(
HTTPSiteID int primary key,
UploadTypeID as 1 persisted, -- computed column; explanation below
-- ...Other fields...
foreign key (MasterTableID, UploadTypeID) references MasterTable(MasterTableID, UploadTypeID)
)
create table FTPSites
(
FTPSiteID int primary key,
UploadTypeID as 2 persisted,
-- ...Other fields...
foreign key (MasterTableID, UploadTypeID) references MasterTable(MasterTableID, UploadTypeID)
)
create table SFTPSites
(
SFTPSiteID int primary key,
UploadTypeID as 3 persisted,
-- ...Other fields...
foreign key (MasterTableID, UploadTypeID) references MasterTable(MasterTableID, UploadTypeID)
)
Each of these type-specific tables includes a dual-key foreign key to the master table on the MasterTableID and the UploadTypeID (this is how you get your referential integrity), and each includes a computed-column for the UploadTypeID that reflects the specific type of upload stored in that table. Each of these computed columns will force any new records inserted into these type-specific tables to be created with a specific UploadTypeID, therefore locking the tables to a specific upload type.
The beauty of this design is that it gives you database-driven referential constraints that meets all of your data integrity requirements without a lot of nulls. You can see the above posted article for detailed examples of how this schema prevents data integrity problems during inserts, deletes, etc. if you want to go deeper.