Normalizing issue with data history - entity-relationship

I have two entities: Location and Employee. Each employee works in a single location at a time. For any given moment in time, the model is as follows:
There is, however, a requirement to also store historical information for all locations and employees for every end-of-month. I can achieve this by adding a Month PK attribute in both entities, but: how do I handle the relationship in that case?
A foreign key has to reference a composite PK in its entirety. Several alternatives come to mind:
Option 1: repeat the Month attribute in the Employee entity to get the full PK as FK attributes. This feels a bit redundant? If an employee has existed in a given month, surely she has to work in a location in the same month - i.e. the two Month attributes have to always have the exact same value:
Option 2: re-use the Month attribute in the PK of the Employee entity as a foreign key referencing Location. I don't even know if this is allowed (note: I'm going to be using SQL Server eventually, if it matters here)?
Option 3: create a separate bridge entity that holds the history of Location-Employee relationships. This feels kind of neat, but then again I have some doubts as to whether or not I can use one Month attribute here or if I need two of them. Also, it would allow many-to-many relationships (an employee in several locations on a given month), which is not supposed to happen in this case and I'd like to be able to enforce this in the data model.
Am I missing something obvious here? What is the "correct" and properly normalized solution? Or should I just leave the FK constraints out?

Related

Database design for reservation of computers in laboratories

I want to create an application for enabling the users to book the computers in a laboratory if they want to use it from a specific time to time.The users can book the computers for their next 15 days. So,how should I design the database for this application.
Start by defining what your entities and attibutes will be. It's better if you can do a Conceptual Design first.
Than you design it logically.
For example, your entities might be:
USERS, COMPUTERS, RESERVATIONS.
Your attributes might be:
USERS (SomeUniquePersonalIDnumber, Name, Surname, Email*, PhoneNumber*)
PrimaryKey in bold. With asterisk *Optional
COMPUTERS (UniqueComputerSerialNumber, NumberOfComputerInLab)
RESERVATIONS (AutoincrementNumber, UserPK, ComputerPK, DateOfReservation, TimeFrom, TimeTill)
PrimaryKey composed of the three attibutes making it unique. Same user might reserve the same computer over time but the AutoincrementNumber field will make the composite PK unique.
RESERVATIONS(UserPK) referencing USER(SomeUniquePersonalIDnumber)
RESERVATIONS(ComputerPK) referencing COMPUTERS(UniqueComputerSerialNumber)
Define what type of fields will those attributes be
(Integer/Varchar/...) based on the querying language you will want
to use.
Translate all of above into commands to create the database, the
tables etc.
Just pick a piece of paper and start with normalization https://en.wikipedia.org/wiki/Database_normalization.
If I look for entities in your question I see the following entities:
user
computer
booking
Then you need to figure out what properties belong to those entities and the relation between them. You can create an ERD if you like and start creating Ruby on Rails models.
In Ruby on Rails if you generate a model the model has a created_at datetime field by default. I think you can use that to figure out the specific time and check if 15 days are past since this booking is created.

Core Data Relationship For Unidirectional One to Many

