I have couple of tables and a junction table in between.
AspNetUsers and Tenant tables are already added in my Entity Framework.
But once I add UserTenant table, it ends up as association instead of entity.
Can someone enlighten me why this happens?
This happens because the only function of this junction table is to create a many to many relation.
When EF finds a table which only have columns which are FKs to other tables, and they compose the primary key, it simply converts it to a many-to-many relation.
If you need to have access to the junction table, you ned to break that rule. The easiest way to do so is adding a new column to the junction table which is not part of an FK, neither the PK. If you do so, the junction table will become an entity in your model. But you will lose the easy way to navigate to relate entities (it's still possible, but a bit harder). See this for more details
You can also read this article, which offers an alternate way of doing this, if you use Code First. If you read it, don't miss the comments. There are several very interesting
Related
I'm creating an ERD and in this m:n relationship I'm trying to indicate that there is a composite key in the LOCATION entity (by combining Location_ID and Department_ID). I realise that this will involve a joining table when it comes to creating a table relationship diagram, but in the ERD, is this notation correct to indicate a composite key?
Your PK,FK demonstration is technically not wrong but for an ERD you ultimately want to remove all many to many relationships otherwise it will cause you more problems down the line. You especially want to remove relationships like this if you have a composite key.
Here's a quick example of how i would do it roughly. (i could do a better one if i understood more info on your scenario and other tables etc...)
You ideally want to create another entity which holds both primary keys from the other tables and therefore creates a composite key. Notice, this also removes the many to many relationships.
I hope this gives you more of an understanding :)
I have a database with tables A and B in a one-to-many relationship. So one entity in A can be assigned to multiple and differing entities in B. A and B each have their own specific fields, but there are also fields and workflows related to either A or B, which are basically the same data but related only to either A or B.
As an example, an entity in A can have multiple comments for differing reasons and so can entities in B. Since there can be multiple comments for a single record I have to have a related comment table outside of tables A and B. I didn't want to have two comment tables, one for A and a separate table for B, so I set up a MasterID table that is related to both A and B and has referential integrity enforced. This means that when I want to add a record in A or B, I have to make sure that a MasterID already exists in the MasterID table. There are other tables that have the same type of functionality, comments is just one example, but if I didn't use a MasterID I'd have to create multiple tables each for A and B.
So my question is, is this the correct way to do this? Is there another way? The front-end will be in Access so I'm running into a little bit of trouble making sure a MasterID is created right before creating a new record in A or B.
MasterID(MasterID)
TableA(TableAID, FK_MasterID)
TableB(TableBID, FK_MasterID, FK_TableAID)
Comments(CommentID, MasterID, Comment)
Thanks for any help.
From a pure data design standpoint, you are on the right track, but not quite. You can use an entity-subtyping approach in which A and B are subtypes of another entity (MasterID). It is this supertype entity which attracts comments. However, for this to be true subtyping, the PK of A and the PK of B would be the FK to MasterID.
The way you've designed your tables, they have two candidate keys. If you eliminate the redundant candidate keys, then you have a standard entity-subtyping pattern, which is a legitimate and commonly used design approach.
Based on my understanding for the problem, I think this is too complex for a little value. If I understand you correctly, you have a situation like the picture and you want to make the key for Comment unique.
Creating a fourth table could work but it adds unnecessary complexity.
What you could do instead is to make the key for the Comments table a compound key of the two columns one is a sequence number and the other is a character field indicating the parent table. So you get keys like (A,1), (A,2), (B,3), (A,4), (B,5) ...etc.
This way you don't need the master table, and you don't need FKs in Table A or B.
I want to make sure this is the best way to handle a certain scenario.
Let's say I have three main tables I will keep them generic. They all have primary keys and they all are independent tables referencing nothing.
Table 1
PK
VarChar Data
Table 2
PK
VarChar Data
Table 3
PK
VarChar Data
Here is the scenario, I want a user to be able to comment on specific rows on each of the above tables. But I don't want to create a bunch of comment tables. So as of right now I handled it like so..
There is a comment table that has three foreign key columns each one references the main tables above. There is a constraint that only one of these columns can be valued.
CommentTable
PK
FK to Table1
FK to Table2
FK to Table3
VarChar Comment
FK to Users
My question: is this the best way to handle the situation? Does a generic foreign key exist? Or should I have a separate comments table for each main table.. even though the data structure would be exactly the same? Or would a mapping table for each one be a better solution?
My question: is this the best way to handle the situation?
Multiple FKs with a CHECK that allows only one of them to be non-NULL is a reasonable approach, especially for relatively few tables like in this case.
The alternate approach would be to "inherit" the Table 1, 2 and 3 from a common "parent" table, then connect the comments to the parent.
Look here and here for more info.
Does a generic foreign key exist?
If you mean a FK that can "jump" from table to table, then no.
Assuming all 3 FKs are of the same type1, you could theoretically implement something similar by keeping both foreign key value and referenced table name2 and then enforcing it through a trigger, but declarative constraints should be preferred over that, even at a price of slightly more storage space.
If your DBMS fully supports "virtual" or "calculated" columns, then you could do something similar to above, but instead of having a trigger, generate 3 calculated columns based on FK value and table name. Only one of these calculated columns would be non-NULL at any given time and you could use "normal" FKs for them as you would for the physical columns.
But, all that would make sense when there are many "connectable" tables and your DBMS is not thrifty in storing NULLs. There is very little to gain when there are just 3 of them or even when there are many more than that but your DBMS spends only one bit on each NULL field.
Or should I have a separate comments table for each main table, even though the data structure would be exactly the same?
The "data structure" is not the only thing that matters. If you happen to have different constraints (e.g. a FK that applies to one of them but not the other), that would warrant separate tables even though the columns are the same.
But, I'm guessing this is not the case here.
Or would a mapping table for each one be a better solution?
I'm not exactly sure what you mean by "mapping table", but you could do something like this:
Unfortunately, that would allow a single comment to be connected to more than one table (or no table at all), and is in itself a complication over what you already have.
All said and done, your original solution is probably fine.
1 Or you are willing to store it as string and live with conversions, which you should be reluctant to do.
2 In practice, this would not really be a name (as in string) - it would be an integer (or enum if DBMS supports it) with one of the well-known predefined values identifying the table.
Thanks for all the help folks, i was able to formulate a solution with the help of a colleague of mine. Instead of multiple mapping tables i decided to just use one.
This mapping table holds a group of comments, so it has no primary key. And each group row links back to a comment. So you can have multiple of the same group id. one-many-one would be the relationship.
This is a basic database design question. I want a table (or multiple tables) defining relationships between customers. I want it so PrimaryCustomer can be linked to multiple SecondaryCustomers, and can have many SecondaryCustomers with the same relationship.
PrimaryCustomerID RelationshipID SecondaryCustomerID
1) If the primary key is {PrimaryCustomerID} then I can only have one linked customer of any kind.
2) If the primary key is {PrimaryCustomerID, RelationshipID}, then I can only have one linked customer for each relationship type.
3) If the primary key is {PrimaryCustomerID, RelationshipID, SecondaryCustomerID}, then I can have whatever I like, but having all columns as the primary key seems completely wrong.
What's the right way to set things up?
A third alternative might be for the key to be (PrimaryCustomerId, SecondaryCustomerId), which would make sense if only one type of relationship is permitted per pair of customers. What keys to implement should be defined by what dependencies you need to represent in the table so that the table accurately represents the reality you are modelling. There's nothing wrong in principle with compound keys or all-key tables.
Number 3 is the right way to go for this data model. Linking tables often have all the columns in a join as all they do is link to other tables.
If a customer can only be linked to one primary customer then you can use a simple recursive relationship in the customer table itself.
CustomerID as PK
PrimaryCustomerID as FK to CustomerID
Nothing wrong with No 3.
If you need to prevent reverse-relationship duplicates, you can use
ALTER TABLE CustomerRelationship
ADD CONSTRAINT chk_id CHECK (PrimaryCustomerId < SecondaryCustomerId);
I'm in the process of creating a social network. It has several entities like news, photo, which can have comments. Since all comments have the same columns and behave the same way, and the only difference is their type — news, or photo, or something else to be added in the future — I decided to create one table for all comments with a column named type. It worked perfectly until I decided to add foreign keys to my database schema.
The comment table have a column parent, which refers to id of news or photo table, depending on the column type.
The problem is, I can't add a foreign key which refers to the unknown in advance table, and even more, which refers to several tables at once.
The whole database now uses foreign keys, except this one parent column in the comment table. It bothers me because it's the only place where I can't add a foreign key.
I'm sure I can't create such a foreign key; something in my database design needs to be changed. I decided to create one table for comments to be ready to add new comment types for new entities in the future — video, music, article, etc — and don't run into maintenance hell when I want to add one new column for all comments.
If I absolutely have to create a separate table for each comment type to be able to use foreign keys fully, I'll do that. But maybe another common solution to this problem already exists, and I'm just not aware of it?
Maybe I should create some sort of link table, which links the comment table with other entities' tables? But maybe this solution is even more complex than creating a separate table for each comment type?
Maybe I should have several columns in the comment table, like newsId, photoId, to which I can add foreign key?
These solutions just don't seem elegant to me, or I just misunderstand something. My whole perception of this issue might be plain wrong. That's why I'm here. Please share your ideas.
I think your problem is that you have several entities - news, photos. But these are all just types of (say) items. Like comments,items will probably have some attributes in common as well as some distinct attributes. One of those attributes will be the ability to be commented upon.
In this approach you have a table CommentableItems (1), with the common attributes. Then you have some sub-tables NewsItems, PhotoItems, etc. It is quite easy to set-up the keys for these tables to enforce the required one-to-one relationship. Obviously, Comments has a foreign key which references CommentableItems.
(1) Actually I would probably shoot myself rather than allow a table called something as ghastly as CommentableItems into my schema, but this is just for the sake of example.