Cascade delete is happening even though there is no foreign key relationship between 2 tables - vistadb

Lets say there are two tables Student and Address. There are no foreign key relationship between the two tables. Let me give the sample structure.
Student TABLE
ID, Name, AddressID, Email
Address TABLE
AddressID, DoorNo, Street, City, Country
The problem here is whenever I delete a record from the Student table the related entry in Address table is also getting deleted even though there is no foreign key reference.
We have thoroughly verified our dbschema scripts, there are no foreign key references. Let us know if we have to do something special in VistaDB for this.
Thanks In Advance
Murali

Related

Query regarding SQLite and Cascading foreign keys

I am currently writing a application in C# that uses a SQLite database to store information the user will input. The application is basically a Management system for users who are called "Students" in the application. This is the most important table in my database and every other table is linked off this table. What I want to do is when a student is removed - they leave the institute/get kicked out etc. - is to remove their data from all the other tables so that data is no longer there as it isn't needed. An example of some of the Create table statements I have written is:
CREATE TABLE student(studentID int(5) PRIMARY KEY NOT NULL, name string(16),...,DOB string(8) );
CREATE TABLE emergencyContact(emergencyID int(5) PRIMARY KEY NOT NULL, name string(16),..., contactNumber int(16));
CREATE TABLE emergencyContactOf(studentID int(5) FOREIGN KEY REFERENCES student('studentID'), emergencyID int(5) FOREIGN KEY REFERENCES emergencyContact('emergencyID');
I have read up on this and my understanding is the data will be deleted in the EmergencyContactOf table if I include a 'ON DELETE CASCADE' statement as the StudentID key will no longer be present in the Parent table.
However, my understanding is the data in the EmergencyContact table that is for that specific student will not be deleted as there is no reference to the StudentID.
My question is, is there a way to remove the data from this table also that is relevant to that Student? For example, if I was to include a column in the EmergencyContact table which would reference the StudentID as a Foreign Key and then remove that row if the StudentID is ever deleted from the parent table? Is this a good solution to this particular problem?
All other tables I have are also designed in this way, where the data is in different tables and then linked back to the Student table with relationship tables so this will also apply to all the other tables I have.
Thanks.
My question is, is there a way to remove the data from this table also that is relevant to that Student? For example, if I was to include a column in the EmergencyContact table which would reference the StudentID as a Foreign Key and then remove that row if the StudentID is ever deleted from the parent table? Is this a good solution to this particular problem?
What happens if multiple students have the same emergency contact? You don't want to duplicate data if you don't have to - that's the whole point of the emergencyContactOf table, to efficiently set up a many to many relation between students and emergency contacts. So you don't want to do something like you describe.
You could periodically (Monthly, yearly, after purging student rosters, whatever) run a delete that removes rows from emergencyContact if they don't appear in emergencyContactOf:
DELETE FROM emergencyContact
WHERE emergencyID NOT IN (SELECT emergencyID FROM emergencyContactOf)
or the like.
Hmm, I see two scenarios here. What if two students have the same emergency contact, say two bothers having their father as emergency contact?
If in such a case you store only one record (the father) in the emergency contact table, you don't want to delete the emergency contact if only one of them leaves. You'd delete the emergency contact for the other one. So you'd need additional logic, when to delete an emergency contact. You could put that in a trigger.
You use a less sophisticated approach and multiple rows from the emergency contact table can map to one person in real life. In that case you can pull the reference to the student directly into the emergency contact table and use ON DELETE CASCADE there.
CREATE TABLE student
(studentid int(5),
name string(16),
...
PRIMARY KEY (studentid),
...);
...
CREATE TABLE emergencycontact
(emergencycontactid int(5),
studentid int(5),
name string(16),
...
PRIMARY KEY (emergencycontactid),
FOREIGN KEY (studentid)
REFERENCES student
(studentid),
...);
The second might be tempting but the "clean way" is the first one, as the second allows contradicting data. From what you posted you're already on the "clean way". But a mentioned that required triggers.

SQL JDBC: parent key not found BUT the parent values have already been inserted into the database

I'm having a problem inserting mock data into the database
The table I'm trying to insert the values into is called 'purchased'
which has some foreign key values such as patient_id, pharmacy_id, drug_id.
The other 3 tables 'patient', 'pharmacy', 'drug' have already been added to the database successfully.
Patient table has a foreign key which is doctor_id. The 'doctor' table has also been added to the database.
Since I know that a foreign key patient_id in 'purchased' table depends upon another foreign key doctod_id, so I've done something like this
foreign key (patient_id, receipt_no) references patient(patient_id,doctor_id) ON DELETE CASCADE
Not sure what I've missed here, why does sqlplus complain that the parent key is not found? Just working for a database class project so I'm still learning.
Here's .sql code file
https://gist.github.com/mopkaloppt/de8fbf64c4d5711c90e2b389a72911ba
Any kind of help will be much appreciated.. I'm freaking out a bit now as I've been struggling with this for a while and it's due soon :(
This part of your FK constraint looks confused:
foreign key (patient_id, receipt_no) references patient(patient_id,doctor_id) ON DELETE CASCADE
^^^^^^^^^^ ^^^^^^^^^
You are getting the errors because there is no receipt_no in your purchased data that matches a doctor_id. This is perhaps unsurprising as the data are unrelated.
Having looked at the data in your patient table, it seems you haven't got the database design quite right. There's duplication in that table: if a patient has multiple illnesses or sees multiple doctors then there are repeated values for all other columns. This is also getting in the way of your FK constraint: you are trying to link a row in purchased to a patient, but there are multiple rows for some patients, so which row do you link to?
It seems you have a many-to-many relationship between patients and illnesses (a patient can have multiple illnesses, multiple patients can have an illness), and also between patients and doctors (a patient can be seen by multiple doctors, a doctor can see multiple patients). So, I would recommend introducing new tables for the relationships between patients and illnesses, and between patients and doctors. For example, here's the table you could use for the relationship between patients and doctors. Insert one row into this table for each combination of patient and doctor:
create table patient_doctor (
patient_id char(4) not null,
doctor_id char (4) not null,
primary key (patient_id, doctor_id),
foreign key (patient_id) references patient(patient_id) on delete cascade,
foreign key (doctor_id) references doctor(doctor_id) on delete cascade);
A linking table such as this is the standard way of representing a many-to-many connection in a relational database.
You don't yet have a table for illnesses, so I'll leave you to create a table for them, a linking table similar to that for patients and doctors (patient_illness perhaps), and the data in both tables.
Once you've done that, remove the doctor_id and illness columns from patient, remove the duplicate rows and make the patient PK depend only on patient. Your FK constraint from purchased to patient can then reference only patient_id.
Hopefully after doing all of this you should see your FK constraint violation errors go away.

SQL Schema Design: Associated with many tables?

Lets say I have a database with 4 types of things in it: Neighborhood, City, Houses, and Comment, like so
City:
name
ID
Neighborhood:
name
ID
CityID (foreign key to City:ID)
House:
name
ID
NeighborhoodID (foreign key to Neighborhood:ID)
CityID (foreign key to City:ID)
Comment:
ID
Text
???? (key to the subject of the comment)
I want users to be able to comment on a City, a Neighborhood or a House. How do I express this relationship in SQL?
One idea I had was to create 3 one to many relationship tables:
CommentToCity:
commentID
cityID
then when fetching the list of Cities, I could do a join on this table as well to get the related comments. I would then create a similar situation for House and Neighborhood.
Another idea would be to have globally unique identifiers in City, House and Neighborhood, and then have that global ID be the foreign key in the comment. Then when fetching the City it would do a join on comments looking for that global ID.
Are either of these a good way? Is there a better way?
Add a commentID to City, Neighborhood And House. (foreign key to comment:Id)
This way you just create an empty comment and add its Id if there is no comment on something.

How to model many-to-many relationships in SQL?

I have a major problem with my SQL design.
I need to create a database which models the following situation:
I have a list of capitals, it looks like this: Berlin, London, Prague, you get it. The other list is a list of travellers: John, Kyle, Peter etc.
The database needs to be able to answer queries such as: List of cities a given Traveller has visited, what Travellers has visited a given City and so on.
My problem is that when I create the two tables I just freeze and am unable to figure out the connection between them that would allow me to implement the intended behaviour.
I read up on it on the internet and I was told to use intersection entities, which I can, but I just don't see how that would help me. Sorry if this is a FAQ, but I just could not get my head around the proper keywords for a search.
Isn't it easier to create third table like travelers_cities with to foreign keys traveler and city, than you jan join that table with table you need and look for result there?
Solution:
Follow the following schema
First Table: Capital
Let say two columns: cid (Primary Key), Name
Second Table: Travellers
Let say two columns: tid (Primary Key), Traveller_Name
Now there is a many to many relationship that one traveller can travel/visit one or many capitals and one capital can be visited by one or many visitors.
Many to many relationship can be acheived by creating a new table which will act as reference/mapping table. let say "capital_travellers"
So, This third table will have following columns
capital_travellers:
id (Primary key): Its optional
cid (Primary key of Capital Table will work as Foreign key)
tid (Primary key of traveller Table will work as Foreign key)
Now when you want to fetch records, you will look into this table(capital_travellers).
I hope it helps.
In a many to many relationship it is necessary to implement a third junction table between the two entities. We could, say, name it travel. This table uses two foreign keys, one from each entity, to form one compound key.
Now you have 3 tables. One table called 'Traveller', one called called 'City' and a third junction table called 'Travel'. Lets assume the primary key for traveller is travellerId and for city it's cityId. The junction table takes these two keys to form a primary key for the entity 'Travel'. When u query the database for which cities a traveller with travelId '031' has travelled to it would make use of this junction table and return the cityId's to you.
If this doesn't help or if you need more clarification I recommend searching these terms:
Many-to-many
Cardinality

How to design a circular reference to a single database table with an added relationship?

I'm not sure how best to phrase the question, but essentially I have a table of contacts, and instead of doing the typical -- a contact has a reference to a table with spouse information, and a table with children, I want each of those people to be a contact, but then define a relationship between those contacts (brother, sister, child, spouse, etc.). So the contacts would exist in a single table, but I'm having trouble determining how best to define the relationship based upon their contact id and the relationship type. Any advice would be appreciated.
CONTACTS table
contact_id, pk
CONTACT_RELATIONSHIP_TYPE_CODE table
contact_relationship_type_code, pk
description
CONTACTS_RELATIONS table
parent_contact_id, pk, foreign key to CONTACTS table
child_contact_id, pk, foreign key to CONTACTS table
contact_relationship_type_code, foreign key to CONTACT_RELATIONSHIP_TYPE_CODE table
If you see the need to support multiple relationship types to a pair of people, add the CONTACTS_RELATIONS.contact_relationship_type_code column to the composite primary key
This is called a self join, it is pretty common and fairly easy to provide the functionallity you mention above. Take a look at this article.
Just implement an intersect table with four columns - key, contactid #1, contact id#2, and relationship.
Why do it this way? Because a contact can have several relationships.