Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
shapper
Constraint Violating Yak Guru
450 Posts |
Posted - 2007-10-17 : 06:31:31
|
| Hello,I have 3 tables. Posts, PostsTags and Tags.This is a many to many relationship.So PostsTags has the following columns:PostId (PK) and TagId (PK)I always did that way in SQL 2005.In some examples I see PostsTags have 3 columns:PostTagId(PK), PostId (FK), TagId (FK)Should I use it this way, instead?Thanks,Miguel |
|
|
Kristen
Test
22859 Posts |
Posted - 2007-10-17 : 06:51:36
|
| having a PostTagId can be helpful in identifying a specific record (single part key instead of multipart), I suppose, but I doubt its a good candidate for a PK!Kristen |
 |
|
|
nr
SQLTeam MVY
12543 Posts |
Posted - 2007-10-17 : 06:54:59
|
| Depends if you have a need for PostTagId.It doesn't serve any purpose apart from giving a single column to index.It's usually because people have a design rule that every table should have an identity column.Usually that table would have two unique indexes PostId,TagId and TagId,PostId so you wouldn't get any performance or space gain from PostTagId - if the table had other columns you might though.==========================================Cursors are useful if you don't know sql.DTS can be used in a similar way.Beer is not cold and it isn't fizzy. |
 |
|
|
Kristen
Test
22859 Posts |
Posted - 2007-10-17 : 07:08:54
|
I have come across the occasional tool that wants a single key, unique, column to manage scrolling grids and the like.Full Text Search needs that, but I don't suppose you are going to be asking it to look after your LINK table |
 |
|
|
shapper
Constraint Violating Yak Guru
450 Posts |
Posted - 2007-10-17 : 07:47:35
|
| Hi,My problems here are the behaviors I am looking for, and LINQ integration in Many to Many relationships.Consider the following tables:Posts (PostId PK)Files (FileId PK)PostsTags (PostId PK, TagId PK)FilesTags (FileId PK, TagId PK)Tags (TagId PK, TagName) The behavior I am looking, which seems logic to me, is:(This is the example for Posts. For files is the same)- When a tag is added to a Post, a record is added to TagsInPosts. If the Tag (given its TagName) does not exist in Tags then it is created in Tags table.- When a tag is removed from a post then it is deleted from PostsTags. If that tag, i.e., is no longer associated with other Post or File through PostsTags and FilesTags then it is deleted from Tags.I have Stored Procedures that do this.But can I simulate this with constrains and maybe triggers.To be honest I am just starting with LINQ so I am not sure where do I need to ensure this behavior: in my LINQ classes or in my SQL tables.Thanks,Miguel |
 |
|
|
shapper
Constraint Violating Yak Guru
450 Posts |
Posted - 2007-10-17 : 07:49:41
|
| By the way, in terms of a GridView I don't think that the Link table needs to have its own PK. Or maybe I am not getting the full picture.Thanks,Miguel |
 |
|
|
Kristen
Test
22859 Posts |
Posted - 2007-10-17 : 07:55:22
|
| "Or maybe I am not getting the full picture"No you are probably right, its just I've come across some Grid type things that can't be bothered to handle a multi-part key!In fairness it is a bit of a pain:To get the next record:SELECT TOP 1 ...FROM ...WHERE Key1 > @Key1 OR ((Key1 = @Key1 AND Key2 > @Key2) OR (Key3 ...ORDER BY Key1, Key2, Key3, ..."But can I simulate this with constrains and maybe triggers"Constrains maybe. Cascading deleted may be OK for this, but once you get too many "circular" relationships you won't be allowed to create them.Triggers definitely: "Delete from MyTable, if child records exist delete them too, if I'm the last child-of-my-parent delete my parent too .... "that type of thing is very do-able in a triggerKristen |
 |
|
|
jsmith8858
Dr. Cross Join
7423 Posts |
Posted - 2007-10-17 : 09:02:55
|
quote: Originally posted by shapper Hi,My problems here are the behaviors I am looking for, and LINQ integration in Many to Many relationships.Consider the following tables:Posts (PostId PK)Files (FileId PK)PostsTags (PostId PK, TagId PK)FilesTags (FileId PK, TagId PK)Tags (TagId PK, TagName) The behavior I am looking, which seems logic to me, is:(This is the example for Posts. For files is the same)- When a tag is added to a Post, a record is added to TagsInPosts. If the Tag (given its TagName) does not exist in Tags then it is created in Tags table.- When a tag is removed from a post then it is deleted from PostsTags. If that tag, i.e., is no longer associated with other Post or File through PostsTags and FilesTags then it is deleted from Tags.I have Stored Procedures that do this.But can I simulate this with constrains and maybe triggers.To be honest I am just starting with LINQ so I am not sure where do I need to ensure this behavior: in my LINQ classes or in my SQL tables.Thanks,Miguel
Yes, you would use a trigger for this. I am not sure why you want to do this; what if you want to eventually apply that tag to a different post? You'd have to keep deleting and then re-creating tags. Wouldn't it be better to have a "tag maintenance" page where you can see all tags and optionally delete any not associated with any posts?But, anyway, that has nothing to do with the need for an extra identity PK on your many-to-many table. I fail to see any advantage of having that key there. If you do have an identity as your PK on that table, you MUST add a unique constraint on the "true" key of PostID/TagID otherwise you will have no data integrity.I write about it here:http://weblogs.sqlteam.com/jeffs/archive/2007/08/23/composite_primary_keys.aspx- Jeffhttp://weblogs.sqlteam.com/JeffS |
 |
|
|
shapper
Constraint Violating Yak Guru
450 Posts |
Posted - 2007-10-17 : 16:00:29
|
Hi Jeff,I just read your article. Just one question: can I use composite Primary Keys when using GUID instead of an int?quote: Yes, you would use a trigger for this. I am not sure why you want to do this; what if you want to eventually apply that tag to a different post? You'd have to keep deleting and then re-creating tags. Wouldn't it be better to have a "tag maintenance" page where you can see all tags and optionally delete any not associated with any posts?
But: If at any moment I want to display all associated tags? Or if when creating a new post some of the tags already exist?My idea was to create a synchronization.I have an SQL procedure that does this:-- Create postINSERT INTO dbo.Posts(BlogId, AuthorId, PostTitle, PostBody)OUTPUT Inserted.PostId INTO @Posts(PostId)SELECT @BlogId, @AuthorId, @PostTitle, @PostBody-- Create post tagsINSERT INTO dbo.Tags(TagText)SELECT data FROM dbo.SplitText(@PostTags, ',') AS stWHERE NOT EXISTS( SELECT TagText FROM dbo.Tags WHERE TagText = st.data)-- Add tags ids to @TagsINSERT INTO @Tags(TagId)SELECT TagId FROM dbo.Tags AS tJOIN dbo.SplitText(@PostTags, ',') AS st ON t.TagText = st.data -- Associate tag to postINSERT INTO dbo.TagsInPosts(PostId, TagId)SELECT p.PostId, t.TagIdFROM @Posts AS pCROSS JOIN @Tags AS t I started to think of triggers because of Linq.I am rethinking my database to improve efficiency and also because of LINQ which I am starting to use.So any feedback is welcome.Thanks,Miguel |
 |
|
|
|
|
|
|
|