I am struggling to wrap my head around this concept. Here is a pic of my ERD
Look at the tables 'Titles' and 'Employees'. Emp_title_id is a foreign key reference to title_id in Title. Now, there are same titles for multiple employees. So shouldn't that be a many-to-one relationship?
The argument against is that the two fields (emp_title_id in Employees and title_id in Title) have same set of values, so it is a one-to-one relationship.
Please let me know if I should think of it as set of values (one to one) or set of "cells" with different values (many to one)
Thanks
One-to-many (1:n)
An employee can have only 1 title.
A title can be given to n employees.
(You have a 1:n relationship between employee and title, as an employee can have only one title. But you have established an m:n relationship between employee and department, as an employee can work in multiple departments. In the datamodel this can be seen from the existence of the bridge table dept_emp needed to provide m:n.)
Related
I'm new to database design and I am working on a project that requires the use of a single entity (medication) that could be tied to any number of patients and each patient could have a different dosage. What would be the best way to layout a table for this type of situation. I could use a single table and just store each individual medication and dosage and tie that to the unique patient. But that would give me duplicate entries in the medication table (same med with just different dosage).
What I would like is to have a single entry for each medication name and have each patient have a unique dosage for that particular med. Of course a single patient could also have many different medications so I would have to be able to have a unique dosage for each med for different patients.
I using entity framework model first approach. Would I use a single table T_Patient_Medication and use each of the two table IDs as the primary key combo and then use a dosage field for that combination? If so how would I create the association to tie this table to the other two. Any suggestions?
Off the top of my head:
-a medication table(MedicineId, MedicineName, etc).
-a patient table(PatientId, PatientName, etc)
-a patient-medicine table(MedicineId, PatientId, Dosage, date, notes etc).
In other words, the medication table contains on row per unique med, a patient contains one row for each unique patient.
The patient-medicine table is where these two things meet: it contains a patientId, a medicineId and then anything else unique about that patient getting that medicine (i.e. Dr. name, dosage, date started etc). Personally I would make each row in the patient-medicine table also have its own unqiue ID separate from the combination of the patientid and medicine id (what are you going to do when the same patient goes back on the same medicine at a different time, if your primary key is Patientid+Medicineid). Each record should have its own unique id in my way of thinking.
There would be foreign keys between the tables to enforce this relationship: i.e. you can't add a row to the patient-medicine table unless the patientid exists in the patient table, and the medicine exists in the medicine table; and equally important prevent you from deleting a rows from tables where there are dependent records in other tables. If you take the time and setup all those foreign keys (relationships), it will be a breeze in EF to navigate the related records.
It is without a doubt more complicated than this, but that is the basics idea of a relational table.
I'm having a little trouble grasping CoreData relationships, i'm note sure which relationship type I should be using between my 2 entities or if my logic is correct.
1) "Person" Entity - attributes such as name, tel, address, country, etc...
2) "CountryList" - attributes such as countryName, countryLat, countryLong, etc..
The CountryList entity is pre populated on first run of the app to include all the countries in the world and their respected data.
Where i'm stuck is do I need a relationship between these two entities?
I will be allowing the user to select a country from the CountryList entity data and wish to store there selection in the country attribute for Person entity.
Do I just take the countryName from CountryList as a string and store it in country from Person? or can I make a relationship between them?
I know a user can only belong to 1 country but a country can have lots of users so is this a one to many relationship? Or is it many to many because lots of users can belong to a country but a country can have loads of users? Confused!
Could someone please enlighten me on this and point me in the right direction in what i should be doing in xcode.
Many Thanks in Advance
Matt
EDIT: Is this correct?
I have made the changes to Entity names etc and think I now have the relationship set correctly.
EDIT 2: Removed country attribute and renamed relationships
Firstly, your "CountryList" entity should be called "Country", since it represents only one country. The fact that you have many of those countries has nothing to do with its name.
After that, it seems just natural to use a relationship, one "Person" has one "Country", but one country can have many persons. Therefore, one-to-many relationship. Using a relationship will simplify many operations you might want to perform (i.e. access all the country information of one person, or get a list of all persons being in one particular country).
Oh, and this might help you understand relationships a bit better: There are no "many-to-many" relationships in CoreData per se. You always define a relation from a source to a target. So if you define a relation from Country to Person, this will be a one-to-many relationship. One country, many persons. You can then define a relationship from Person to Country, which would be a one-to-one relationship. One person, one country. If you defined this as an one-to-many relationship, you would end up with a de facto many-to-many relationship (because on person can have many countries and one country can have many persons). It's not as complex as it appears.
Now, after you've defined your two relationships, you can set them as each others "Inverse Relationship". Do it for one of the relationships, the other one will be set automatically. After you did that, CoreData will for example update a Person's country when you add the person to the country's list.
See https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdRelationships.html for further information.
CountryList should just be Country
Then you set a 'many to one' relationship between Person.county and Country
You are using Core Data so you must define relationship between Person and Country if you want to fetch person's country from database.
And in this relationship you may take one to one relationship. As One person will belong to one country only. Of Course a country will have many person but unless you want to show all people related to particular country you do not need one to many relationship..
In case you want to implement one to many relationship this tutorial link maybe helpful to you for understanding one to many relationship..
http://www.theappcodeblog.com/2011/09/29/iphone-app-development-tutorial-core-data-part-2-one-to-many-relationship/
I have my app using core data with the data model below. However, I'm switching to a standard database with columns and rows. Can anyone help me with setting up this new database schema?
First of all you need to create tables for each of the Entities and their attributes (note I added "id" to each of the tables for relationships):
Routine (name, timestamp, id)
Exercise - this looks like a duplicate to me, so leaving one only here (muscleGroup, musclePicture, name, timeStamp, id)
Session (timeStamp, id)
Set (reps, timeStamp, unit, weight, id)
Now that you have tables that describe each of the entities, you need to create tables that will describe the relationships between these entities - as before table names are in capitals and their fields are in parenthesis:
RoutineExercises (routine_id, exercise_id)
SessionExercises (session_id, exercise_id)
ExerciseSets (exercise_id, set_id)
That's it! Now if you need to add an exercise to a routine, you simply:
Add an entry into Exercise table
Establish the relationship by adding a tuple into RoutineExercises table where routine_id is your routine ID and exercise_id is the ID of the newly created entry in the Exercise table
This will hold true for all the rest of the relationships.
NOTE: Your core data model has one-to-many and many-to-many relationships. If you want to specifically enforce that a relationship is one-to-many (e.g. Exercise can only have 1 routine), then you will need to make "exercise_id" as the index for the RoutineExercises table. If you want a many-to-many relationships to be allowed (i.e. each exercise is allowed to have multiple routines), then set the tuple of (routine_id, exercise_id) as the index.
Let's say I have a Database with 3 tables: Keywords, Documents, and KeywordDocuments. KeywordDocuments has only 3 columns, KeywordDocumentID, KeywordID, and DocumentID.
The relationship between Documents and KeywordDocuments is the same as Keywords and KeywordDocuments, i.e. one-to-many.
Watching Julie Lerman's video on EF, she said that we don't need KeywordDocuments's entity in the model. How do I eliminate that entity while making sure that in the relationship will be respected in the underline database?
Thanks for helping
Remove the KeywordDocumentID column from the KeywordDocument table. It will then contain only the foreign key columns from the tables for which it represents a many to many relationship.
Create a new composite primary key on the KeywordDocument table which includes both the KeywordID and the DocumentID columns. This will replace the original primary key that you had on the KeywordDocumentID column - that key would have been deleted along with the column.
A table such as this will not result in an entity being generated in the model. Rather, both of the other entities (Keyword and Document in this case) will have navigation properties based on EntityCollection. Document will have a collection of Keywords and vice verca.
Please help an EF n00b design his database.
I have several companies that produce several products, so there's a many-to-many relationship between companies and products. I have an intermediate table, Company_Product, that relates them.
Each company/product combination has a unique SKU. For example Acme widgets have SKU 123, but Omega widgets have SKU 456. I added the SKU as a field in the Company_Product intermediate table.
EF generated a model with a 1:* relationship between the company and Company_Product tables, and a 1:* relationship between the product and Company_Product tables. I really want a : relationship between company and product. But, most importantly, there's no way to access the SKU directly from the model.
Do I need to put the SKU in its own table and write a join, or is there a better way?
I just tested this in a new VS2010 project (EFv4) to be sure, and here's what I found:
When your associative table in the middle (Company_Product) has ONLY the 2 foreign keys to the other tables (CompanyID and ProductID), then adding all 3 tables to the designer ends up modeling the many to many relationship. It doesn't even generate a class for the Company_Product table. Each Company has a Products collection, and each Product has a Companies collection.
However, if your associative table (Company_Product) has other fields (such as SKU, it's own Primary Key, or other descriptive fields like dates, descriptions, etc), then the EF modeler will create a separate class, and it does what you've already seen.
Having the class in the middle with 1:* relationships out to Company and Product is not a bad thing, and you can still get the data you want with some easy queries.
// Get all products for Company with ID = 1
var q =
from compProd in context.Company_Product
where compProd.CompanyID == 1
select compProd.Product;
True, it's not as easy to just navigate the relationships of the model, when you already have your entity objects loaded, for instance, but that's what a data layer is for. Encapsulate the queries that get the data you want. If you really want to get rid of that middle Company_Product class, and have the many-to-many directly represented in the class model, then you'll have to strip down the Company_Product table to contain only the 2 foreign keys, and get rid of the SKU.
Actually, I shouldn't say you HAVE to do that...you might be able to do some edits in the designer and set it up this way anyway. I'll give it a try and report back.
UPDATE
Keeping the SKU in the Company_Product table (meaning my EF model had 3 classes, not 2; it created the Company_Payload class, with a 1:* to the other 2 tables), I tried to add an association directly between Company and Product. The steps I followed were:
Right click on the Company class in the designer
Add > Association
Set "End" on the left to be Company (it should be already)
Set "End" on the right to Product
Change both multiplicities to "* (Many)"
The navigation properties should be named "Products" and "Companies"
Hit OK.
Right Click on the association in the model > click "Table Mapping"
Under "Add a table or view" select "Company_Product"
Map Company -> ID (on left) to CompanyID (on right)
Map Product -> ID (on left) to ProductID (on right)
But, it doesn't work. It gives this error:
Error 3025: Problem in mapping fragments starting at line 175:Must specify mapping for all key properties (Company_Product.SKU) of table Company_Product.
So that particular association is invalid, because it uses Company_Product as the table, but doesn't map the SKU field to anything.
Also, while I was researching this, I came across this "Best Practice" tidbit from the book Entity Framework 4.0 Recipies (note that for an association table with extra fields, besides to 2 FKs, they refer to the extra fields as the "payload". In your case, SKU is the payload in Company_Product).
Best Practice
Unfortunately, a project
that starts out with several,
payload-free, many-to-many
relationships often ends up with
several, payload-rich, many-to-many
relationships. Refactoring a model,
especially late in the development
cycle, to accommodate payloads in the
many-to-many relationships can be
tedious. Not only are additional
entities introduced, but the queries
and navigation patterns through the
relationships change as well. Some
developers argue that every
many-to-many relationship should start
off with some payload, typically a
synthetic key, so the inevitable
addition of more payload has
significantly less impact on the
project.
So here's the best practice.
If you have a payload-free,
many-to-many relationship and you
think there is some chance that it may
change over time to include a payload,
start with an extra identity column in
the link table. When you import the
tables into your model, you will get
two one-to-many relationships, which
means the code you write and the model
you have will be ready for any number
of additional payload columns that
come along as the project matures. The
cost of an additional integer identity
column is usually a pretty small price
to pay to keep the model more
flexible.
(From Chapter 2. Entity Data Modeling Fundamentals, 2.4. Modeling a Many-to-Many Relationship with a Payload)
Sounds like good advice. Especially since you already have a payload (SKU).
I would just like to add the following to Samuel's answer:
If you want to directly query from one side of a many-to-many relationship (with payload) to the other, you can use the following code (using the same example):
Company c = context.Companies.First();
IQueryable<Product> products = c.Company_Products.Select(cp => cp.Product);
The products variable would then be all Product records associated with the Company c record. If you would like to include the SKU for each of the products, you could use an anonymous class like so:
var productsWithSKU = c.Company_Products.Select(cp => new {
ProductID = cp.Product.ID,
Name = cp.Product.Name,
Price = cp.Product.Price,
SKU = cp.SKU
});
foreach (var
You can encapsulate the first query in a read-only property for simplicity like so:
public partial class Company
{
public property IQueryable<Product> Products
{
get { return Company_Products.Select(cp => cp.Product); }
}
}
You can't do that with the query that includes the SKU because you can't return anonymous types. You would have to have a definite class, which would typically be done by either adding a non-mapped property to the Product class or creating another class that inherits from Product that would add an SKU property. If you use an inherited class though, you will not be able to make changes to it and have it managed by EF - it would only be useful for display purposes.
Cheers. :)