繁体   English   中英

数据库结构/设计

[英]Database Structure/Design

我想不出这个标题,所以甚至都不知道该从哪里开始自己研究。 我必须创建一个数据库,在其中有一张CD / DVD表格,但是它们上的娱乐类型在元数据/信息方面需要不同的属性,例如音乐CD具有艺术家,发行人,制作人和CDNo。 某个软件可能具有相似性,但有一些音乐所没有,并且可能与电影和游戏相同。 因此,我不确定就ER图而言这将如何工作,到目前为止,我决定:

尚不确定项目表或库存表中的CD / DVD名称。

tbl_items-> item_id,item_format(DVD或CD,可能会粘贴到蓝光或hd-dvd),item_entertainment_type(音乐,电影等)<---可能不确定。 元数据表的外键,以便在元数据已经存在的情况下交付新CD / DVD时,我只输入一个新项目,因此元数据和项目之间是一对多的(项目>-元)。

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

我正在使用MySQL和PHP。

谢谢!

没有一般规则或最佳实践,外键不应为空。 很多时候,一个实体不与另一个实体有关系是很有意义的。 例如,您可能有一张要跟踪的艺术家表,但目前您还没有这些艺术家录制的CD。

至于具有可以是音乐/音频或软件的媒体(CD,DVD,BluRay),则可以有一个包含公用信息的表,然后有两个外键,每个扩展表一个(音频数据和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表,然后与Media表结合以获取其余信息,以此类推,以软件或游戏为例。 如果您具有ID值,但不知道它是什么类型,请搜索“媒体”表,“类型”值将告诉您要连接的三个(或更多)数据表中的哪个。 关键是FK引用是通用表,而不是通用表。

当然,电影,游戏或软件可以在一种以上的媒体类型上发布,因此您可以在Media表和相应的数据表之间建立交叉表。 Otoh,这些标签通常带有不同的SKU,因此您可能还需要将它们视为不同的商品。

如您所料,代码可能会变得相当复杂,尽管还算不错。 Otoh,我们的设计目标不是简化代码,而是数据完整性。 这使得不可能将例如游戏数据与电影项目混合。 而且您摆脱了拥有一组字段的情况,其中只有一个字段必须具有值,而其他字段必须为null。

我的观点:摆脱的FOREIGN KEYs ; 只要确定您有合适的INDEXes

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM