Question

I am designing a database that has multiple types of users, i.e. Administrators, Editors, Teachers and Students. Now all these users have some common fields (CF) and some unique fields (UF) associated to them. I was wondering if this is a good design?

Table Users: [user_id (PK), CF1, CF2,..., CFN, user_type (enum)]

Table Admin: [id (PK), UF_A1, UF_A2, ... , U_AN, user_id(FK)]

Table Editors: [id (PK), UF_E1, UF_E2, ... , U_EN, user_id(FK)]

Table Teachers: [id (PK), UF_T1, UF_T2, ... , U_TN, user_id(FK)]

Table Students: [id (PK), UF_S1, UF_S2, ... , U_SN, user_id(FK)]

where UF_A, UF_E, UF_T and UF_S are unique fields for each of the respective tables.

Now my questions are:

  1. Is this a good design? If not, how will you design it?
  2. How do I ensure that a user of user_type teacher is not stores in students table for example?

PS: Some more points if they might help in getting a better insight:

  1. The database will be used with codeigniter.
  2. Examples of CF are: username, password, email, profile picture
  3. Examples of unique fields are: Students(age, enrollment number), Teacher (univ. name, univ. logo, academic degree)
Was it helpful?

Solution 2

Your design (Users.user_type) implies that a particular person can be an Admin, or that person can be an Editor, but can't be both. It also implies that teachers can't be editors. Is that what you intended?

The columns Admin.user_id, Editors.user_id, Teachers.user_id, Students.user_id are usually primary keys in the kind of structure you're describing. If CodeIgniter won't let you make them primary keys, you still need to declare them unique.

Examples of unique fields are . . . Teacher (univ. name, univ. logo, academic degree)

That's probably not true.

How do I ensure that a user of user_type teacher is not stores in students table for example?

With overlapping constraints, default values, check constraints, and foreign key references. It's easier than it sounds. See this SO answer. But I'm not convinced you really want to do this.

OTHER TIPS

Your design is one of 3 generally recognized ways of modeling inheritance relationships in relational databases; the others are "class per table", where each subclass has its own complete table, or "one table to rule them all", where all possible columns live in a single table.

Further alternatives are using Entity-Attribute-Value or documents (e.g. JSON or XML) to store the data.

Your design has the following benefits:

  • Consistency: the common data is consistently stored and managed; once you've written the rules for passwords, you know they'll be applied everywhere.
  • Maintainability: it's clear which data lives where, and it allows you to use subtly different implementations for subclasses (storing a teacher's name may require including a title - "Dr.", storing a student's name may not).
  • Performance: it should be fast to run relational queries on the data structure ("find all students between 12 and 14 who have no enrollment number"); this can get very tricky on EAV or document solutions.

Drawbacks:

  • creating a new subclass may require creating a new table (this is where EAV and document solutions often win).
  • querying across subclasses may be tricky ("find all users who were either born after 1990 or who have a degree from Stanford"). This is where "one big table" often wins.
  • some relations are not easily modeled using "standard" relational tools like unique keys, foreign keys etc. - your example of "you are either a student or a teacher, but not both", for instance. You can use triggers or application logic instead.
  • multiple inheritance - a user may be both and editor and a teacher, for instance - can become confusing.

Your design illustrates a design technique known as .
This tag has an info tab that outlines the technique.

As the info says, there is a another technique that might be helpful, namely .

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top