I have two entities - Request and Report. Each Request can have only one Report and each Report can belong to only one Request. This is one-to-one relationship.
Right now I'm thinking about underlying database schema. Right now in table requests I have FK to PK reports.id.
Is it a correct approach ? Where FK to other entity must be placed - in reports or requests table ?
That's all you need regarding the foreign keys. You may want to also add a unique constraint (unique index) to the foreign key for better performance and consistency guarantees.
Related
As mentioned in the title, is it possible to create many-to-many relationship between two tables that belong to two different databases? If yes, how can i perform that with PostgreSQL?
The standard way of using foreign key constraints to enforce referential integrity is only possible within the same database - not db cluster. But you can operate across multiple schemas in the same database.
Other than that, you can create tables just the same way. And even join tables dynamically among remote databases using dblink or FDW. Referential integrity cannot be guaranteed across databases by the RDBMS, though.
Does not matter much whether the other DB is on the same physical machine or even in the same DB cluster - that just makes the connection faster and more secure.
Or you can replicate data to a common database and add standard constraints there.
It should be possible, but as has been stated you cannot expect much in the way of referential integrity.
If you follow the standard design pattern of using a linking table, you can generate a sort of M2M relationship.
DB1.dbo.Users has the USER_ID primary key
DB2.dbo.Tasks has the TASK_ID primary key
you could create a table on either DB1 or DB2 that is UsersToTasks
DB1.dbo.UsersToTasks
USER_ID - KEY
TASK_ID - KEY
This way, a unique pairing of USER_IDs and TASK_IDs are used as a key in that table. The only thing is you cannot create a foreign key to the other table.
As a pseudo workaround, you could write a trigger on DB2.dbo.Task that would write the TASK_ID to DB1.dbo.TASK_IDS and link that as the foreign key on the linking table above. I'm not sure, but you could also potentially create a delete trigger that would remove the TASK_ID as well.
http://solaimurugan.blogspot.com/2010/08/cross-database-triggers-in-postgresql.html
I'm trying to set up an EDM on an existing SQL Server infrastructure, and came across a problem.
The EDM will not resolve a PK-FK relationship to a composite foreign key.
My DB table structure looks something like this (names changed to protect the innocent):
I have a PERSONS table containing an INT column called PerID (PK)
I have an OFFICE table containing an INT column called OffID (PK)
I am tying these tables together using a table called OFFICEPERSONS, creating a many-to-many relationship between PERSONS and OFFICE. This table has two INT columns, PerID and OffID, which together form a composite primary key.
I have a table called OFFICELOCATION that contains two INT columns, LocID and OffID. These two columns comprise a composite primary key. Additionally, OffID is also a FK to the OFFICE table.
Finally, I have a table called OFFICEPERSONSLOCATION. This table has three INT columns: PerID, OffID, and LocID. All three columns comprise a composite primary key. LocID and OffID provide a FK relationship to OFFICELOCATION, and OffID and PerID provide a FK relationship to OFFICEPERSONS.
With me so far? Hopefully, I haven't lost you yet. When all is said and done, my structure looks like this:
This structure works great in SQL Server. In EDM? Not so much. It will NOT allow me to construct the relation between OFFICEPERSONSLOCATION and OFFICEPERSONS. I get the following error:
Error 6037: Foreign key constraint 'FK_OFFICEPERSONSLOCATION_OFFICEPERSONS' has been omitted from the storage model. Column 'OffID' of table 'Model.Store.OFFICEPERSONSLOCATION' is a foreign key participating in multiple relationships. A one-to-one Entity Model will not validate since data inconsistency is possible.
Huh? Data inconsistency?!? How?
How do I get my entity framework to recognize this?
I agree that it is the entity framework's problem, and the problem is stupid. Even if you have the UPDATE CASCADE to "no action", it is not like you could create an inconsistency, but no, it claims that you can somehow.
In any case, in this situation, if you are willing to use surrogate keys instead of composite keys, you can get around this, because the only place to change the ID reference is in the main table.
In this case, OffID could be "inconsistent", but by using ID's in the OFFICEPERSONS and OFFICELOCATIONS tables (and therefore reference in OFFICEPERSONSLOCATION), you are forced to have the OffId managed in its primary table.
I'm designing a database for pure multi-tenancy (one database, one schema) and I'd like to keep a Tenant_Id in most of my tables as a security measure to ensure that data doesn't fall into the wrong tenant's hands. It seems like this would require a composite key on every table.
Example:
Under single-tenant circumstances, I would have a single primary key:
Animal_Id (PK)
Animal_Type
Animal_Name
Under Multi-tenant circumstances, I would add another primary key for Tenant_Id:
Animal_Id (PK)
Tenant_Id (PK)
Animal_Type
Animal_Name
Does adding a Tenant_Id column to every table mean that I will need to have a composite key in every table, or is there a secure way to avoid this? Composite keys are ok, but I'd like to avoid them if I can.
If all your ids are autoincremented integers, you can add tenant_id which is not a part of the primary key and just check for it in all your queries.
However, this has several side effects which you may or may not see as drawbacks:
You can possibly link two entities from different tenants in a many-to-many link table and the FOREIGN KEY constraint won't prevent you from doing this (as it would in case tenant_id were a part of the PRIMARY KEY)
Your users can evaluate how many other tenants are there from the ids
You will have to additionally join the entity tables to the searches which could possibly be done only from many-to-many link tables (to check the tenant)
In other words, if you really don't like composite keys for entities, it is possible to design the database without them.
Unless you are repeating the other id per customer (you could have two or more animal_id = 1) there is no real reason to make it a composite key. You can just add the field. That's works for us.
Do you really need to support two different tenants having the same ANIMAL_ID value? Whatever mechanism you're using to generate what appear to be synthetic primary key values should be able to generate values that are unique across tenants. Adding a TENANT_ID column to the table would potentially make sense but it's not obvious that adding it to the primary key would be beneficial.
When having a one-to-one relationship in a database the other table has a foreign key ID (in this example). And in a one-to-many relationship the table contains many foreign keys.
But does the database know whether this is a one-to-one or one-to-many relationship? Are the relationships that I make in an ER-Diagram only to indicate where there should be foreign keys when making the actual tables?
What is the difference between one-to-one and one-to-many relationship in a database?
In a sense, all the relationships we talk about are not known to the database, they are constructs we have invented to better understand how to design the tables.
The big difference in terms of table structure between one-to-one and one-to-many is that in one-to-one it is possible (but not necessary) to have a bidirectional relationship, meaning table A can have a foreign key into table B, and table B can have a foreign key into the associated record in table A. This is not possible with a one-to-many relationship.
One-to-one relationships associate one record in one table with a single record in the other table. One-to-many relationships associate one record in one table with many records in the other table.
To enable one-to-one relationship you need to add unique constraint to foreign key. It is not possible to have two foreign keys for each table as it will be impossible to create records.
Im having trouble understanding what the actual question is.
Your analysis is for the most part correct, in that if you have a 2 tables, and table2 has a foreign key to table one, it could be either a one-to-one or a many-to-one.
Your sentence "And in a one-to-many relationship the table contains many foreign keys."
The table of the 'many' side still contains one column that is a foreign key, its just that more than one row can have the same foreign key value (many rows point to one parent).
Also note that you can put the foreign key on the parent table, to the child, instead of the other way around. In this way, you can prevent one-to-many if you want to do that. Also note that in this way, more than one parent can share a child, which might or might not be what you want.
The database-level equivalent of a 1:1 vs. 1:m is having a unique index on the foreign key column. Note that this will only work for 1:1, NOT 1:0..1, as null is considered when evaluating uniqueness. There are workarounds for this restriction, but that's it at the basic level.
Similarly by example, a product has only one product code, so it's one-to-one relationship (product <-> ABC123), but a customer can purchase more than one product, so it's one-to-many relationship (person <->>>product).
well, you are right, this relation is important for you, but not for db itself. When you have two tables, one with your basic information, and another one with your detailed information.. for both tables you are you, so it is one-to-one relation, you can not map your data to somebody else.
Now add third table "cities" and one of your information points to city you live in - this is example of one-to-many (one city can be used, and should be used for many people).
one-to-many / one-to-one just show how your tables interact. And all the time, you want to "save" rows/columns in table not duplicating them you will use one-to-many relation with another table. Or many-to-many :)
Let's assume you have a table with two attributes A and B. If A is a candidate key and B is not then the relationship between A and B is 1 to many. If both A and B are candidate keys then the relationship is 1 to 1.
Given table A and B if
A and B have a strict 1 to 1 relationship
For every B instance, there will always be an A instance
The best approach is to make the primary key of B also a foreign key referencing A. This is also called "Table per Type Inheritance" and the "is a" relationship. There are other ways to enforce a unique foreign key, but using the primary key makes the relationship clear in the schema and in ER diagrams.
Of course there are always other scenarios, and if your design doesn't meet both of the criteria above, you'll have to use another approach.
If I want to implement the relationship between Category and Classified, is a database-level nullable foreign key required or is it possible/advisable for an application to define this type of relationship without using a database constraint?
[Note: Because the white dot indicates "optional" and the black dot "required", for each Category a Corresponding classified may or may not exist. In addition, the crows feet between them indicate this is a many to many relationship.]
Since it's a many-to-many relationship, you'll want a cross-reference table rather than a simple foreign key column.
So the Category table does not have a FK to Classified, and Classified does not have a FK to Category. Instead you can have a new table :
XrefCategoryClassified
FK to Category NOT NULL
FK to Classified NOT NULL
This is a typical way to implement a many-to-many relationship. And now, instead of worrying about NULLable fields if two records aren't related, you simply care about the existence or non-existence of a xref record
Why not use both?
Foreign keys, check constraints etc are known as "Declarative Referential Integrity" for a reason. They protect your data. What if you add a bulk load next month, or you have to run a SQL script to change data?
Another point would be that the database engine is the correct tool for this.
Absent compelling reasons to do otherwise, I'd enforce referential integrity at the database level; after all that's (partly) what an RDBS is good for.
And since you'll likely have some sort of mapping table to define the many-to-many relationship between Category and Classified, it seems like a no-brainer to put your constraints there. Your queries will thank you for it later.