I have a table named Books which contains 3 columns.
TableName: Books
Columns: BookId (PK), BookName, Book_Publisher_XRef_Id (FK), IsInternal
I have two tables that contains publisher information. Both these tables have different set of columns.
TableName: InternalPublishers
Columns: PublisherId (PK), PublisherName, ....
TableName: ExternalPublishers
Columns: PublisherId (PK), PublisherName, ....
I have a link table that contains information about which book belongs to which publisher. One book can have multple publishers.
TableName: Books_Publishers_XRef
Columns: Book_Publisher_XRef_Id (PK), PublisherId
If I want to create a Foreign Key constraint on PublisherId, I need to create sort of Composite Foreign Key constraint which I am not sure can be created.
So in this scenario, what is the best way to achieve FK on PublisherId in Books_Publishers_XRef table?
Break Books_Publishers_XRef table in 2 tables i.e. one for Internal Publishers and another one for External Publishers and have 2 columns in Books table for Books_Internal_Publishers_XRef and Books_External_Publishesr_XRef tables?
Don't create FK on Publisher_Id column and leave the design as it is?
Create composite FK by adding Publisher_Type_Id column in Books table and Books_Publishers_XRef table where if Publisher_Type_Id = 1, it belongs to Internal_Publishers table and Publisher_Type_Id = 2, it belongs to External_Publishers table ? (Not sure if this is possible)
Some other schema design?
Please advise.
Don't divide your data amongst two tables: InternalPublishers, ExternalPublishers. Create one table and have a bit field to determiner whether they are internal or external. Something like this:
create table Publisher
(
PublisherId int not null primary key clustered,
PublisherName varchar(100) not null,
IsInternal bit not null
)
go
That way you can easily create your foreign key reference. After all, you seem to have this same design for Books, keep that going to publishers.
Keep all common columns in the Publisher table.
Subtype tables have only columns specific to each one.
Related
I'm trying to create a foreign key between two tables. Problem is one of those tables has a composite primary key..
My tables are products (one row per product) and product_price_history (many rows per product).
I have a composite key in product_price_history, which is product id and start date of a specific price for that product.
Here's my code :
CREATE TABLE products (
product_id INT IDENTITY(1,1) PRIMARY KEY,
product_name VARCHAR(50) NOT NULL,
product_desc VARCHAR(255) NULL,
product_group_id INT
)
CREATE TABLE product_price_history (
product_id INT NOT NULL,
start_date DATE NOT NULL,
end_date DATE NULL,
price NUMERIC (6,2) NOT NULL
)
ALTER TABLE product_price_history
ADD CONSTRAINT pk_product_id_start_dt
PRIMARY KEY (product_id,start_date)
Now I'm trying to create a foreign key between the products table and the product_price_history table but I can't because its a composite key.
Also it doesn't make sense to add the start date (the other part of the foreign key) to the products table.
What's the best way to deal with this? Can I create a foreign key between these tables? Do I even NEED a foreign key?
My intentions here are
to enforce uniqueness of the product price information. A product can only have one price at any time.
to link these two tables so there's a logical join between them, and I can show this in a database diagram
The foreign key on the product_price_history table should only include product_id. Your target is to ensure that any entry product_price_history already has "parent" entry in products. That has nothing to do with start_date.
The way I see this situation, in theory, fully normalized version of the tables would have to have current_price as unique value in products table. And the product_price_history is simply a log table.
It's not necessary to do it this way, with a physical field, but thinking from this perspective helps to see where your tables model is slightly de-normalized.
Also, if you make product_price_history table anything but simple log table, how do you ensure that new start_date is newer than previous end_date? You can't even express that as a primary key. What if you edit start_date later? I would even think to create different compaund key for product_price_history table. Perhaps product_id+insert_date or only auto-increment id, while still keeping foreign key relationship to the products.product_id.
I'm asking about this generally, but I'll give an example for illustration purposes.
Table1 has the following columns:
ID (Pk)
Order_Desc
Order_DT
Table2 has the following columns:
ID (PK)
Product_Code (PK)
Product_Desc
Is it possible for me to have relationship between Table1 and Table2. If so, how would you do this in SQL without you running into an error? Would you be able to create a relationship if the Product Code or ID was not a primary key? Instead, it was a foreign key?
Your table2 does not have two primary keys - it has ONE primary key made up from 2 columns. Any relational table NEVER has more than one primary key - it's just not possible at all.
Any FK relationship to that table must include all the columns that the PK of the referenced table has - so any FK to Table2 must include both ID and Product_Code.
It's an all or nothing proposition - either your foreign key includes all columns of the referenced tables primary key - or you cannot establish a FK-relationship.
I have a problem to set correct constraint to make sure one column has and only has one matched column within the table.
For example, company Apple has Bloomberg ticker AAPL:US and only has this ticker. Otherwise, SQL Server will notice there is a error.
I try to use constraint with unique, but it does not work.
I imagine that your schema might be a standard one using a junction table. That is, your tables might look something like:
company (id, name)
ticker (id, name)
company_ticker (id_company, id_ticker)
That is, the company_ticker table is a junction table which stores the relationships between companies and tickers. Normally, this table would by default be many-to-many. But if you want to restrict a company to having only one ticker, then you may place a unique constraint on the id_company column:
CREATE TABLE company_ticker (
id_company INT NOT NULL,
id_ticker INT NOT NULL,
PRIMARY KEY (id_company, id_ticker),
CONSTRAINT cnstr UNIQUE (id_company)
);
With the above unique constraint in place, your schema will only allow a given company to have one relationship with some ticker.
I have 4 SQL tables: User, Student, Professor and Publication.
User has the common columns for any kind of user;
Student has columns specific for a student;
Professor has columns specific for a professor;
Publication is only for professors.
So I have:
create table dbo.[User] (
Id int identity not null
constraint PK_User_Id primary key clustered (Id),
-- Other user columns
)
create table dbo.Student (
UserId int not null
constraint PK_Student_UserId primary key clustered (Id),
-- Other student columns
)
create table dbo.Professor (
UserId int not null
constraint PK_Professor_Id primary key clustered (Id),
-- Other student columns
)
create table dbo.Publication (
Id int identity not null
constraint PK_Publication_Id primary key clustered (Id),
UserId int not null
-- Other student columns
)
alter table dbo.Student
add constraint FK_Student_UserId foreign key (UserId) references dbo.[User](Id);
alter table dbo.Professor
add constraint FK_Professor_UserId foreign key (UserId) references dbo.[User](Id);
alter table dbo.Publication
add constraint FK_Publication_UserId foreign key (UserId) references dbo.Professor(Id);
QUESTION
Should I have a column Id as PK in Professor and Student tables?
And make, for example, (Id, UserId) as the PK of Professor (Same for student)
Then Publication would reference Professor.Id and not Professor.UserId.
I am asking this because it sounds strange to have Publication to reference UserId from Professor table which can be confusing when I will have more tables.
Could someone please advice me on this?
In your current schema arrangement and without knowing your use cases (programmatically), one could make the argument that you don't need the Id identity columns for any of the extension tables. I assume this would be a 1 to 1 relationship to the User table anyway, so you'd at least want a unique constraint on the UserID columns, which you'd get by making it a PK anyway.
Things I like to consider are:
Can a professor ever become a different user ?
Is it possible for a professor to exist without an user ?
Is it possible for a single user to be two professors (multiple disciplines?)
If so, why wouldn't you give every professor an unique Id (ProfessorId), and only create a foreign key to the User table (UserId, you could call this UserFk).
In the publication table you can reference the professor by his/her id and call this one ProfessorFk. This way you create very efficient references between tables. The publication table than also gets a single PublicationId as primary key.
Correct me if i'm wrong, i don't know your use case. But it would seem reasonable that a professor can have multiple publications, but a publication can also be written by multiple professors ? This would mean you need an extra table between publication and professor for the n-n relationship.
About creating a professor key that is a combined key (Id, UserId). I personally dislike combined keys, if you want to reference this professor from your publication table you need two columns.
This would also suggest you can have multiple professors for the same user, if so, go for the single Id option.
This means i would create the following setup:
User Table
UserId
Student Table
StudentId
UserFk
Professor Table
ProfessorId
UserFk
ProfessorPublication Table
ProfessorFk
PublicationFk
Publication Table
PublicationId
So, it partly is based on what you want to be able to do with your data, and partly just your preference.
I have set up my tables like so:
Table A:
Id
[...]
Table B:
Id
AId
[...]
I have a foreign key created as
FK_TableB_TableA where primary key table is Table A and its primary key is Id and the foreign key table is TableB and its foreign key is AId...
However, when I update my dbml for linq TableB is defined as an entityref instead of an entityset...
Adding a foreign key should generate a one-to-many relationship correct?
This is very generic but if I need to add more detail please let me know!
Didn't figure out why this was happening however on the dbml there was no association created between the two tables for whatever reason - therefore I just added the association.