entity relationship between an actor and a receiver - sql

So I have a SQL relationship problem. Lets say I have a database where I want to keep records of information about individuals. Now I have setup a table to take on that information. Okay so far so good.
Often times duplicate information can be discovered in the table and it would be removed. A record is considered a duplicate if a particular field has the same value as another field in another row. Example: Duplicate emails.
Now I want to create another table in the database to keep track of every duplicate that is ever discovered and deleted. My first thought into this was to create a Foreign Key relationship. So I created and then connected a dupes table to my persons table. The relationship was a simple Foreign to Primary key relationship with an on delete constraint.
Now while that may have worked at first the problem arose that the dupes table was receiving records that were deleted even if they were not deleted because they were dupes. This was a problem because even if I decided to delete a person from the persons table just because I did not like them, they would stored in the dupes table anyway.
Then I thought, why not create a disposition field in the persons table and connect that as a unique or primary key to my dupes table's index foreign key. Well the problem is a unique key must have a unique value so multiple dispositions of dupe or I don't like you would not work. The other option was to make the disposition field a primary key. That has the same problem though.
What would be the right relationship for this problem?

I can think of this implementation: An on delete trigger, with a 'before delete' check. The before delete check would confirm if the record being deleted is a duplicate or not. Not sure what all RDBMS systems support such checks though.
IMO, the theoritical relationship is complicated because the record is supposed to be preserved even after the dupe is deleted.

Foreign Keys are not going to solve this problem. I discovered Triggers and their exactly what I need.

Related

MSSQL Multiple FKs in table: cannot have multiple cascade/set nulls?

I have a fairly simple design, as follows:
What I want to achieve in my grouping_individual_history is marked in red:
when a session is deleted, I want to cascade delete the grouping_history....
when a grouping is deleted, I just want the child field to be nullified
It seems that MSSQL will not allow me to have more than one FK that does something else than no action ... It'll complain with:
Introducing FOREIGN KEY constraint 'FK_grouping_individual_history_grouping' on table 'grouping_individual_history' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
I've already read this post (https://www.mssqltips.com/sqlservertip/2733/solving-the-sql-server-multiple-cascade-path-issue-with-a-trigger/), although it's not quite the same scenario it seems to me.
I've tried doing a INSTEAD OF DELETE trigger on my grouping table, but it wont accept it, because in turn, my grouping table has another FK (fkSessionID) that does a cascade delete... So, the fix would be to change it all, in all affected tables with FKs. The chain is long though, and we cannot consider it.
For one thing, can someone explain to me why SQL Server is giving me the issue for this very simple scenario in the first place? I just don't understand it.
Is there another workaround I could use (besides just removing the foreign key link from my grouping_individual_history table)?

How do I automatically delete all associated components while deleting a product in a SQL relational database?

Is this possible?
If so, does it happen automatically or do I need to config the definition of the foreign key in the component table properly?
The foreign key(s) would need to be defined as ON DELETE CASCADE in order for this to occur. Generally I'd recommend against such a setting because can you imagine (say) deleting a row from your GENDER table and suddenly discovering that half of the millon rows in your CUSTOMER table just vanished, and similarly half of the 100 million rows in your CUSTOMER_SALES tables also went.... That's a career limiting move.
If the foreign keys are not defined as ON DELETE CASCADE you could still mine the data dictionary to wor out the relationships in order to build a "delete child before parent" mechanism for those rare scenarios where you might need this

DELETE FROM table becomes heavy as the number of records in table's children increase

I have a main table called Campaign. Campaign's Id is a foreign key in another table CampaignRun and CampaignRun's Id is a foreign key in a third table CampaignRecipient. Due to my CASCADE requirements I am using
DELETE FROM Campaign WHERE Id = x
to remove all the associated information about a campaign. But this function becomes very heavy on the server and of course locks the tables while running. I was wondering if there is a faster way of dealing with DELETE FROM. TRUNCATE is faster but it unfortunately accepts no condition.
Will appreciate any working suggestions.
maybe you can check this out, interrupt() might be the answer

SQL Trigger: On update of primary key, how to determine which "deleted" record cooresponds to which "inserted" record?

Assume that I know that updating a primary key is bad.
There are other questions which imply that the inserted and updated table records match by position (the first of one matches the first of the other.) Is this a fact or coincidence?
Is there anything that could join the two tables together when the primary key changes on an update?
There is no match of inserted+deleted virtual table row positions.
And no, you can't match rows
Some options:
there is another unique unchanging (for that update) key to link rows
limit to single row actions.
use a stored procedure with the OUTPUT clause to capture before and after keys
INSTEAD OF trigger with OUTPUT clause (TBH not sure if you can do this)
disallow primary key updates (added after comment)
Each table is allowed to have one identity column. Identity columns are not updateable; they are assigned a value when the records are inserted (or when the column is added), and they can never change. If the primary key is updateable, it must not be an identity column. So, either the table has another column which is an identity column, or you can add one to it. There is no rule that says the identity column has to be the primary key. Then in the trigger, rows in inserted and updated that have the same identity value are the same row, and you can support updating the primary key on multiple rows at a time.
Yes -- create an "old_primary_key" field in the table you're updating, and populate it first.
Nothing you can do to match-up the inserted and deleted psuedo table record keys -- even if you store their data in a log table somewhere.
I guess alternatively, you could create a separate log table that tracked changes to primary keys (old and new). This might be more useful than adding a field to the table you're updating as I suggested right at first, as it would allow you to track more than one change for a given record. Just depends on your situation, I guess.
But that said -- before you do anything, please go find a chalk board and write this 100 times:
I know that updating a primary key is bad.
I know that updating a primary key is bad.
I know that updating a primary key is bad.
I know that updating a primary key is bad.
I know that updating a primary key is bad.
...
:-) (just kidding)

Create foreign key without checking existing data

This is a 2 part question.
Question 1: I am trying to create a foreign key on a table where I need to turn off the "Check Existing Data on Creation or Re-Enabling". I know theres an option visually but I'm looking for a way to do it programmatically. Is there anyway to do this?
Question 2: I have a code table and two tables A and B that need to reference that code table. I want to have these both referenced from a relationship table but I want to able to use the same column. Can I have 2 foreign keys pointing to the same column?
Yes you can have the same column inthe parent table refer to differnt columns in multiple tables.
I do not recommend turning off checking FK on creation. If you have bad data now, you need to fix it now. Otherwise the first time someone edits one of those records it will fail the FK check then.
From Books online as to why it is a bad idea to use nocheck:
If you do not want to verify new CHECK
or FOREIGN KEY constraints against
existing data, use WITH NOCHECK. We do
not recommend doing this, except in
rare cases. The new constraint will be
evaluated in all later data updates.
Any constraint violations that are
suppressed by WITH NOCHECK when the
constraint is added may cause future
updates to fail if they update rows
with data that does not comply with
the constraint.