| Author |
Topic |
|
barrabutus
Starting Member
6 Posts |
Posted - 2011-02-01 : 21:37:02
|
Hi AllAfter 3 hours of trying to get this to work, I gave up and came here lolI understand that Foreign Keys are the "links" between tables.As im new to SQL relations, I thought i would try it out I created 2 tables (Users,Passwords) Users Table - 3 Fields (user_id,username,password_id)Now trying to use password_id (Auto_increment field as the identifier from Passwords table)Passwords Table - 2 Fields(password_id,password)Tables Image The below code does exactly what i want when i run it once.but i run it again and the table returns with 4 rows :SIt shows me i have 4 rows 2 with identical user_id,s even when that row is set to auto increment. I have no idea why this is?--Insert a new passwordINSERT INTO passwords(password ) VALUES ('TestPass')--Insert a new user and get the last insert (Insert above to retrieve the password ID)INSERT INTO users(username,password_id) VALUES ('NewUser',@@IDENTITY )--Display the comined tables.SELECT * FROM users,passwordsImage Below DELETE FROM users WHERE username = 'NewUser' It just deletes the users name but the linked FK of password_id still remains.The password of the deleted user still remains in the password table (Just to clarify)If anyone can point me to a decent tutorial which uses non-technical terms of how i can use FK,s and perform cascading deletions of data, It would be muchly appreciated.Alternatively if anyone has any solutions to how i can perform these tasks.Many Thanks Sorry for the long post Barrab :) |
|
|
MIK_2008
Master Smack Fu Yak Hacker
1054 Posts |
Posted - 2011-02-02 : 00:05:01
|
| 1) Well through out your post i don't see any sort of Foreign Key's definition (Constraint) over the pwdID field of Users table :). So if not created, create a foreign key constraint.2) but i run it again and the table returns with 4 rows :SThere are two records in each of the table so as per your select query it has (and should have) returned 4 rows ... :DCheers!MIK |
 |
|
|
barrabutus
Starting Member
6 Posts |
Posted - 2011-02-02 : 05:35:02
|
Thanks for your reply ;)I will post an image with the relationship As you can see i have Upon Delete Cascade set, So thinking that if i delete a user then the password associated to the user should be deleted as well from the passwords table.Q: When creating a relationship within MSSQL is the left table the parent table and the right table the child ? So take from the child and put the value into the parent ?I am asking as each tutorial/video i found which showed how to do this did not clarify in basic english which each side of the relationship was what.Or would this only be relevant IF i delete from a foreign key like so DELETE FROM users WHERE password_id = TheUserPasswordID Is this correct?Many Thanks Barrab |
 |
|
|
MIK_2008
Master Smack Fu Yak Hacker
1054 Posts |
Posted - 2011-02-02 : 05:56:57
|
| Can you script the definition of the foreign key's table to Create To and post the code here ? It should work if the cascade delete is turned on! Cheers!MIK |
 |
|
|
barrabutus
Starting Member
6 Posts |
Posted - 2011-02-02 : 07:50:04
|
Sorry for the excessively long reply but im trying to give as much information as i possibly can to make it easier for you to understand what im trying to achieve.The scripted FK USE [testDB]GOIF EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_users_passwords]') AND parent_object_id = OBJECT_ID(N'[dbo].[users]'))ALTER TABLE [dbo].[users] DROP CONSTRAINT [FK_users_passwords]GO Which looks like I tried this code and have written each step to try and solve this :), I tried commenting out each DELETE command to try each one but both resulted in the same problem. Maybe this will help--Clear the tables DELETE FROM users;DELETE FROM passwords--Insert new Password INSERT INTO passwords(password) VALUES ('AlexPass')--Insert New UserINSERT INTO users(username,password_id) VALUES ('Alex',@@IDENTITY )--Delete Alex from the users table. (This should remove AlexPass from password also)DELETE FROM users WHERE username = 'Alex'-- Try to delete by the linked password_idDELETE FROM users WHERE password_id = ThePasswordID--Result : Still the same Password still remains in password table-- After deletion Alex (Users Table) and AlexPass (Passwords Table) both should not exist.-- Check the tables ( Should only return 2 empty tables)SELECT * FROM usersSELECT * FROM passwords--FAILS AlexPass still remains in password table..But Alex has been deleted from Users.--RESULT : We have a password which has no user..Many thanks for your replys and help and taking the time to read my seriously long posts.Barrab :) |
 |
|
|
barrabutus
Starting Member
6 Posts |
Posted - 2011-02-02 : 08:01:44
|
UPDATE : If i use DELETE FROM passwords WHERE password_id = thePasswordId This actually works and drops the user Alex from Users table and removes AlexPass from the password table.Am beginning to think that i have my relationship the wrong way around ... lolSo i have to delete the users password by its ID for it to remove the user and password together ? (Surely a password cannot exist without a user??) I thought it would make sense to store any "links" between users and passwords into the users table but it doesnt seem to be working for me that way.Again Thanks :)Barrab |
 |
|
|
MIK_2008
Master Smack Fu Yak Hacker
1054 Posts |
Posted - 2011-02-03 : 00:23:30
|
| dear sorry if i was not clear but i asked for the "create table" syntax of the table having foreign key. Any how go through the below example hope you may point out the problem of your design your selves!!! Create table tab1(ID1 int primary key,Col1 varchaR(10))Create table tab2(ID2 int ,Col2 varchaR(10),ID1 int)ALTER TABLE tab2WITH CHECKADD CONSTRAINT FK_Table1_ID FOREIGN KEY (id1)REFERENCES tab1 (ID1) ON Delete cascade On update cascade;Insert into tab1 values(1,'aaa'),(2,'aaa')Insert into tab2 values(1,'ssfr',1),(2,'dewggg',2)Select * from tab1Select * from tab2-- AS you see that both primary keys values are inserted into the tab2. Now try to delete one of both of them Delete from tab1 where id1=2-- And Check now Select * from tab1Select * from tab2Cheers!MIK |
 |
|
|
blindman
Master Smack Fu Yak Hacker
2365 Posts |
Posted - 2011-02-03 : 10:32:58
|
quote: Originally posted by barrabutus Users Table - 3 Fields (user_id,username,password_id)Passwords Table - 2 Fields(password_id,password)
This implies that a user may have only one password, but that a password may belong to more than one user.Are you sure that is the scenario you are trying to model?It would make more sense to set your tables up like this:Users Table - 2 Fields (user_id, username)Passwords Table - 3 Fields(password_id, user_id, password)________________________________________________If it is not practically useful, then it is practically useless.________________________________________________ |
 |
|
|
Lamprey
Master Smack Fu Yak Hacker
4614 Posts |
Posted - 2011-02-03 : 12:41:53
|
quote: Originally posted by blindman
quote: Originally posted by barrabutus Users Table - 3 Fields (user_id,username,password_id)Passwords Table - 2 Fields(password_id,password)
This implies that a user may have only one password, but that a password may belong to more than one user.Are you sure that is the scenario you are trying to model?
I completely agree. My assumption was that this is just an investigatory exercise.quote: It would make more sense to set your tables up like this:Users Table - 2 Fields (user_id, username)Passwords Table - 3 Fields(password_id, user_id, password)
Although that prevents mutiple users from using the same password, it's not really a good solution. Why surrogate? Why put an atrribute of an entitity in another table that isn't even an entity? |
 |
|
|
blindman
Master Smack Fu Yak Hacker
2365 Posts |
Posted - 2011-02-03 : 13:08:13
|
quote: Originally posted by Lamprey Although that prevents mutiple users from using the same password, it's not really a good solution. Why surrogate?
This is probably not a good thread to resurrect the entire "surrogate vs natural key" debate.The important issue here is modeling the user/password relationship, not the implementation.________________________________________________If it is not practically useful, then it is practically useless.________________________________________________ |
 |
|
|
Lamprey
Master Smack Fu Yak Hacker
4614 Posts |
Posted - 2011-02-03 : 14:16:08
|
| I don’t think my question about the surrogate is a revival of that debate because UserID is not a natural key. And I agree with you that the model is very important. That is why I was asking question to see if you had some reason for modeling it that way. As I mentioned it seems like a really bad way to model a User/Password. However, I don’t know what your thought process is. Perhaps you were just showing one way to prevent the same password from being used by multiple users and that’s fair. But, I’d hate for a beginner to think that modeling it that way would be a good idea unless there is a very compelling reason to put the password in its own table. |
 |
|
|
blindman
Master Smack Fu Yak Hacker
2365 Posts |
Posted - 2011-02-03 : 14:54:24
|
<Sigh> If you insist.quote: Originally posted by Lamprey As I mentioned it seems like a really bad way to model a User/Password.
No. You are absolutely 100% incorrect. It is an F'ing fantastic way to model users and passwords, and the only method that would be deemed acceptable by any dba with even a modicum of experience and sense.It allows a user to have multiple passwords. You got a problem with that? For multiple systems, or for maintaining password histories, or whatever.You got a problem with this? Let them flame-games begin.________________________________________________If it is not practically useful, then it is practically useless.________________________________________________ |
 |
|
|
Lamprey
Master Smack Fu Yak Hacker
4614 Posts |
Posted - 2011-02-03 : 15:22:28
|
| You obviously made a bunch of assumptions about how a password is/might be used that you didn't articulate. That's why I was asking questions. Thanks for being comletely rude about it though. |
 |
|
|
russell
Pyro-ma-ni-yak
5072 Posts |
Posted - 2011-02-03 : 15:35:41
|
| I don't allow cascading foreign keys ever.They introduce difficult to track down bugs. They cause data to be deleted/modified unintentionally. They change history -- a huge no no. They are the lazy programmers way out of actually understanding what they are doing. |
 |
|
|
blindman
Master Smack Fu Yak Hacker
2365 Posts |
Posted - 2011-02-03 : 16:28:34
|
quote: Originally posted by Lamprey You obviously made a bunch of assumptions about how a password is/might be used that you didn't articulate.
As did you. Of course, I did not raise these concerns at the time, because they were completely irrelevant to the subject of the post.quote: Originally posted by Lamprey Thanks for being comletely rude about it though.
Thanks. To be fair though, I wasn't the first one to break the rudeness barrier.quote: Originally posted by Lamprey Although that prevents mutiple users from using the same password, it's not really a good solution.
quote: Originally posted by Lamprey As I mentioned it seems like a really bad way to model a User/Password.
I'm just more open and honest and blatant about it.________________________________________________If it is not practically useful, then it is practically useless.________________________________________________ |
 |
