Considera lo siguiente:
entity User
{
autoincrement uid;
string(20) name;
int privilegeLevel;
}
entity DirectLoginUser
{
inherits User;
string(20) username;
string(16) passwordHash;
}
entity OpenIdUser
{
inherits User;
//Whatever attributes OpenID needs... I don't know; this is hypothetical
}
Los diferentes tipos de usuarios (usuarios de inicio de sesión directo y usuarios de OpenID) muestran una relación IS-A; a saber, que ambos tipos de usuarios son usuarios. Ahora, hay varias formas en que esto se puede representar en un RDBMS:
Un camino
CREATE TABLE Users
(
uid INTEGER AUTO_INCREMENT NOT NULL,
name VARCHAR(20) NOT NULL,
privlegeLevel INTEGER NOT NULL,
type ENUM("DirectLogin", "OpenID") NOT NULL,
username VARCHAR(20) NULL,
passwordHash VARCHAR(20) NULL,
//OpenID Attributes
PRIMARY_KEY(uid)
)
Camino dos
CREATE TABLE Users
(
uid INTEGER AUTO_INCREMENT NOT NULL,
name VARCHAR(20) NOT NULL,
privilegeLevel INTEGER NOT NULL,
type ENUM("DirectLogin", "OpenID") NOT NULL,
PRIMARY_KEY(uid)
)
CREATE TABLE DirectLogins
(
uid INTEGER NOT_NULL,
username VARCHAR(20) NOT NULL,
passwordHash VARCHAR(20) NOT NULL,
PRIMARY_KEY(uid),
FORIGEN_KEY (uid) REFERENCES Users.uid
)
CREATE TABLE OpenIDLogins
(
uid INTEGER NOT_NULL,
// ...
PRIMARY_KEY(uid),
FORIGEN_KEY (uid) REFERENCES Users.uid
)
Camino tres
CREATE TABLE DirectLoginUsers
(
uid INTEGER AUTO_INCREMENT NOT NULL,
name VARCHAR(20) NOT NULL,
privlegeLevel INTEGER NOT NULL,
username VARCHAR(20) NOT NULL,
passwordHash VARCHAR(20) NOT NULL,
PRIMARY_KEY(uid)
)
CREATE TABLE OpenIDUsers
(
uid INTEGER AUTO_INCREMENT NOT NULL,
name VARCHAR(20) NOT NULL,
privlegeLevel INTEGER NOT NULL,
//OpenID Attributes
PRIMARY_KEY(uid)
)
Estoy casi seguro de que la tercera forma es la equivocada, porque no es posible hacer una unión simple contra usuarios en otra parte de la base de datos.
Sin embargo, mi ejemplo del mundo real no es un usuario con diferentes inicios de sesión; Estoy interesado en cómo modelar esta relación en el caso general.