考虑以下:
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
}
不同类型的用户(直接登录用户和OpenID用户)显示IS-A关系。即,两种类型的用户都是用户。现在,有几种方法可以在RDBMS中表示:
方式一
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)
)
方式二
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
)
方式三
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)
)
我几乎可以肯定,第三种方法是错误的方法,因为不可能对数据库中其他地方的用户进行简单的联接。
我的真实示例不是使用不同登录示例的用户;而是 我对如何在一般情况下建立这种关系感兴趣。
我已经编辑了答案,以包括乔尔·布朗(Joel Brown)评论中建议的方法。它应该为您工作。如果您正在寻找更多建议,我会重新标记您的问题,以表明您正在寻找MySQL特定的答案。
—
Nick Chammas
注意,这实际上取决于在数据库的其余部分中如何使用关系。涉及子实体的关系只需要那些表的外键,并禁止映射到单个统一表而没有任何恶意。
—
贝尔达兹
在像PostgreSQL这样的对象关系数据库中,实际上有第四种方法:您可以从另一个表声明一个表INHERITS。postgresql.org/docs/current/static/tutorial-inheritance.html
—
MarkusSchaber,