Associative Tables in SQL, 2 primary keys - sql

I am taking an introductory course on SQL and I'm stumped on one of our labs. For this lab, we get an ERD that we need to implement via SQL. The lab requires us to create two tables joined together with an associative table (SQL apparently doesn't like many to many relationships).
In this associative table, both attributes need to be primary keys and foreign keys (Pk, Fk) according the ERD. This doesn't make much sense to me (you can't have multiple primary keys) and thus have far I have been unable to implement the ERD by creating multiple primary keys in the table. Where I am going wrong here internet?
The code:
CREATE Table dbo.TargetMailingList
(
TargetID INT NOT Null
Foreign Key References dbo.TargetCustomers(TargetID),
MailingListsID INT Not NULL
Foreign Key References dbo.Mailinglists(MailingListID),
Primary Key (MailingListID,TargetID),
);

There are no two primary keys. It is a compound key. Both the columns are part of the same primary key. Check out http://en.wikipedia.org/wiki/Compound_key for more info.

You can create a compound key, as stated by #Juru and create 2 foreign keys:
CREATE TABLE dbo.Table_link
(
ndIdTable1 int NOT NULL,
ndIdTable2 int NOT NULL
) ON [PRIMARY]
GO
ALTER TABLE dbo.Table_link ADD CONSTRAINT
PK_Table_link PRIMARY KEY CLUSTERED
(
ndIdTable1,
ndIdTable2
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
ALTER TABLE dbo.Table_link ADD CONSTRAINT
FK_Table_Table_1 FOREIGN KEY
(
ndIdTable1
) REFERENCES dbo.Table_1
(
ndIdTable1
) ON UPDATE NO ACTION
ON DELETE NO ACTION
GO
ALTER TABLE dbo.Table_link ADD CONSTRAINT
FK_Table_Table_2 FOREIGN KEY
(
ndIdTable1
) REFERENCES dbo.Table_2
(
ndIdTable2
) ON UPDATE NO ACTION
ON DELETE NO ACTION
GO

Related

Is there any possibility to have two PK on one table in sql server?

I am really surprised that the table having two PK columns.
When I am trying to add PK on another column then those two PK columns changed as normal and only one column changed to PK.
Below is the script it was given
ALTER TABLE [dbo].[ProductionPlaning] ADD CONSTRAINT [PK_ProductionPlaning] PRIMARY KEY CLUSTERED
(
[ProductionPlaningId] ASC,
[Date] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
By definition, a primary key is one or more fields that uniquely identifies a record in a database table. Therefore, you cannot have two separate primary keys for the same table.
If you just want the field to be unique, you simply make it a unique field by adding a unique constraint to it ALTER TABLE YourTableNAme
ADD UNIQUE (Date);
If you want the both ProductionPlanningId and Date to be the unique identifiers for your table; you make a composite primary key:
ALTER table TABLE_NAME
ADD CONSTRAINT [name of your PK, e.g. PK_TableName] PRIMARY KEY CLUSTERED(column1, column2, etc.)
The create script describes the situation.
ALTER TABLE [dbo].[ProductionPlaning] ADD CONSTRAINT [PK_ProductionPlaning] PRIMARY KEY CLUSTERED
(
[ProductionPlaningId] ASC,
[Date] ASC
)
As you see, the PK is created by two columns (ProductionPlaningId and Date) so there is no multiple different PK in the table. It is not possible.
A table can never have more than one Primary Key. However, a Primary Key can consist of several columns.In you example Primary key is made with more than one column .
A primary key is defined as one or more columns with the following properties:
The combination of values is unique.
None of the values is ever NULL.
Only one such set is called "primary".
Other sets are called candidate primary keys. A table can have any number of candidates, and you can even declare them as being NOT NULL and UNIQUE. However, the primary in "primary key" means "one".
By default SQL Server actually sorts the data on the data pages using the primary key (this is called a "clustered" index). The data is only stored once, so it can only be sorted once, further emphasizing the one-ness of the primary key.
That said, your question is really about composite primary keys. These are primary keys that have more than one column. In general, I avoid composite primary keys, preferring a synthetic identity column as a primary key. However, they are definitely allowed and sometimes useful.

How to create member_follower table structure?

I have one member table structure in SQL Server:
member_table
memberid name address email
111 aaa IND a#a.com
222 bbb UK b#b.com
Now I want to give such facility that one member can follow as many other members. How can I do that?
Should I create a new table? Should I use any flags?
I'm thiking to create a new table and give Member table
You can create another table consisting of two attributes (member_id, follows_member_id)
This table keeps records of each member following other members. Both attributes reference your members table. This is a standard approach in creating a many-many relation as it is normalized. read more
I would create a junction table with a key on both member_ids to ensure there is at most 1 row.
I try to not cater to YGWITs (your gonna want it), but it seems a subscription table would call for some additional metadata such as the date the subscription starts or the last access date to know if there is new activity.
I would end up with something like this:
CREATE TABLE [dbo].[member_subscription](
[member_id] [int] NOT NULL,
[target_member_id] [int] NOT NULL,
[date_created] [datetime] NOT NULL,
[date_last_visit] [datetime] NULL,
CONSTRAINT [PK_member_subscription] PRIMARY KEY CLUSTERED
( -- key on both member_id fields
[member_id] ASC,
[target_member_id] ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
-- Foreign key contrain for member_id
ALTER TABLE [dbo].[member_subscription] WITH CHECK ADD CONSTRAINT [FK_member_subscription_member] FOREIGN KEY([member_id])
REFERENCES [dbo].[member] ([member_id])
GO
ALTER TABLE [dbo].[member_subscription] CHECK CONSTRAINT [FK_member_subscription_member]
GO
-- Foreign key contrain for target_member_id
ALTER TABLE [dbo].[member_subscription] WITH CHECK ADD CONSTRAINT [FK_member_subscription_target_member] FOREIGN KEY([target_member_id])
REFERENCES [dbo].[member] ([member_id])
GO
ALTER TABLE [dbo].[member_subscription] CHECK CONSTRAINT [FK_member_subscription_target_member]
GO
-- Default value for date_created
ALTER TABLE [dbo].[member_subscription] ADD CONSTRAINT [DF_member_subscription_datecreated] DEFAULT (getdate()) FOR [date_created]
GO

Foreign Key referencing Primary key in the same table

I have a table with two columns as the primary key. These two columns are also a foreign key that references the same table:
(This table was created some time ago by someone who has since left the company)
CREATE TABLE [dbo].[tblItemLink](
[ItemListID] [int] NOT NULL,
[ItemID] [int] NOT NULL,
CONSTRAINT [PK_tblItemList] PRIMARY KEY CLUSTERED
(
[ItemListID] ASC,
[ItemID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[tblItemLink] WITH CHECK ADD CONSTRAINT [FK_tblItemLink_tblItemLink] FOREIGN KEY([ItemListID], [ItemID])
REFERENCES [dbo].[tblItemLink] ([ItemListID], [ItemID])
GO
ALTER TABLE [dbo].[tblItemLink] CHECK CONSTRAINT [FK_tblItemLink_tblItemLink]
GO
In practice, ItemID refers to tblItem.ItemID, and ItemListID is found nowhere else in the DB but there is a corresponding enum in the application.
Is there any reason for the primary key to also be a foreign key referencing itself (ie. some undocumented performance improvement), or is it just a mistake?
I know of no reason why this, specifically, could provide a benefit - so I'm going to go with option 2 - a mistake.
Of course, if it was different columns in the same table, that would make sense, and as #Jignesh.Raj points out, that would form some kind of hierarchy.
You can even sometimes end up with multiple hierarchies within the same table with such multi-column references:
CREATE TABLE T (
GroupID int not null,
ItemID int not null,
ParentItemID int null,
constraint PK_T PRIMARY KEY (GroupID,ItemID),
constraint FK_T_Parent FOREIGN KEY (GroupID,ParentItemID) references T (GroupID,ItemID)
)
In the above, the GroupID column always references itself.
But as I say, with your current table, where both columns only reference themselves, it makes no sense.
Thats how you would create a hierarchy, and could also ensure you can't have a child with an invalid parent.
See also Should you make a self-referencing table column a foreign key?

How to create composite primary key in SQL Server 2008

I want to create tables in SQL Server 2008, but I don't know how to create composite primary key. How can I achieve this?
create table my_table (
column_a integer not null,
column_b integer not null,
column_c varchar(50),
primary key (column_a, column_b)
);
CREATE TABLE UserGroup
(
[User_Id] INT NOT NULL,
[Group_Id] INT NOT NULL
CONSTRAINT PK_UserGroup PRIMARY KEY NONCLUSTERED ([User_Id], [Group_Id])
)
Via Enterprise Manager (SSMS)...
Right Click on the Table you wish to create the composite key on and select Design.
Highlight the columns you wish to form as a composite key
Right Click over those columns and Set Primary Key
To see the SQL you can then right click on the Table > Script Table As > Create To
I know I'm late to this party, but for an existing table, try:
ALTER table TABLE_NAME
ADD CONSTRAINT [name of your PK, e.g. PK_TableName] PRIMARY KEY CLUSTERED (column1, column2, etc.)
For MSSQL Server 2012
CREATE TABLE usrgroup(
usr_id int FOREIGN KEY REFERENCES users(id),
grp_id int FOREIGN KEY REFERENCES groups(id),
PRIMARY KEY (usr_id, grp_id)
)
UPDATE
I should add !
If you want to add foreign / primary keys altering, firstly you should create the keys with constraints or you can not make changes. Like this below:
CREATE TABLE usrgroup(
usr_id int,
grp_id int,
CONSTRAINT FK_usrgroup_usrid FOREIGN KEY (usr_id) REFERENCES users(id),
CONSTRAINT FK_usrgroup_groupid FOREIGN KEY (grp_id) REFERENCES groups(id),
CONSTRAINT PK_usrgroup PRIMARY KEY (usr_id,grp_id)
)
Actually last way is healthier and serial. You can look the FK/PK Constraint names (dbo.dbname > Keys > ..) but if you do not use a constraint, MSSQL auto-creates random FK/PK names. You will need to look at every change (alter table) you need.
I recommend that you set a standard for yourself; the constraint should be defined according to the your standard. You will not have to memorize and you will not have to think too long. In short, you work faster.
First create the database and table, manually adding the columns. In which column to be primary key. You should right click this column and set primary key and set the seed value of the primary key.
To create a composite unique key on table
ALTER TABLE [TableName] ADD UNIQUE ([Column1], [Column2], [column3]);
CREATE TABLE UserGroup
(
[User_Id] INT Foreign Key,
[Group_Id] INT foreign key,
PRIMARY KEY ([User_Id], [Group_Id])
)

Problem Setting Foreign Key

I am trying to set a foreign key relationship between an Order_Items table and Parts table. I want to link the parts to products in the Order_Items table via foreign key. I have no issues doing this with other tables.
Here is how the Order_Items table is defined:
CREATE TABLE [dbo].[Order_Items](
[order_id] [uniqueidentifier] NOT NULL,
[product_number] [varchar](50) NOT NULL,
[quantity_ordered] [int] NOT NULL,
[product_tested] [bit] NULL,
CONSTRAINT [PK_Order_Items] PRIMARY KEY CLUSTERED
(
[order_id] ASC,
[product_number] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[Order_Items] WITH CHECK ADD CONSTRAINT [FK_Order_Items_Orders] FOREIGN KEY([order_id])
REFERENCES [dbo].[Orders] ([order_id])
GO
ALTER TABLE [dbo].[Order_Items] CHECK CONSTRAINT [FK_Order_Items_Orders]
and Parts table:
CREATE TABLE [dbo].[Parts](
[part_number] [varchar](50) NOT NULL,
[product_number] [varchar](50) NOT NULL,
[part_description] [varchar](max) NULL,
[part_tested] [bit] NULL,
CONSTRAINT [PK_Parts_1] PRIMARY KEY CLUSTERED
(
[part_number] ASC,
[product_number] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
I have tried setting the unique constraint on both product_number columns, but I still get the error message in SQL Server 2005 Management Studio Express as:
"The columns in table 'Order_Items' do not match an existing primary key or UNIQUE constraint"
Question: if [product_number] in your Parts table can be made unique by a unique constraint - why isn't it the primary key by itself??
My gut feeling: [product_number] in Parts isn't really unique - only the combination of (part_number, product_number), which is the primary key, really is unique.
If you can create a UNIQUE INDEX on the product_number column alone, you should be able to create the FK constraint - try this:
CREATE UNIQUE INDEX UIX01_Parts ON dbo.Parts(product_number)
ALTER TABLE dbo.Order_Items
ADD CONSTRAINT FK_OrderITems_Parts
FOREIGN KEY(product_number) REFERENCES dbo.Parts(product_number)
Does it work? If not - what error to you get, and where??
If that doesn't work, and only (part_number, product_number) is truly unique, then you need to reference both columns in your foreign key constraint:
ALTER TABLE dbo.Order_Items
ADD CONSTRAINT FK_OrderItems_Parts
FOREIGN KEY(part_number, product_number)
REFERENCES dbo.Parts(part_number, product_number)
and of course, this also means you need to have both those columns in your Order_Items table in order to be able to make the foreign key constraint work.
Just as a side note: having a compound primary key of two VARCHAR(50) columns and making that a clustered index on your Parts table is anything but optimal. If ever possible, try to make one or both of those "numbers" really a numeric type - e.g. an INT column. Or if that is not possible, think about having a surrogate PartID column (INT, IDENTITY) on your Parts table - that would make the FK constraint easier, too!
In order for this relationship to work, the Parts table cannot have composite key. In other words, you need to use product_number as the primary key since it is the column that they both have in common. You currently have part_number and product_number as your primary key.
Once you make that change, this statement will work:
ALTER TABLE [dbo].[Order_Items] WITH CHECK
ADD CONSTRAINT [FK_Order_Items_Parts] FOREIGN KEY([product_number])
REFERENCES [dbo].[Parts] ([product_number])
I ended up restructuring my entire database to get this to work and streamlined the table connections.