I'm trying to model the following relationships between entities, mainly consisting of a partial, disjoint generalization.
original EERD
'mapped' to relational
Since I didn't need the subclasses to have any particular attributes I decided to use the "single table inheritance" approach, added the "type" field and moved the relationships towards the parent.
After that I had two choices to make:
1- type for the "business type" attribute
2- way to constraint participation to at most one of the 4 relationships based on the type attribute
For the sake of portability and extensibility I decided to implement no.1 as a lookup table (rather than enum or a hardcoded check).
About no.2 I figured the best way to enforce participation and exclusivity constraints on the four relationships would be a trigger.
The problem is that now I'm not really sure how to write a trigger function; for instance it would have to reference values inserted into business type, so I'd have to make sure those can't be changed or deleted in the future.
I feel like I'm doing something wrong so I wanted to ask for feedback before going further; is this a suitable approach in your opinion?
I found an interesting article describing a possible solution: it feels a bit like an 'hack' but it should be working
(it's intended for SQL Server, but it can be easily applied in postgres too).
EDIT:
It consists in adding a type field to the parent table, and then have every child table reference said field along with the parent's id by using a foreign key constraint (a UNIQUE constraint on this pair of fields has to be added beforehand, since FKs must be unique).
Now in order to force the type field to match the table it belongs to, one adds a check constraint/always generated value ensuring that the type column always has the same value
(eg: CHECK(Business_type_id = 1) in the Husbandry table, where 1 represents 'husbandry' in the type lookup table).
The only issue is that it requires a whole column in every subclass, each containing the same generated value repeated over and over (waste of space?), and it may fall apart as soon as the IDs in the lookup table are modified
Related
For an assessment task I'm doing, an entity album has the attribute also_bought, which is a self-referential attribute. However, this one attribute has multiple entries for any one album - as the also_bought recommendations are rarely only one recommendation - and thus, is a bit of a question mark when it comes to normalisation. I'm not sure whether it passes 1NF or not.
To be clear, the entire entity's set is
Album(album_id, title, playtime, genre, release_date, price, also_bought)
"Also bought" items should be stored in a separate table, something like.
AlsoBought (table)
album_id
also_bought_album_id
Then configure foreign keys from both columns to reference Album.album_id.
You mean that Album is a "self-referencing table" because it has a FK (foreign key) from one column list to another in the same table? (A FK constraint holds when subrow values for a column list must appear elsewhere.) If you mean that the type of also_bought is a list of album_ids, there is no FK from the former to the latter, because values for the former (lists of ids) are not values for the latter (ids). There's a constraint that is reminding you of a FK.
Anyway, normalization is done to one table, and doesn't depend on FKs.
But any time you are "normalizing to 1NF" eliminating "non-atomic columns" you have to start by deciding what your "table" "columns" contain. If you decide a cell for a column in a row contains "many values" then you don't have a relational table and you have to come up with one. The easiest way is to assume a set-valued column to get a relation and then follow the standard rules for elimination of too-complex column types.
I am little confused in understanding Candidate Keys. Do we check Candidate Keys in 1st Normal Form tables only?
As we know, a Candidate Key simply consists of a column or group of columns which can take the place of a Primary Key. If there are more than one then any one can stand as a Primary Key.
So, in 1st Normal Form there can be one table also i.e. we can make one big table and fill the whole table with values to remove repeating groups so we make Candidate Keys relating to one big table in 1st Normal Form.
Then what about 2nd Normal Form? or Third Normald Form. Do we find Candidate Keys for tables in these forms or only once, in 1st Normal Form?
If yes, then what does it mean if previous Candidate Keys are not removed which were found in the 1st Normalized Form table before new Candidate Keys are added in 2nd and 3rd Normal Form?
As we normalize to a higher normal form we replace a relation by other relations that join back to that relation. Each new relation has fewer attributes than the one it came from. And each may satisfy fewer functional dependencies, which are how we determine its candidate keys. Since each relation has its own attributes and satisfied functional dependencies, it may have different candidate keys.
The candidate keys of a relation that we decomposed just don't matter any more because we aren't using it any more. We don't "remove" candidate keys. The candidate keys of a relation depend on its attributes and the functional dependencies it satisfies.
PS Sometimes a non-relational table "normalizes" to multiple 1NF relations. Sometimes "normalizing" a relation to 1NF by replacing attributes by those deemed in some sense "simpler" produces multiple relations.
PPS Normalization does not necessarily involve moving through multiple normal forms.
I'm using entity framework 4.3 model first and can't figure out why I'm not allowed to have a one to zero-to-one association along with a referential constraint.
I have two main problems. I can't force referential integrity (without manual intervention) and my lazy loading doesn't seem to work... all my 1 to many associations are fine.
I basically have two tables, Loans and Contracts. The Contracts table has a scalar field for LoanId.
Until a loan is submitted, it does not have contract data and I chose not to place everything in the same table due to the size of the contract data. Ie. I don't want contract data retrieved from the database unless it is actually required.
I've searched around and can't seem to find any model first information that clearly answers my questions. Any information that may help me understand and clarify my problem would be greatly appreciated.
Regards
Craig
I guess LoanId field is not a primary key in Contracts table. In such case you cannot have such one-to-one relation because EF doesn't support it. When you create LoanId field in Contracts table the only way to force one-to-one relation is to add unique constraint on that field. EF currently doesn't support unique keys (except primary keys) so the only way to create one-to-one relation is to create relation between primary keys (Loan.Id <-> Contract.Id). If you don't follow this you will get error in designer.
In trying to normalize a database schema and mapping it in Entity Framework, I've found that there might end up being a bunch of lookup tables. They would end up only containing key and value pairs. I'd like to consolidate them into one table that basically has two columns "Key" and "Value". For example, I'd like to be able to get Addresses.AddressType and Person.Gender to both point to the same table, but ensure that the navigation properties only return the rows applicable to the appropriate entity.
EDIT: Oops. I just realized that I left this paragraph out:
It seems like a TPH type of problem, but all of the reading I've done indicates that you start with fields in the parent entity and migrate fields over to the inherited children. I don't have any fields to move here because there would generally only be two.
There are a lot of domain-specific key-value pairs need to be represented. Some of them will change from time to time, others will not. Rather than pick and choose I want to just make everything editable. Due to the number of these kinds of properties that are going to be used, I'd rather not have to maintain a list enums that require a recompile, or end up with lots of lookup tables. So, I thought that this might be a solution.
Is there a way to represent this kind of structure in EF4? Or, am I barking up the wrong tree?
EDIT: I guess another option would be to build the table structure I want at the database level and then write views on top of that and surface those as EF entities. It just means any maintenance needs to be done at multiple levels. Does that sound more, or less desireable than a pure EF solution?
Table per hiearchy demands that you have one parent entity which is used as base class for child entities. All entities are mapped to the same table and there is special discriminator column to differ type of entity stored in database record. You can generally use it even if your child entities do not define any new properties. You will also have to define primary key for your table otherwise it will be handled as readonly entity in EF. So your table can look like:
CREATE TABLE KeyValuePairs
(
Id INT NOT NULL IDENTITY(1,1),
Key VARCHAR(50) NOT NULL,
Value NVARCHAR(255) NOT NULL,
Discriminator VARCHAR(10) NOT NULL,
Timestamp Timestamp NOT NULL
)
You will define your top level KeyValuePair entity with properties Id, Key, Value and Timestamp (set as concurrency mode fixed). Discriminator column will be used for inheritance mapping.
Be aware that EF mapping is static. If you define AddressType and Gender entities you will be able to use them but you will not be able to dynamically define new type like PhoneType. This will always require modifying your EF model, recompiling and redeploying your application.
From OOP perspective it would be nicer to not model this as object hiearchy and instead use conditional mapping of multiple unrelated entities to the same table. Unfortunatelly even EF supports conditional mapping I have never been able to map two entities to the same table yet.
I have the following tables in the database (just a demo, of course):
Positions
PositionId
Limits
LimitId
PositionId
I want to left join them into a single entity (always have position, not always have a limit attached to it):
Position
PositionId
LimitId
I've seen articles regarding one-to-one mapping and "Table per type inheritence", and tried to implement the same method here, but with no sucess. Is that even possible?
I think what you want is an ordinary inner join where your foreign key (PositionID in the Limits table) is allowed to be null.
Yes and no...In my scenario, the 2nd option is the applicable one, since I don't have the same primary key in both tables. so, I must create an updateable view...The problem with updateable view is that I can't modify fields which are in different tables and expect the database to handle it, unless I use "Instead of" triggers, which I really don't want to get into at all...
So, I guess there's nothing out of the box for me...damn.
(Unless you have another idea...)
Anyways, I really thank you for your help, it's much appreciated.
Nir.