|
|
blindman
Master Smack Fu Yak Hacker
2365 Posts |
Posted - 2011-02-03 : 16:30:22
|
quote: Originally posted by russell I don't allow cascading foreign keys ever.They introduce difficult to track down bugs. They cause data to be deleted/modified unintentionally. They change history -- a huge no no. They are the lazy programmers way out of actually understanding what they are doing.
I used to implement cascading deletes, but now I agree with you that the developers should really be aware of and handle such things in their code. I still use cascading updates on occasion, though.________________________________________________If it is not practically useful, then it is practically useless.________________________________________________ |
 |
|
|
Lumbago
Norsk Yak Master
3271 Posts |
Posted - 2011-02-04 : 03:51:53
|
| Barrab: someone obviously had a bad day when responding to your questions...I'll try to address a few of them. First of all, cascading updates/deletes are regarded as "bad" because it makes stuff happen automatically in your database without the use of code and as your system grows this will become less and less obvious what's going on behind the scenes. I try to avoid triggers as well for that very same reason...I think it reduces control over the stuff that's going on. You will be a lot better off by staying away from cascading updates/delets altogether. Now about this select you had that returned 4 rows; this is because you have no join condition. This will give you the correct result: SELECT * FROM users a inner join passwords b on a.password_id = b.password_id. What you did will create what is called a cartesian product which is basically all combinations of all rows -> http://en.wikipedia.org/wiki/Cartesian_product- LumbagoMy blog-> www.thefirstsql.com |
 |
|
|
MIK_2008
Master Smack Fu Yak Hacker
1054 Posts |
Posted - 2011-02-04 : 04:48:53
|
| Hi folks, it was the following part onto which i had this discussion with OP: "If anyone can point me to a decent tutorial which uses non-technical terms of how i can use FK,s and perform cascading deletions of data, It would be muchly appreciated."Yes the (cascade delete/update) approach is Bad to solve such problems. However i just replied in light of the above question.Cheers!MIK |
 |
|
|
barrabutus
Starting Member
6 Posts |
Posted - 2011-02-04 : 15:25:53
|
| Many Thanks for all your replys Sorry for the delayed reply, Ok just to clarify my thought process was that if i had a user and then any tables "linking" information to a user could be pulled from calling the users table. But as it looks like Cascading and Auto-Deletion is not really a good idea i think i will probably leave that alone and use manual queries like i used to in PHP, I just thought that with a relational system + cascading it would save me deleting from 1 table and then searching for an ID in 1+ more tables and then deleting any rows linked to the initial table.The main idea was a test program for me to learn to use tables in a relational way , So this was NOT a serious program just for self-educational purposes. Thank you for the SQL explaining why i received 4 rows from the SQL query i ran, That was very helpful :)Just to make the table thought process completely clear , So you can tell me if this is wrong (Bear in mind this is not a real table system ), I just need to know if im thinking of relationships the wrong way. 3 Tables Users (users_id,username,password_id,details_id)Details (details_id,Fname,Lname)Password (password_id,password)So we have a user named Joe Bloggs with a Password of Bloggy123 and he uses the username Joey to login.I am thinking that 1 user must have a First Name + Last Name and a password so this would be a 1-1-1-1 relationship throughout the tables because a Fname,Lname,Password will have no Rows without a user.I am thinking its more like a "Segregated" users table instead of having user_id,password,fname,lname all contained in 1 table each table has a responsibility to hold a "part" of the users information.We end up with 1 row in Users like so -- > (1,Joey,1,1)And DELETE from users WHERE user_id = 1 ( should truncate through the details and password tables and delete all rows with an id of 1)Im guessing this is the wrong way to perform this, I wish i understood relational tables a lot better (All the tutorials/videos i see show different things), So thats why im trying the practical approach.Thanks again for all your replys and taking the time to read my postBarrab. |
 |
|
|
barrabutus
Starting Member
6 Posts |
Posted - 2011-02-04 : 15:30:19
|
quote: Originally posted by Lamprey Perhaps you were just showing one way to prevent the same password from being used by multiple users and that’s fair. But, I’d hate for a beginner to think that modeling it that way would be a good idea unless there is a very compelling reason to put the password in its own table.
This is just an exercise to try and understand and learn how to use a relational table setup (Because my prior db designs have always been manually cascaded by hand) with no relations setup at all only when i have written in PHP and told it to do all the followup deletions so sending a lot of querys. |
 |
|
|
4dbobort
Starting Member
1 Post |
Posted - 2011-04-29 : 15:07:44
|
I think the problem might be the way you are selecting the data.You ran this query:SELECT * FROM users, passwords I think what you intended to do was this:SELECT * FROM users INNER JOIN passwords ON users.password_id = passwords.password_id |
 |
|
|
Next Page
|