mysql - tag系统 - 博客数据库设计



数据库结构/设计 (2)

我想不出一个这样的标题,所以甚至不知道从哪里开始为自己研究。 我必须建立一个数据库,在这里我有一个CD / DVD表格,但是他们的娱乐类型需要不同的元数据/信息属性,例如音乐CD有艺术家,出版商,制作人,CDNo。 而一个软件可能有相似之处,但有一些音乐不会有,可能与电影和游戏相同。 所以我不确定这是如何在ER图上起作用的,到目前为止我决定:

物品表或库存表中的CD / DVD尚未确定名称。

tbl_items - > item_id,item_format(DVD或CD,也许axpand蓝光或HD - DVD),item_entertainment_type(音乐,电影等)<---也许在另一个不知道。 元数据表的外键,如果元数据已经存在,那么当新的CD / DVD发送时,我只需输入一个新的项目,所以元数据和项目之间是一对多的关系(项目>元)。

我认为的问题是, musicMeta_id INT NULL, FOREIGN KEY musicMetaID REFERENCES tbl_musicMeta(musicMeta_id)外键字段是不好的做法,只是选择哪个添加关系,所以musicMeta_id INT NULL, FOREIGN KEY musicMetaID REFERENCES tbl_musicMeta(musicMeta_id)这样的每种类型? 或者以某种方式合并它们,或者有一个数据库有一个技巧。

我用PHP使用MySQL。

谢谢!


Answer #1

我的意见:摆脱FOREIGN KEYs ; 只要确保你有合适的INDEXes


Answer #2

没有一般规则或最佳实践,外键不应该是可空的。 很多时候,一个实体不与另一个实体有关系是非常合理的。 例如,您可能有一张您正在追踪的艺术家的表格,但此刻,您没有这些艺术家记录的CD。

至于具有可以是音乐/音频或软件的媒体(CD,DVD,BluRay),您可以有一个共同信息的表,然后是两个外键,每个扩展表(AudioData和SoftwareData)一个,但是一个必须为NULL 。 这呈现出一种被称为除了别的之外的独占弧的情况。 通常被认为是有问题的。

考虑一个超类和两个派生类,如Java或C ++的OO语言。 在关系模式中表示的一种方法是:

create table Media(
    ID      int not null, -- identity, auto_generated, generated always as identity...
    Type    char( 1 ) not null,
    Format  char( 1 ) not null,
    ... <other common data>,
    constraint PK_Media primary key( ID ),
    constraint FK_Media_Type foreign key( Type )
        references MediaTypes( ID ), -- A-A/V, S-Software, G-Game
    constraint FK_Media_Format foreign key( Format )
        references MediaFormats( ID ) -- C-CD, D-DVD, B-BluRay, etc.
);
create unique index UQ_Media_ID_Type( ID, Type ) on Media;
create table AVData( -- For music and video
    ID       int not null,
    Type     char( 1 ) not null,
    ... <audio-only data>,
    constraint PK_AVData primary key( ID ),
    constraint CK_AVData_Type check( Type = 'A',
    constraint FK_AVData_Media foreign key( ID, Type )
        references Media( ID, Type )
);
create table SWData( -- For software, data
    ID       int not null,
    Type     char( 1 ) not null,
    ... <software-only data>,
    constraint PK_SWData primary key( ID ),
    constraint CK_SWData_Type check( Type = 'S',
    constraint FK_SWData_Media foreign key( ID, Type )
        references Media( ID, Type )
);
create table GameData( -- For games
    ID       int not null,
    Type     char( 1 ) not null,
    ... <game-only data>,
    constraint PK_GameData primary key( ID ),
    constraint CK_GameData_Type check( Type = 'G',
    constraint FK_GameData_Media foreign key( ID, Type )
        references Media( ID, Type )
);

现在,如果您正在寻找电影,您可以搜索AVData表格,然后使用软件或游戏与媒体表格一起加入其他信息。 如果您有一个ID值,但不知道它是什么类型,请搜索媒体表,Type值将告诉您要加入的三个(或更多)数据表中的哪一个。 重点是FK是指通用表,而不是它。

当然,电影或游戏或软件可以以多种媒体类型发布,因此Media表格和各个数据表格之间可以有交集表格。 Otoh,那些通常标有不同的SKU,所以你可能也想把它们作为不同的项目。

代码,正如你所期望的,可能会变得相当复杂,但不是太糟糕。 Otoh,我们的设计目标不是简单的代码,而是数据的完整性。 这使得不可能将游戏数据与电影项目混合。 而你摆脱了一套只有一个必须有一个值,其他必须为空的字段。





entity-relationship