【问题标题】:Database Structure/Design数据库结构/设计
【发布时间】:2015-06-17 23:14:08
【问题描述】:

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

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

tbl_items -> item_id, item_format(DVD 或 CD,可能扩展至蓝光或高清 DVD), item_entertainment_type(音乐、电影等) --元)。

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

我正在使用 MySQL 和 php。

谢谢!

【问题讨论】:

    标签: mysql database-design entity-relationship


    【解决方案1】:

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

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

    当然,电影、游戏或软件可以在多个媒体类型上发布,因此您可以在Media 表和相应的数据表之间建立交集表。 Otoh,它们通常标有不同的 SKU,因此您可能还希望将它们视为不同的项目。

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

    【讨论】:

    • MySQL 不强制执行 CHECK 约束。
    • 非常感谢,由于截止日期,我不得不提出一个简单的解决方案,但这对将来会有帮助。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-17
      • 2021-08-10
      • 1970-01-01
      • 1970-01-01
      • 2012-10-20
      • 1970-01-01
      • 1970-01-01
      • 2010-09-11
      相关资源
      最近更新 更多