What is the best practice for creating Unidirectional One to Many Relationships in Core Data?
For example...
Lets take two classic entity examples, "teacher" and "student".
Each student has one teacher, and each teacher has many students.
In CoreData right now you are forced to provide an inverse such that teacher is forced to have a reference to a 'student'. If you don't you get this nice warning that says something along the lines of...
file:///Users/josephastrahan/Documents/VisualStudioProjects/Swift3WorkOrders/WorkOrders/WorkOrders/WorkOrders.xcdatamodeld/WorkOrders.xcdatamodel/: warning: Misconfigured Property: Teacher.student should have an inverse
What if I don't want teacher to have a reference to student?
Some other posts have brought up that I should just allow the inverse anyways but I think this inverse may be causing an issue with one of my projects.
That said let me explain my exact issue.
Lets say that our teacher has a unique attribute int64 called 'id'. Lets say the students also have unique attribute int64 called 'id'.
The int64 is enforced to be unique by adding a constraint on the model for teacher on id. (refer to image below to see how that is done)
Every year there is new students but the teachers stay the same. So I decided that I want to delete all the students without deleting the reference to the teacher. So I set the delete rule to 'nullify' for the relationship for the teacher to student and 'nullify' for the student to teacher.
Now when I create a new student I want to assign one of the existing teachers to that student... (something like student.teacher = teacher object with id of 1 or the same id as before) however!! , because the teacher has the inverse relationship to a student that no longer exists (which in theory should be null) the program crashes!
I know this is the case as I've used print console logs to narrow it down the exact point that it occurs. Also I know this because if I add the delete rule of cascade for student the crash will go away but...then I lose my teacher! which I don't want...
Some things that I think might be the issue:
1.) When I do my testing I do it at the startup of the program which creates a new context everytime. Could it be that because I never deleted teacher it still thinks it refers to a student from a context that no longer exists? (if I'm even saying this right...)
I'm not sure the best solution to acheive what I'm trying to do with Coredata and any advice is much appreciated!
Note:
Forgot to mention I also have the Merge Policy of: NSMergeByPropertyObjectTrumpMergePolicy, which will overwrite the old data with the new. When I'm creating new students I'm creating new teachers also just using the same id which should follow this policy.
You are almost there.
The advice to keep the inverse relationship is a good one. Keep it.
Your issue is likely caused by different contexts. Instead of holding on to a teacher object in memory, you should fetch the teacher (based on the id) in the context in which you intend to use it.
Your nullified students should not have any impact. A to-many relationship is really a Set<Student>. Make sure the set is empty.
NB:
If you want to keep the student in the database (for historical purposes) - it seems from your description that this is the case - you might also consider another scheme: give your students another attribute (such as a year) and use that to filter the student list. You would not have to delete or nullify anything. You could also do some more interesting time-based queries on the data.
Unique Constraints are available with iOS9. Which have helped iOS Developers with adding and updating records in CoreData.
Unique Constraints make sure that records in an Entity are unique by the given fields. But unique constraints along with To-Many relationship leads to a lot of weird issues while resolving conflicts.
e.g. “Dangling reference to an invalid object.”
This post is basically focused to a small problem that may take days to fix.
http://muhammadzahidimran.com/2016/12/08/coredata-unique-constraints-and-to-many-relationship/

SQL Relationships

I'm using MS SQL Server 2008R2, but I believe this is database agnostic.
I'm redesigning some of my sql structure, and I'm looking for the best way to set up 1 to many relationships.
I have 3 tables, Companies, Suppliers and Utilities, any of these can have a 1 to many relationship with another table called VanInfo.
A van info record can either belong to a company, supplier or utility.
I originally had a company_id in the VanInfo table that pointed to the company table, but then when I added suppliers, they needed vaninfo records as well, so I added another column in VanInfo for supplier_id, and set a constraint that either supplier_id or company_id was set and the other was null.
Now I've added Utilities, and now they need access to the VanInfo table, and I'm realizing that this is not the optimum structure.
What would be the proper way of setting up these relationships? Or should I just continue adding foreign keys to the VanInfo table? or set up some sort of cross reference table.
The application isn't technically live yet, but I want to make sure that this is set up using the best possible practices.
UPDATE:
Thank you for all the quick responses.
I've read all the suggestions, checked out all the links. My main criteria is something that would be easy to modify and maintain as clients requirements always tend to change without a lot of notice. After studying, research and planning, I'm thinking it is best to go with a cross reference table of sorts named Organizations, and 1 to 1 relationships between Companies/Utilities/Suppliers and the Organizations table, allowing a clean relationship to the Vaninfo table. This is going to be easy to maintain and still properly model my business objects.
With your example I would always go for 'some sort of cross reference table' - adding columns to the VanInfo table smells.
Ultimately you'll have more joins in your SP's but I think the overhead is worth it.
When you design a database you should not think about where the primary/foreign key goes because those are concepts that doesn’t belong to the design stage. I know it sound weird but you should not think about tables as well ! (you could implement your E/R model using XML/Files/Whatever
Sticking to E/R relationship design you should just indentify your entity (in your case Company/supplier/utilities/vanInfo) and then think about what kind of relationship there is between them(if there are any). For example you said the company can have one or more VanInfo but the Van Info can belong only to one Company. We are talking about a one – to- many relationship as you have already guessed. At this point when you “convert” you design model (a one-to many relationship) to a Database table you will know where to put the keys/ foreign keys. In the case of a one-to-Many relationship the foreign key should go to the “Many” side. In this case the van info will have a foreign keys to company (so the vaninfo table will contain the company id) . You have to follow this way for all the others tables
Have a look at the link below:
https://homepages.westminster.org.uk/it_new/BTEC%20Development/Advanced/Advanced%20Data%20Handling/ERdiagrams/build.htm
Consider making Com, Sup and Util PKs a GUID, this should be enough to solve the problem. However this sutiation may be a good indicator of poor database design, but to propose a different solution one should know more broad database context, i.e. that you are trying to achive. To me this seems like a VanInfo should be just a separate entity for each of the tables (yes, exact duplicate like Com_VanInfo, Sup_VanInfo etc), unless VanInfo isn't shared between this entities (then relationships should be inverted, i.e. Com, Sup and Util should contain FK for VanInfo).
Your database basically need normalization and I think you're database should be on its fifth normal form where you have two tables linked by one table. Please see this article, this will help you:
http://en.wikipedia.org/wiki/Fifth_normal_form
You may also want to see this, database normalization:
http://en.wikipedia.org/wiki/Database_normalization

EF4: Creating a 0..1 to Many Association

I am trying to add an association that I didn't have originally. I realized that two tables were technically related, and that some navigation properties might simplify what I would have otherwise had to do manually. The tables and their keys look like this:
Import
Primary Key:
Number : Int32
Date : DateTime
Hour
Primary Key:
DepartmentID : Int32
UserNumber : Int32
Date : DateTime
The association is named ImportHour. Import.Number maps to Hour.UserNumber, and Import.Date maps to Hour.Date. I am trying to add an association that is 0..1 on Import, and * on Hour with navigation properties and no additional foreign keys. When I do this, the designer tells me that the association is not mapped. If I then generate the DDL, it creates new fields Hours.Import_Date and Hours.Import_Number (Hours is the actual database table name for the Hour entity). If I manually map the fields, I end up with the following error:
Error 3021: Problem in mapping fragments starting at line 332:
Each of the following columns in table Hours is mapped to multiple conceptual side properties:
Hours.Date is mapped to <ImportHour.Hour.Date, ImportHour.Import.Date>
Hours.UserNumber is mapped to <ImportHour.Hour.UserNumber, ImportHour.Import.Number>*
I am not really sure what is happening, and I don't think I understand the 'mapping' process well enough to figure this out. It almost seems as if it wants a quintuple key, instead of realizing that the one key maps to the other. I look at my other one-to-many associations, and they do not even have table mappings; I think they have referential constraints instead, but you obviously can't have a referential constraint with a 0..1 to many association.
There are two ways to define relation but in your case you must use the Foreign key association. It means that once you draw association in entity model you must select it and define referential constraints.
You cannot have 0..1 on Import because in such case UserNumber and Date in Hour must be nullable. That is what that relation mean. If no principal entity exists (Import) FK properties in dependent entity (Hour) will be null.
Btw. using DateTime in primary key is not recommended.
As far as I can tell from other databases I have since used, the issue here seems to be that the EF model requires a foreign key to already exist in the database. While I cannot seem to get EF to generate one, it will accept one if it already exists. (Contrary to what I said in the question, you can have a referential constraint on a 0..1 to many (nullable) foreign key).
#Sahuagin this may be long after your question but did you try after adding the association, deleting the scalar property in the designer -- example after creating the ImportHour association, delete the hour.usernumber and hour.date from your hour entity.
this way the independent association established this way is the only relationship between yuor entities - thats the meaning of independent association

Domain Driven Design: When to make an Aggregate Root?

I'm attempting to implement DDD for the first time with a ASP.NET MVC project and I'm struggling with a few things.
I have 2 related entities, a Company and a Supplier. My initial thought was that Company was an aggregate root and that Supplier was a value object for Company. So I have a Repository for company and none for Supplier.
But as I have started to build out my app, I ended up needing separate list, create, and update forms for the Supplier. The list was easy I could call Company.Suppliers, and create was horrible I could do Company.Suppliers.Add(supplier), but update is giving me a headache. Since I need just one entity and I can't exactly stick it in memory between forms, I ended up needing to refetch the company and all of the suppliers and find the one I needed to bind to it and again to modified it and persist it back to the db.
I really just needed to do a GetOne if I had a repository for Supplier. I could add some work arounds by adding a GetOneSupplier to my Company or CompanyRepository, but that seems junky.
So, I'm really wondering if it's actually a Value Object, and not a full domain entity itself.
tldr;
Is needing separate list/create/update view/pages a sign that an entity should be it's own root?
Based on your terminology I assume you are performing DDD based on Eric Evans' book. It sounds like you have already identified a problem with your initial go at modeling and you are right on.
You mention you thought of supplier as a Value Object... I suggest it is not. A Value Object is something primarily identified by its properties. For example, the date "September 30th, 2009" is a value object. Why? Because all date instances with a different month/day/year combo are different dates. All date instances with the same month/day/year combo are considered identical. We would never argue over swapping my "September 30th, 2009" for yours because they are the same :-)
An Entity on the other hand is primarily identified by its "ID". For example, bank accounts have IDs - they all have account numbers. If there are two accounts at a bank, each with $500, if their account numbers are different, so are they. Their properties (in this example, their balance) do not identify them or imply equality. I bet we would argue over swapping bank accounts even if their balances were the same :-)
So, in your example, I would consider a supplier an Entity, as I would presume each supplier is primarily identified by its ID rather than its properties. My own company shares its name with two others in the world - yet we are not all interchangeable.
I think your suggestion that if you need views for CRUDing an object then it is an Entity probably holds true as a rule of thumb, but you should focus more on what makes one object different from others: properties or ID.
Now as far as Aggregate Roots go, you want to focus on the lifecycle and access control of the objects. Consider that I have a blog with many posts each with many comments - where is/are the Aggregate Root(s)? Let's start with comments. Does it make sense to have a comment without a post? Would you create a comment, then go find a post and attach it to it? If you delete a post, would you keep its comments around? I suggest a post is an Aggregate Root with one "leaf" - comments. Now consider the blog itself - its relationship with its posts is similar to that between posts and comments. It too in my opinion is an Aggregate Root with one "leaf" - posts.
So in your example, is there a strong relationship between company and supplier whereby if you delete a company (I know... you probably only have one instance of company) you would also delete its suppliers? If you delete "Starbucks" (a coffee company in the US) do all its coffee bean suppliers cease to exist? This all depends on your domain and application, but I suggest more than likely neither of your Entities are Aggregate Roots, or perhaps a better way to think about them is that they are Aggregate Roots each with no "leaves" (nothing to aggregate). In other words, company does not control access to or control the lifecycle of suppliers. It simply has a one-to-many relationship with suppliers (or perhaps many-to-many).
This brings us to Repositories. A Repository is for storing and retrieving Aggregate Roots. You have two (technically they are not aggregating anything but its easier than saying "repositories store aggregate roots or entities that are not leaves in an aggregate"), therefore you need two Repositories. One for company and one for suppliers.
I hope this helps. Perhaps Eric Evans lurks around here and will tell me where I deviated from his paradigm.
Sounds like a no-brainer to me - Supplier should have its own repository. If there is any logical possibility that an entity could exist independently in the model then it should be a root entity, otherwise you'll just end up refactoring later on anyway, which is redundant work.
Root entities are always more flexible than value objects, despite the extra implementation work up front. I find that value objects in a model become rarer over time as the model evolves, and entities that remain value objects were usually the ones that you could logically constrain that way from day one.
If companies share suppliers then having supplier as a root entity removes data redundancy as well, as you do not duplicate the supplier definition per company but share the reference instead, and the association between Company and Supplier can be bi-directional as well, which may yield more benefits.

Resources