I'm having a scenario to create an ER diagram.
Scenario
There are Several Regions. One region can have several Business Chains. Each Business chain have one region to cover. One Business chain have several outlets. Customers can use this system to connect to any Business chain. Employees of a Business chain can be assigned to any outlet by the admin of the particular Business chain................
My Question is how am I suppose to handle user details and login details in the above ER diagram (or in the application)
Should I use two separate entities as "Customer" and "Employee"???
Should I use one entity as "User"? If so how to handle the above case of handling emplyees' roster
I suggest you combine customers, employees and users into persons, and use subtyping for each of the roles in which a person may occur:
I left out any indication of overlapping/disjoint subsets, you can fill them in based on your requirements. Implementing disjoint subsets would require adding some additional type indicators and check constraints to the tables below.
Physically, the diagram above would translate into a set of tables like:
person (person_id PK, first_name, last_name, ...)
user (person_id PK/FK, username, password_hash, ...)
customer (person_id PK/FK, credit_limit, ...)
employee (person_id PK/FK, salary, ...)
This allows any person with a user record to log in, and you can easily find out whether they're customers, employees (or both) by joining with those tables. You can create customer or employee-specific relationships easily, e.g.
outlet_employees (outled_id PK/FK, employee_person_id PK/FK)
where employee_person_id has an FK constraint referencing person_id in the employee table. You can also make user-specific relationships, or general person relationships, as your requirements dictate
Related
Lets say a relationship is described as:
A company has many employees
A company has many departments
A department has many employees
So, something like this;
Company -<< Departments >>- Employees
If department table has a basic structure of:
// Pseduocode
company_id // Foreign key
department_id // Primary key
[employees] // Array or collection of employees
If we go back to this phrase;
A Company has many employees
Does this mean that the employee table needs or requires a reference for the company_id too?
So, Employee would be:
employee_id
company_id // I'm not sure if this is requried or not
department_id
I'm intending to hopefully abstract this data into a contracts table in case of employees are freelancers/contracters, etc or have multiple employees.
But for now..
My question is:
Does my employee table require a reference to the company table, or is the company reference implied via the department table?
Many thanks
Question is: do you need a straight connection between Company and Employee? If you do, add it, if not then yes, the connection is implied through Department.
EDIT:
Technically, your Department table does not need a list of Employees. Each row of Employee table has a reference ID to Department, that's enough.
Check this out for more information.
The relationship is implied through the department, so you don't conceptually need it. Adding it, would be an example of denormalisation, and would allow inconsistencies to crop up. For example, you might have company_1 with department_1 and company_2. Now employee_1 might be linked to department_1 but company_2, because of some flaw/bug in the application code. There's no way to express this constraint as a SQL schema, so you'd have to go with more complicated stuff such as triggers, or application code checks etc.
However, sometimes you only need info about companies and employees, but not about departments. If it's really performance critical, doing the extra join with departments in order to find the company for an employee or the employees for a company might not cut it, so you'll just have to live with the denormalisation.
You probably do not need to link Company with Employee. The relation between Departement and Company already do the job. You may need it only if there are existing particular cases requiring this relationship.
I'm searching for a solution to model a "can-be" relationship.
E.g.: A User can be Special User.
Any suggestions?
Types for entities can be viewed (results) as one of the following two things:
Relationships
Fields
The types that results in fields are usually seen as functional redundancy, where different rows/records in a table can have the same type. For example, the sex/gender of a user, or access privileges or permission level from a user as well.
If, however, this field has attributes/properties, so we have a new entity. In this case, users would be relating to, for example, address, which may have the street name, house number, among other things. Or, in your case, if Special User has attributes/properties, we have a "Special Users" entity. The cardinality here depends on how many types a user can have, and that takes into account the problem context.
As you say that a user "can be", it means it "can not be" too. You could:
Set a nullable functional redundancy field in Users entity or,
Set an entity "Types of Users" and create a relationship N-N for
"Users". In this case, you would have an intermediate table that
would allow or not the connection between the two entities.
In both approaches you have the ability to add new types of users in the future without effort.
There is a third case, however, referred to as partitioning, where we have types and subtypes of entities. In this case, entities subtypes inherit fields of their super entities. I believe this is not your case here.
If you have any questions, please comment and I will answer.
I have a standard devise user model with the usual fields.
This is for a situation where people are either looking for a place to stay, or they have a place to stay. So I have two categories of user that a person can be. These two categories are very distinct (i.e. a person looking for a place to stay will have very different fields to a person who has a place to stay).
So a User has:
User: name, email, password, profile_id
A User can also have a Profile (i.e. they are looking for a house).
Profile: age, sexuality, religion, occupation
That's what I have at the moment. Now I need to change that slightly, so a User can have a profile OR... they can have a House (i.e. they have a house and are looking for more people):
House: price_per_week, address, etc
How best to model this in ActiveRecord? Polymorphic association of some kind?
I've found in general that polymorphic relationships don't work well over time if the objects they are modeling are even mildly different. For your case I'd recommend keeping the two objects separate.
In general, the best way is to consider the way you want to retrieve the data. For example, I'd imagine you want to access both:
#user.house
or
#user.profile
So I'd recommend beginning by setting up relationships (that can be optional) between the users table and both the profiles and houses table. I'd also add a type field that can be used to determine which of the two types the users are.
This allows users to be of either type and allows them to have both a profile and a house.
So both houses and profiles belong_to users, and users have_many (or have_one) houses and profiles
My Rails application uses STI where I have different types of companies and persons. For example I have suppliers, manufacturers and customers as types of Company. I have also employees, contacts and customers as types of People.
Now I want to refer to a Customer which can either be a Company Customer or a Person Customer. Which method can I use/should I use to combine these two different entities into one? So I can refer to a Customer, from an Order?
You could either use:
Order
belongs_to :company
belongs_to :person
end
And have two foreign keys - and then add some validations to make sure one of them is filled in, and then maybe add a 'customer' method which returns either the related company or person, depending which is used.
OR, create a separate Customer model (and table), which has those two same two foreign keys, and then Order can simply belong_to :customer. This second method may be preferably if you want to store additional data at the customer level (such as credit limit, or billing details), and may be cleaner long-term.
Alternative, you could reconsider your business logic, and insist that all orders belongs to a Person, even if that person is an employee of a Company and is purchasing on behalf of the company.
F
I have multiple user account types, each with different information. For example, business contacts link to businesses, school administrators and students link to schools. Students have physical addresses, but business contacts and school admins use the organizations address. There's other information unique to each type as well.
I'm leaning toward separate tables for students, school admins and business contacts, but using Authlogic, I have a Users table with authentication information (all need to log in).
The question is really how best to link this single authentication table with the individual profiles. It seems like a one-to-one relationship requires a single table (e.g. Users <-> Students or Users <-> Business_contacts). I want to have something of a "one-to-one-of-the-following" relationship (Users <-> Students or Business_contacts). Is there a good way to do this using a join table or other construct?
Alternatively, I could unify the common information in the Users table and come up with a "profile" column in XML to support the unique information. My thought was that keeping everything in clean DB columns would simplify selects/inserts.
Thoughts, ideas?
business contacts link to businesses, school administrators and students link to schools.
This means you have different roles of users rather than different users.
Students have physical addresses, but business contacts and school admins use the organizations address
There's other information unique to each type as well.
Which means different roles have different data and behavior, leading to different OO classes.
The question is really how best to link this single authentication table with the individual profiles.
I want to have something of a "one-to-one-of-the-following" relationship (Users <-> Students or Business_contacts). Is there a good way to do this using a join table or other construct?
The simplest model I can think of if the following:
User (Username, Email, Password, Names and other common data for every user)
Participant, abstract. (has relation to one user - defines the role of the participant, behavior and its common data). Should provide the interface for participants.
Student (inherits from Participant, adds its own behavior and data)
SchoolAdministrator (inherits from participant)
And so on
In the Object Oriented World (non RDBMS) this has a simple advantage: polymorphism. Having a user you don't need to know exactly who he is. You just do things like this:
user.participant.can_manage_stuff?
user.participant.order_book(harry_potter)
And the appropriate actions will take place which will be implemented in Student, SchoolAdministrator or other class inherited from Participant.
Another things is that it is very easy to add new roles for the system. Just inherit from Participant and implement its interface.
Now, when Object Oriented Design is done, let's have a look at the data storage. I assume you use RDBMS.
So now you have 2 types of links:
One-to-one association between User and Participant.
Generalization (inheritance) between Participant and Student, SchoolAdministrator.
Implementation of 1st is as simple as having has_one and/or belongs_to association for the following table (via participant_id column):
users:
id | username | email | password | etc | participant_id (non-null) FK_TO_participants table |
So you can easily implement that.
Now, the 2nd link can be implemented in RDBMS in number of different wasy.
But fortunately or unfortunately ActiveRecord supports only one option to do that. And it is hierarchy per table mapping strategy that uses discriminator column to distinguish the type (stored in type column by convention).
So you will have the 2nd table that looks like this:
perticipants:
id | type | student_card_number (null) | administrator_number (null) | etc
This table will have all the columns for all possible participants. This is the simplest and easiest implementation of hierarchy in DB. But not the most optimal from some points of view. As I said with ActiveRecords it is only one option available anyway.
So as a result of this design you will end up with 2 database tables (users, participants) and at least 3 classes (User, Participant, Student).
And, of course, you can vary from here a lot but that should deliver my point.
And yes, please no XML in database, don't waste your nerves and valuable personal time.
Cheers.
If you really need seperate models for each role you use, then I would recomend to use polymorphic association (read more here). So:
# User model
belongs_to :owner, :polymorphic => true
# Student model
has_one :user, :as => :owner
# Any other model
has_one :user, :as => :owner
And you need to add to users table:
t.integer :owner_id
t.string :owner_type