加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程 > 正文

数据库计划 – 怎样将IS-A相关映射到数据库?

发布时间:2021-01-10 13:26:46 所属栏目:编程 来源:网络整理
导读:思量以下: 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 d

思量以下:

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,privilegeLevel INTEGER 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,PRIMARY_KEY(uid)
)

CREATE TABLE OpenIDUsers
(
    uid INTEGER AUTO_INCREMENT NOT NULL,//OpenID Attributes
    PRIMARY_KEY(uid)
)

我险些可以必定第三种方法是错误的方法,由于不行能对数据库中其他处所的用户举办简朴的毗连.

我的真实天下示例不是具有差异登录示例的用户;我对如安在一样平常环境下模仿这种相关感乐趣.

办理要领

方法二是正确的要领.

您的基类获取一个表,然后子类只行使它们引入的其他字段得到本身的表,以及对基表的外键引用.

正如Joel在对此谜底的评述中所提议的那样,您可以担保用户将具有直接登录或OpenID登录,但不能同时(也也许两者都没有)通过向每个子范例表添加范例列来锁定到根表.每个子范例表中的type列被限定为具有暗示该表范例的单个值.因为此列是外键到根表,因此一次只能有一个子范例行链接到统一根行.

譬喻,MySQL DDL看起来像:

CREATE TABLE Users
(
      uid               INTEGER AUTO_INCREMENT NOT NULL,type              ENUM("DirectLogin","OpenID") NOT NULL
    // ...,PRIMARY_KEY(uid)
);

CREATE TABLE DirectLogins
(
      uid               INTEGER NOT_NULL,type              ENUM("DirectLogin") NOT NULL
    // ...,FORIGEN_KEY (uid,type) REFERENCES Users (uid,type)
);

CREATE TABLE OpenIDLogins
(
      uid               INTEGER NOT_NULL,type              ENUM("OpenID") NOT NULL
    // ...

    PRIMARY_KEY(uid),type)
);

(在其他平台上,您将行使CHECK束缚而不是ENUM.)MySQL supports复合外键,因此这应该得当您.

第一种要领是有用的,尽量你在那些可以行使NULL的列中挥霍空间,由于它们的行使取决于用户的范例.利益是,假如您选择扩展要存储的范例的用户范例,而且这些范例不必要其他列,则只需睁开ENUM的域并行使沟通的表.

方法三逼迫任何引用用户搜查两个表的查询.这也会阻止您通过外键引用单个用户表.

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读