How to create member_follower table structure? - sql

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

Related

How to insert a duplicate value in primary key column?

I have a table that has primary key on first column, but when I see the data available of this table, I find that records are repeated include primary key data. I want to know how can it be possible? Does primary column has repeated data in SQL Server 2008?
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[DemoTbl](
[ProcedureId] [int] NOT NULL,
[ProcedureName] [nvarchar](100) NOT NULL,
[VersionNo] [char](5) NULL,
[PublishDate] [datetime] NULL,
[PublishUser] [varchar](50) NULL,
[SpecialtyId] [int] NOT NULL,
[ProcedureNumber] [varchar](20) NULL,
[PowerpointName] [nvarchar](100) NULL,
[Duration] [int] NOT NULL,
[LanguageId] [int] NOT NULL,
[TierId] [smallint] NOT NULL,
[PrintPdf] [bit] NULL,
[PresentationModeId] [tinyint] NULL,
CONSTRAINT [pk_DemoTbl] PRIMARY KEY CLUSTERED
(
[ProcedureId] ASC,
[LanguageId] 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].[DemoTbl] WITH CHECK ADD FOREIGN KEY([PresentationModeId])
REFERENCES [dbo].[DemoTbl] ([PresentationModeId])
GO
ALTER TABLE [dbo].[DemoTbl] WITH CHECK ADD CONSTRAINT [FK_DemoTbl_Specialty] FOREIGN KEY([SpecialtyId])
REFERENCES [dbo].[Specialty] ([SpecialtyId])
GO
ALTER TABLE [dbo].[DemoTbl] CHECK CONSTRAINT [FK_DemoTbl_Specialty]
GO
ALTER TABLE [dbo].[DemoTbl] WITH CHECK ADD CONSTRAINT [FK_DemoTbl_TierMaster] FOREIGN KEY([TierId])
REFERENCES [dbo].[TierMaster] ([TierId])
GO
ALTER TABLE [dbo].[DemoTbl] CHECK CONSTRAINT [FK_DemoTbl_TierMaster]
GO
ALTER TABLE [dbo].[DemoTbl] ADD CONSTRAINT [DF_DemoTbl_CreationDate] DEFAULT (getdate()) FOR [CreationDate]
GO
ALTER TABLE [dbo].[DemoTbl] ADD CONSTRAINT [DF_DemoTbl_ModifiedDate] DEFAULT (getdate()) FOR [ModifiedDate]
GO
ALTER TABLE [dbo].[DemoTbl] ADD CONSTRAINT [DF_DemoTbl_IsActive] DEFAULT ((1)) FOR [IsActive]
GO
ALTER TABLE [dbo].[DemoTbl] ADD CONSTRAINT [DF_DemoTbl_LanguageId] DEFAULT ((1)) FOR [LanguageId]
GO
ALTER TABLE [dbo].[DemoTbl] ADD CONSTRAINT [DF_DemoTbl_ManageContent] DEFAULT ('false') FOR [ManageContent]
GO
ALTER TABLE [dbo].[DemoTbl] ADD CONSTRAINT [DF__Procedure__Print__1B14C01D] DEFAULT ((1)) FOR [PrintPdf]
GO
No, it is not possible in SQL Server to insert records that have duplicate values in the Primary Key.
It is not possible to have more than one row in the same table with the same primary key (PK).
If you are doing a SELECT and getting more than one row with the same PK could be because:
That table actually does not have a PK, maybe it was not properly created. You can check this by doing the following (it should return the PK column(s)):
SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'TableName' AND COLUMN_KEY='PRI';
The SELECT statement is not correct. Maybe you are selecting from two or more tables and you are not relating them correctly.
To clarify, you can do the following:
1- Create a new table:
CREATE TABLE IF NOT EXISTS `Customer` (
`id` int(4),
`name` varchar(20),
`surname` varchar(40),
`phone` int(9),
PRIMARY KEY (`id`)
) ENGINE=INNODB;
Now you have a new table for storing customers identified by an ID.
2- Let's add some customers:
INSERT INTO Customer VALUES(111, 'John', 'White', 123456789),
(222, 'Bianca', 'Williams', 987654321),
(333, 'Mikel', 'Peterson', 421345642),
(444, 'Jolene', 'Gomez', 948113552);
3- If you try to insert a customer with an existing PK (id) you will get an error:
INSERT INTO Customer VALUES (222, 'Paul', 'Brown', 123412345);
4- In order to check the final table, you can do the following select:
SELECT * FROM Customer;
No it is not possible to have duplicate primary keys if the primary key constraint has been set to True.
Further to prevent duplicate primary keys set the Identity Specification to True
If this table is an intermediate table in a many to many connection the original columns are foreign keys and able to accept many instances of the same prodId(the whole point of the exercise). If someone then slams a PK on that column then no more duplicates can be added but if you query it the table will still return the original stuff in this guys screenshot.
This scenario can be seen in the Northwind sample database between Products and orders (OrderDetails table has composite PK on OrderID, ProdID but still shows duplicates of both). The PK was added afterwards, after data had been added.
The intermediate table is a link between the Many-to-Many tables and in general doesn't need a PK. Normalization 101.
For PK Constraint it create a Unique Index (Clustered / non Clustered ) on defined PK. If we disable indexes before loading that include PK Unique Index as well than we can insert duplicate PK in the column because the PK constraint is disabled. So while disabling Indexes please avoid PK index not be disable "is_primary_key=0 to disable all other indexes"
Tested -> it's possible if we create a primary key with nonclustered index. If we disable this index we will be able to insert duplicated record then. But - it won't be possible to enable (rebuild) the index back with duplicated values on primary key

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?

Should I use the inserted table in this trigger to set a default value for a nullable foreign key?

I have a table with a nullable FK field. I made it nullablle to avoid changing the loader.
In order to achieve (Advertisers)* 1(Currencies), I wrote a simple trigger:
ALTER TRIGGER InsertedAdvertisersDefaultCurrency
ON dbo.Advertisers
FOR INSERT
AS
UPDATE Advertisers
SET Currency_Id=(SELECT TOP 1 Id FROM Currencies WHERE Name='USD')
WHERE Currency_Id=NULL
My question is basically about how I am checking the whole table for null rows on every insert.
I feel like I should be using the inserted table (?)
Here's the table:
CREATE TABLE [dbo].[Advertisers](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](max) NOT NULL,
[Currency_Id] [int] NULL,
CONSTRAINT [PK_Advertisers] PRIMARY KEY CLUSTERED
(
[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
ALTER TABLE [dbo].[Advertisers] WITH CHECK ADD CONSTRAINT [FK_CurrencyAdvertiser1] FOREIGN KEY([Currency_Id])
REFERENCES [dbo].[Currencies] ([Id])
GO
ALTER TABLE [dbo].[Advertisers] CHECK CONSTRAINT [FK_CurrencyAdvertiser1]
GO
Yes, you should just update the insertd records:
UPDATE Advertisers
SET Currency_Id=(SELECT TOP 1 Id FROM Currencies WHERE Name='USD')
WHERE Id in (select Id from inserted)
Or you may use a default value in that field
ALTER TABLE [dbo].[Advertisers] ADD CONSTRAINT [DF_Advertisers_Currency_Id] DEFAULT ((101)) FOR [Currency_Id]
GO
Where 101 is the USD 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.

How do you add Foreign Key Relationships?

I'm working with an existing SQL 2005 database that was not implemented with FK relationships between tables. I tried to add the relationships with a database diagram and my application immediately blew up trying to edit or insert any data that is tied to the new FK.
dbo.person [person_id | firstname | lastname | dateofbirth]
dbo.campaign [campaign_id | campaign_description]
dbo.disposition [disposition_id | disposition_description]
dbo.person_campaigns [person_campaign_id | person_id | campaign_id | disposition_id]
The person_campaigns table is where a person, campaign, and disposition are tied together. Can you please provide the appropriate SQL syntax for adding the proper FK relationships between these entities?
EDIT
CREATE TABLE [dbo].[person_campaigns](
[person_campaigns_id] [int] IDENTITY(1,1) NOT NULL,
[person_id] [int] NOT NULL,
[d_campaign_id] [int] NOT NULL,
[d_physician_disposition_id] [int] NULL,
CONSTRAINT [PK_person_campaigns] PRIMARY KEY CLUSTERED
(
[person_campaigns_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
CREATE TABLE [dbo].[d_campaign](
[d_campaign_id] [int] IDENTITY(1,1) NOT NULL,
[name] [varchar](50) NULL,
[year] [int] NULL,
[isactive] [bit] NOT NULL,
CONSTRAINT [PK_d_campaign] PRIMARY KEY CLUSTERED
(
[d_campaign_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
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[d_campaign] ADD CONSTRAINT [DF_d_campaign_isactive] DEFAULT ((1)) FOR [isactive]
GO
CREATE TABLE [dbo].[d_disposition](
[d_disposition_id] [int] IDENTITY(1,1) NOT NULL,
[name] [varchar](50) NULL,
[isactive] [bit] NOT NULL,
CONSTRAINT [PK_d_disposition] PRIMARY KEY CLUSTERED
(
[d_disposition_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
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[d_disposition] ADD CONSTRAINT [DF_d_disposition_isactive] DEFAULT ((1)) FOR [isactive]
GO
CREATE TABLE [dbo].[person](
[person_id] [int] IDENTITY(1,1) NOT NULL,
[firstname] [varchar](30) NULL,
[lastname] [varchar](30) NULL,
[dateofbirth] [datetime] NULL
CONSTRAINT [PK__person__0BC6C43E] PRIMARY KEY CLUSTERED
(
[person_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
the easiest way to do it is through the database diagram editor; do them one at a time and save the diagram to affect the tables after each connection is made. If it "blows up" it is most likely because the tables contain foreign-key values that do not exist; you'll have to clean these up first.
If you have to add them after the table is created the syntax is
create table person (person_id int primary key
,firstname varchar(10)
, lastname varchar(10)
, dateofbirth varchar(10))
create table campaign (campaign_id int primary key
, campaign_description varchar(10))
create table disposition (disposition_id int primary key
,disposition_description varchar(10))
create table person_campaigns(person_campaign_id int
,person_id int, campaign_id int ,disposition_id int)
go
alter table person_campaigns add Constraint
fk_person_campaigns_person_id
Foreign Key (person_id) References person(person_id)
GO
alter table person_campaigns add Constraint
fk_person_campaigns_campaign_id
Foreign Key (campaign_id) References campaign(campaign_id)
GO
alter table person_campaigns add Constraint
fk_person_campaigns_disposition_id
Foreign Key (disposition_id) References disposition(disposition_id)
GO
Suppose I had two tables that should have had a foreign key but did not. The first thing to do is check to see if there will be a data problem if I set a foreign key.
something like the below code would get you the records in the child table that do not have a match in the parent table.
select t2.FKField, t2.PKfield from table2 t2
left join Table1 t1 on t2.fkfield = t1.pkfield
where t1.pkfield is null
Once you can see what is wrong with the existing data, then you need to create a way to fix it. The fix will vary depending on what data you have that has no relationship to the Parent table and what the tables represent. Suppose your parent table contained a VIN number for automobiles as the PK. If your child table contains the cars that were worked on by the shop, you would want to fix the issue by adding the nonexisting VINS to the primary table becasue you wouldn't want to lose the history of what was worked on. There are other structures where you might want to simply delete the records that don't match in child table because they are meaningless. In other circumstances you might want to update those records to some default value (perhaps a customer in the customer table called unknown). In still other circumstances, you might need to go to audit tables or backups to find the value of the PK that was deleted without the associated child records being deleted. The actual way to fix this problem is highly dependent on what the data is used for and how important it is to retain all historical records. Since you should never delete any record that might be related to a financial transaction for legal (and accounting) reasons, you need to be most careful with those.
After fixing all the data, then you run the code to create the FK constraint.
Since I don't have SQL Server on this PC and I don't memorize the syntax, the easiest thing to do is to create two new test tables, create TableA with an ID field, TableB with a field that is a FK of TableA.ID, and then script out TableB to see the ADD CONSTRAINT syntax. Do this using SQL Server Management Studio via a database diagram.
However, if you were able to successfully create the FKs in a data diagram, and you only can't add or update records, I believe something else is wrong. Script out the person_campaigns table and post the code.