I have a Jekyll project that contains products (in a collection). Each product has a company, which is a reference to an entity in the companies collection. Each company then has its own properties (for the sake of the example, let's say it has a country property).
How can I list products and group them by the company's country? Can I "project" the company's properties on the collection I'm actually working with (in this case, the products collection)? Or am I limited to properties of the collection being enumerated?
Related
Is this a circular reference? If so, how can I improve my model?
You don't have any circular references. I interpret the data model to say:
An Item belongs to exactly 1 Client
An Item belongs to 0 or 1 Employee
An Employee belongs to exactly 1 Client
A circular reference would add An Employees to exactly 1 Item.
In the comments, you said than an item always belongs to the same client as it's employee, but not all items belong to an employee.
There are a few ways to model this.
What I would avoid is having ClientID as a not-null foreign key relationship on Item - this duplicates the logic that "an item without an explicit client ID inherits the client ID from its employee". It's not expressive (people reading the schema would not be able to figure that out), and opens up bugs.
One option is to make the cardinality of both item->employee and item-> client optional (i.e. 0..1). Your convention would then be if an item has a client relationship, it may not have an employee relationship, and if an item has an employee relationship, it may not have an explicit client relationship; the client is determined by the employee. You can't cleanly express this in your schema, and would have to build this into your data access code.
Another option is to create two type of item, one with a clientID foreign relationship, and one with an employeeId foreign relationship. This is much more expressive from a schema point of view - presumably there is some business concept you can use to name the tables. However, if Item has lots of attributes, you're duplicating a lot.
Finally, you could store the relationship of items to either client or employee in separate joining table:
Item
-------
ItemID
...
ItemEmployees
-----------------
ItemID
EmployeeID
ItemClients
----------
ItemID
ClientID
This avoids the duplication of attributes on Item, but is less expressive because it uses a pattern more commonly used for many-to-many relationships, and doesn't explicitly declare "either or".
I am looking for some feedback/guidance on modeling a hierarchy structure within a relational database. My requirement states that I need to have a tree structure, where every node within the tree can represent a different type of data. For example:
Organization
Department 1
Employee 1
Employee 2
Office Equipment 1
Office Equipment 2
Department 1
Team 1
Office Equipment 3
In the example above, Organization, Department, Employee, Office Equipment, and Team could all be different tables within the database and have different properties associated with them. Additionally, things like Office Equipment may not necessarily be required to be associated to a department - it could be associated to a Team or the Organization.
I have two ideas surrounding modeling this:
The first idea is to have a hierarchy table like below:
hierarchys
hierarchy_id (INT, NOT NULL)
parent_hierarchy_id (INT, NOT NULL)
organization_id (INT, NULL)
department_id (INT, NULL)
team_id (INT, NULL)
office_equipment (INT, NULL)
In the table above, each of the columns would be a nullable field with a foreign key reference to their respectable table. The idea would be that only one column from every row would be populated.
My second idea is to have a single table like below:
hierarchys
hierarchy_id (INT, NOT NULL)
parent_hierarchy_id (INT, NOT NULL)
type (INT, NOT NULL)
In this case, the table above would manage the hierarchy structure, and each "node table" would have a hierarchy_id which would have a foreign key reference back to the hierarchy table (i.e. organizations would have a hierachy_id column). The type column would be a lookup to represent which type node is being represented (i.e. Organization, Employee, etc).
I see pros and cons in both approaches.
Some additional information:
I would like to keep in mind maintainability of this table - there will be additions, deletions, changes, etc.
I will have to display this data on an user interface, which will likely just display an icon to represent the node type, and the name.
I will have to preform some aggregations across the tree for different data requests.
This structure will be backed by a MySQL database.
Does anyone have an experience with a similar scenario? I have searched quite a bit for information and guidance on this approach, but have not been able to find any information. I have a feeling there is a specific term for what I am looking for that I am failing to use.
Thank you in advance for the community's help.
You may want to look into "nested sets". This is a model for representing subsets of an ordered set by two limits, which we can call "left" and "right". In this model, (6,7) is a subset of (5,10) because it is "nested" inside of it. If you use nested sets together with your design of having a separate table for the hierarchy, you'll end up with four columns in your hierarchy table: leftID, rightID, ObjectID (an FK), and level.
There is a good description of the nested set model in Wikipedia, which you can view by clicking here.
I have encountered similar situations throughout different projects, and the approach I've taken in those cases was very similar to your second solution.
I am also a bit biased towards how some Ruby on Rails gems do things, but you can easily figure out how you would implement these techniques with plain SQL and some application logic. So I'm giving you one alternative to your solution:
Using "Multi Table Inheritance" (Implemented in Heritage: https://github.com/dipth/Heritage). In this scenario you would have a Node table which forms the basis of your hierarchy with:
Node (id, parent_node_id, heir_type, heir_id)
Where the heir_type is the name of the table holding the details for the node (e.g., Organization, Employee, team, etc.), and the heir_id is the id of the object in that table.
Then each type of node would have it's own table and it's own unique id. e.g.:
Organization(id, name, address)
Having the rest of the tables independently from the hierarchy (i.e., strong entities) makes your model more flexible to new additions. Also having a separate table with its own unique id to handle the hierarchy makes it easier to render the hierarchy without having to deal with parent types etc. This model is also more flexible in the sense that one entity can be part of many different branches of the hierarchy (e.g., Employee 1 could be a member of Team 1 and Team 2 at the same time.)
Your solution has one mistake: The hierarchys is miss-spelled :P JK. The hierarchys table has no unique id. It looks like the unique id is a composite key (hierarchy_id, type). The parent_hierarchy_id does not capture the type of the parent and thus it may point to multiple nodes and many inconsistencies.
If you'd like me to elaborate more, let me know.
Right now I have US products in my database only. They reside within a table named products. These products are searchable through assigned tags which are in a separate table.
My challenge is to now add products from a different country with the requirement that wherever the user is from he will only see products from his country.
The country can either be selected by these infamous country-flag-picker dropdowns, set in the user profile or first determined by the visitors IP.
How would you store the international products in the database? Presumably there will not only be one more country added but many more.
Would it either make sense to simply add a column in the products table which country this product belongs to or
have a mapping table or
have separate tables for each country or
something totally different?
Right now I can not say for sure that each product will only be sold exclusively in one country. So I have to assume that one product may be sold in more than one country.
Looking forward to hear your thoughts on this.
That's a classical many-to-many case.
Create a country table and a reference table which stores links between countryID and productID. That way you'll be able to sell a product in only one country or as many countries as you want.
There is a lot of information on SO about many-to-many relationships: https://stackoverflow.com/search?q=many-to-many+mysql
I'm working on building a database to manage project assignments, and the one part that's giving me particular trouble is the assignment of job titles to employees with for each project they are working on.
Requirements
An Employee can be on multiple Projects at a time
A Project has multiple Employees on it
A Project has multiple Job Titles
An Employee works on a Project under exactly one of the Project's Job Titles
Multiple Employees can work under the same Job Title in a Project
I'm not sure how to represent this using tables; every layout I come up with either makes it possible for an employee to work on a project under a job title from a different project, or they are able to work on the same project under two different job titles.
Example Diagrams
Basically, I have three tables:
Tables
Projects
Project Name (unique)
Project ID
Employees
Employee Name (unique)
Employee ID
Job Titles
Title
Project ID (Title-ProjectID unique)
Title ID
And then a cross-reference table, called Assignments. The two ways I have come up with so far for Assignments are as follows:
Example 1
Assignments
Employee ID
Project ID (EmployeeID-ProjectID unique)
Title ID (unique)
AssignmentID
This way limits employees to one title per project, but allows them to use a title that doesn't belong to the project in the assignment.
Example 2
Assignments
Employee ID
Title ID (EmployeeID-TitleID unique)
AssignmentID
This way assigns employees to the project through the title, so it is impossible to assign someone to a project with an invalid title. However, this allows an employee to be assigned to the same project under multiple titles.
Again, the diagrams are available here: http://i.imgur.com/IbR0P.png
I know there must be a way to do this cleanly, but I haven't had any real formal training in database design and I can't find anything through my searches except how to make a many-to-many relationship, which isn't exactly what I need help with.
Thanks!
EDIT 1
Bolded Primary Key Fields (were underlined in diagram image, but hard to tell since they are the last fields)
Added AssignmentID (Primary Key) to Assignments table in the question (was present in designs, forgot to include when creating question & diagram)
EDIT 2
Added missing requirement (5)
Added headers for examples and requirements
EDIT 3
I have 10 rep now, so I can put up the diagram!
EDIT 4
Added identifiers for unique keys (individual unique keys identified in diagram, but I don't know how to do compound keys in DIA)
Add an ID field to you Job Titles table - let's call it JobTitleID
Now your Assignments table has Employee ID and JobTitleID.
This ofcourse means, that to find the Projects for an employee, you need to join through the Assignments table and the Job Titles table
EDIT
After discussion in the comments, please disregard the above, I left it only as history.
Now here is the new version: Your Assignments table needs (as you already considered)
Employee ID
Project ID
Title ID
AssignmentID
But it also needs a UNIQUE INDEX(EmployeeID, ProjectID) - this will make it impossible for one employee to be in the same project under different titles.
Multiple employees under the same title will still be allowed, as well as multiple titles in different projects for one employee.
Do it the first way you mention. It doesn't limit a person to one job title, you can create another record with the same Employee ID and Project ID but with a different Title ID, just use a new Assignment ID as the primary key.
You might even want to take Project ID out of the Job Title table.
I have product and location entities that may/may not have a collection of images.
I know I cannot create a list in the respective entities, but nor do I want to make an association in the Image entity for the other two.
I just want the Image Entity to have Id and file path.
Is there a way I can do this?
If the answer is I MUST create an association in the Image Entity for the other two, then that means whenever in the future I create a new entity that may/may not have photos, I have to modify the Image entity for the association and I do not like that idea.
Thanks in advance.
It sounds like you want a uni-directional relationship. Is this correct? So you want to access Collection<Image> from Product and Location, but not be able to access Product or Location from Image?
You can do this. In EF, the Image class will not have a navigational property to Product or Location -- it will just have Id and FilePath.
However in the database, the Image table will have columns for ProductId and LocationId. This is so that EF can manage the foreign key relationship and populate the collection propertes on Product and Location.
code:
modelBuilder.Entity<Product>.HasMany(p => p.Images).WithOptional()
.Map(d => d.MapKey("ProductId"));
modelBuilder.Entity<Location>.HasMany(p => p.Images).WithOptional()
.Map(d => d.MapKey("LocationId"));
When managing these in your application, you can just add images to the Images collection property on your principal entities (Product and Location) without having to set a navigation property from the dependent Image back to the principal (you can't since the foreign key properties are not present).
You could create two new tables, ProductImages and LocationImages, link to the collection from your Product and Locations, when you insert an item for either, insert a record that joins the image and the product.
That way, when you load your product or your location, you can check if there are any association images by checking the collection.