Null values in relational database - postgresql

I'm new in PostgreSQL(still learning)
I'm trying to create a relational database for a venue.
In my table(still in UNF) I have attribute to store the client's name, phone, email.
The problem is that the client will give maybe 2 or 1 info on him. So I will always have null values.
Sometimes I can get all the client's values(for the 3 attribute)
How am i supposed to deal with this in the normalization process?
Do I need to separate the tables in other relation. If so 3 relations is not too much?

For every attribute that should be there once, use a column in the main table. "Should" indicates it might be missing / unknown, too. That's a NULL value then. If the attribute must be there, define the column NOT NULL.
Attributes where there can be multiple distinct instances, especially if the maximum number is uncertain, create a separate table in a one-to-many relationship.
Store (non-trivial) attributes that can be used in many rows of the main table, in a separate table in a many-to-one relationship.
And attributes that can be linked multiple times on either side are best implemented in a many-to-many relationship.
Referential integrity is enforced with foreign key constraints.
It's not nearly as complex as reality, but the point is to establish a logically valid model that can keep up with reality.
Read basics about database normalization.
Detailed code example with explanation and links for n:m relationship:
How to implement a many-to-many relationship in PostgreSQL?

Related

Modeling many to many relations with postgreSQL

I work in cattle production and I am learning about database design with postgreSQL. Now I am working on an entity attribute relationship model for a database that allows to register the allocation of the pastures in which cattle graze. In the logic of this business an animal can be assigned to several grazing groups during its life. Each grazing group in turn has a duration and is composed of several pastures in which the animals graze according to a rotation calendar. In this way, at a specific time, animals graze in a pasture that is part of a grazing group.
I have a situation in which many grazing groups can be assigned to many animals as well as many pastures. Trying to model this problem I find a fan trap because there are two one-to-many relationships for a single table. According to this, I would like to ask you about how one can deal with this type of relationship in which one entity relates to two others in the form of many-to-many relationships.
I put a diagram on the problem.
model diagram
Thanks
Traditionally, using a link table (the ones you call assignment) between two tables has been the right way to do many-to-many relationships. Other choices include having an ARRAY of animal ids in grazing group, using JSONB fields etc. Those might prove to be problematic later, so I'd recommend going the old way.
If you want to keep track of history, you can add an active boolean field (to the link table probably) to indicate which assignment is current or have a start date and end date for each assignment. This also makes it possible to plan future assignments. To make things easier, make VIEWs showing only current assignment and further VIEWs to show JOINed tables.
Since there's no clear question in your post, I'd just say you are going the right way.

When to use an owned entity types vs just creating a foreign key or adding the columns directly to the table?

I was reading about owned entity types here https://learn.microsoft.com/en-us/ef/core/modeling/owned-entities#feedback and I was wondering when I would use that. Especially when using .ToTable(); although I am not sure if ToTable creates a relationship with keys.
I read the entire article so I understand that it essentially forces you to access the data via nav properties and prevents the owned table from being treated as an entity. They also say Include() is not needed and the data comes down with every query for the parent table so its not like you are reducing the amount of data that comes back.
So whats the point exactly? Also whats the point of "table splitting"?
It takes the place of Complex types with the option to set it up like a 1-1 relationship /w ToTable while automatically eager-loaded. This would use the same PK in both tables, same as 1-1.
The point Table-splitting would be that you want an object model that is normalized, where the table structure is not. This would fit scenarios where you have an existing table structure and want to split off related pieces of that data into sub-entities associated with the main entity. With the ToTable option, it would be similar to a 1-1 relationship, but automatically eager-loaded. However when considering the reasons to use a 1-1 relationship I would consider this option a bad choice.
The common reasons for using it in normal 1-1 relationships would include:
Splitting off expensive to load, rarely used data. (images, binary, memo)
Encapsulating data particular to a single application off of a common entity. i.e. if I have a "Customer" which is used by a billing system vs. a CRM I might have "CustomerBillingData" and "CustomerCRMData" owned by "Customer" rather than an inherited BillingCustomer / CRMCustomer. As there is a "single" customer that may serve one or both systems. Billing doesn't care about CRM data, CRM doesn't care about Billing. If all data is in "Customer" then both systems potentially need to be updated, and I cannot rely on constraints when the data is optional to the other system. By using composition I can enforce required data for a particular system.
In neither of these cases would I want to use table-splitting or anything that automatically eager-loads, so Owned Types /w ToTable would not replace 1-1 relationships by any stretch. It's essentially a more strict version of complex types, I'd say it's strictly used for entity organization. Not something I'd admit to wanting to use very often.

I don't need/want a key!

I have some views that I want to use EF 4.1 to query. These are specific optimized views that will not have keys to speak of; there will be no deletions, updates, just good ol'e select.
But EF wants a key set on the model. Is there a way to tell EF to move on, there's nothing to worry about?
More Details
The main purpose of this is to query against a set of views that have been optimized by size, query parameters and joins. The underlying tables have their PKs, FKs and so on. It's indexed, statiscized (that a word?) and optimized.
I'd like to have a class like (this is a much smaller and simpler version of what I have...):
public MyObject //this is a view
{
Name{get;set}
Age{get;set;}
TotalPimples{get;set;}
}
and a repository, built off of EF 4.1 CF where I can just
public List<MyObject> GetPimply(int numberOfPimples)
{
return db.MyObjects.Where(d=> d.TotalPimples > numberOfPimples).ToList();
}
I could expose a key, but whats the real purpose of dislaying a 2 or 3 column natural key? That will never be used?
Current Solution
Seeming as their will be no EF CF solution, I have added a complex key to the model and I am exposing it in the model. While this goes "with the grain" on what one expects a "well designed" db model to look like, in this case, IMHO, it added nothing but more logic to the model builder, more bytes over the wire, and extra properties on a class. These will never be used.
There is no way. EF demands unique identification of the record - entity key. That doesn't mean that you must expose any additional column. You can mark all your current properties (or any subset) as a key - that is exactly how EDMX does it when you add database view to the model - it goes through columns and marks all non-nullable and non-computed columns as primary key.
You must be aware of one problem - EF internally uses identity map and entity key is unique identification in this map (each entity key can be associated only with single entity instance). It means that if you are not able to choose unique identification of the record and you load multiple records with the same identification (your defined key) they will all be represented by a single entity instance. Not sure if this can cause you any issues if you don't plan to modify these records.
EF is looking for a unique way to identify records. I am not sure if you can force it to go counter to its nature of desiring something unique about objects.
But, this is an answer to the "show me how to solve my problem the way I want to solve it" question and not actually tackling your core business requirement.
If this is a "I don't want to show the user the key", then don't bind it when you bind the data to your form (web or windows). If this is a "I need to share these items, but don't want to give them the keys" issue, then map or surrogate the objects into an external domain model. Adds a bit of weight to the solution, but allows you to still do the heavy lifting with a drag and drop surface (EF).
The question is what is the business requirement that is pushing you to create a bunch of objects without a unique identifier (key).
One way to do this would be not to use views at all.
Just add the tables to your EF model and let EF create the SQL that you are currently writing by hand.

Entity Framework Inheritance

Have a scenario with a client's new crm where they have suppliers and clients and a supplier is also a client and vice versa. Table per hierarchy will only allow a person to only be one or the other, so I assume table per type would be better suited.
The db structure would be:
[Contact]
ContactId pk
Name
...
[Client]
ContactId pk / fk
VATNumber
...
[Supplier]
ContactId pk / fk
...
Anyone have any other suggestions or experience from a similar scenario?
Table per type will also assume one Contact is either a client or a supplier (this is clearer if you look at the generated SQL: eg. see "Inheritance with EF Code First CTP5: Part 2 – Table per Type (TPT)").
Instead I think you need to change your model to be Contact and Contact-Role with a one to many relationship. Contact-Role would have the Supplier and Client subtypes. The whole Contact-Role hierarchy could then be mapped as TPH or TPT.
This reflects an OO design where each client has one or more roles (inheritance, "is-a" releationship, will always be singular, you cannot have an object of abstract type client that is simultaneously both subtypes of client).
This cannot work unless you model it as three level inheritance which would require that either client is always supplier or supplier is always client. I guess that is not correct model in your application which means you cannot use inheritance.
You have to either use one-to-one (0..1-1) relations between contact-client and contact-supplier or you can simply place all properties to single table and add IsClient and IsSupplier bit columns - it is not very nice and it is less extensible but it is very easy to use. These two bit columns can be useful in case of relational representation as well.

One Entity for multiple similar tables

have two tables in database.
They have completely the same columns, only the difference between them - they have different names.
Lets say i have TableSea with column s Id and Name and TableOcean with the same columns Id and Name.
I want to use EF 4 to be able CRUD operations, i am also want to use stored procs mapping for insert update and delete operations.
I am already created POCO entity for first table and i did create stored procedures and map them to entity model. All working well.
How make it work with two tables without create a new entity for second table?
AFAIK, you can't, and you definitely shouldn't!
If you have two identical database tables, then this means one of the following:
The two tables mirror closely
related concepts (like Sea and Ocean
in your example).
The two tables
mirror different concepts which only
accidentally have the same
properties.
Depending on which scenario is closer to reality, you have these two design options:
Merge the two tables and add a
Type property (column), then map
it to one entity type. You might
have different subclasses to
differentiate between types, or you
may go with an additional Type
property - whichever fits better for
you.
Have two tables. Which means: there are two different concepts. Consequently, this has to be mirrored by two different entities in the business model.
In any case, having an entity table in the database means having an entity class in the business model. If there's no such 1:1 - mapping, then clearly something is wrong with the design!
Thomas