There are various options, as stated in other answers, that shake out different ways. I can tell you that in my experience, I have never regretted parsing the user from the roles. In other words:
A user table that contains only the attributes that describe a user. These are usually just identification and authentication (an identifier, a name, often a primary authenticating email address, and often the actual authentication attributes such as password, salt, encryption key, etc. Think about how you registered for stackoverflow.
A reference table for the roles with rows for Student, Teacher, Administrator, etc.
An association between the two so a user may be a member of zero, one or more roles. Even if your current need is for a one-to-one, you want that to be a business decision and not a technical constraint. Unless you are processing extreme velocity, the association should not cause any significant performance hit (assuming proper indexing).
Then you are free to extend into authorization by associating roles with tasks through permissions, etc.
It's true you could use a type discriminator as an attribute of user, but think about how limited this will be when 1) the business decides that a user can inhabit multiple roles, or 2) that you want to have relationships to the roles instead of the user as in my authorization example.
It's also true that you could forego the user table and just have separate tables for each user type such as teacher, administrator, etc. But then you'll need to artificially union those tables just to authenticate, authorize or otherwise work with users. If you want to extend the set of user attributes, you have to modify all those tables. If you want to add a role, you have to alter your schema with a new table instead of just adding a row to the role table.