数据库计划 – 怎样将IS-A相关映射到数据库?
思量以下: 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的域并行使沟通的表. 方法三逼迫任何引用用户搜查两个表的查询.这也会阻止您通过外键引用单个用户表. (编辑:湖南网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |