【问题标题】:Database Design Issue - Different Statuses for Different Sex数据库设计问题 - 不同性别的不同状态
【发布时间】:2015-05-18 08:42:24
【问题描述】:

场景

我想设计表格来保存小牛的数据。

牛和小牛共有的属性/列

  • 价格
  • 出生日期 等(一些来自 FK 以及 Breed 等)

为小牛保留的属性

  • 父亲
  • 妈妈

为 CATTLE(女性)保留的属性

  • IsMilking(是或否)

  • InseminationDate(当然,一头奶牛可以多次受精,因此必须对其进行标准化,并且应该有一个新表:ID(使用 CATTLE 表的 PK 的 FK)和 InsemDate - 但它应该存在仅限女性)

Status 的特殊属性 CATTLE 具有以下属性:

  • 男女通用:{健康、生病}

  • 仅限女性:{孕妇、小母牛等}

由于这种无能的设计,我的整个软件都失败了。我现有的设计如下:

现有设计

有一个 CATTLE 表,它引用所有 STATUS、BREED 等表,因为它是 FK。

有一个包含这些列的 CALF 表:

ID (FK from CATTLE table) - Having cattle and calf in same table is apparently failing
FatherID (FK from CATTLE table) - Again we can have Calfs themselves as Father in this column
MotherID (FK from CATTLE table) - Same issue

提前致谢。我已经尽了最大的努力。为 MALE 和 FEMALE 拆分表(但它需要继承,我还必须拆分所有后续表,如 STATUS 表等)。

【问题讨论】:

  • 一条指示“未知父母”的记录将允许您将所有动物放在同一个表中。
  • 它的设计呢?你的意思是 Calf_Father 和 Mother 列也应该在动物表中吗?
  • 我不是农民,但牛犊不宰杀不就变成牛(牛、牛、牛)吗?您为什么不想为所有动物存储有关父母的信息 - 追踪血统的能力不是在所有情况下都很重要,而不仅仅是对孩子吗?
  • @jpw 哈哈。这很重要,但实际上购买了许多动物,因此没有祖先的下落。是的,小牛会在一段时间后(我估计是 18 个月)转为 CATTLE 状态
  • @TalhaIrfan 啊,我明白了。这是有道理的。

标签: sql sql-server database database-design


【解决方案1】:

问题太宽泛,可能的答案很多,但我尝试过,因为我从事数据库设计。

虽然不完美,但希望能对你有所帮助。

小牛表(小牛记录)

与牛 2x 的关系

牛表(牛记录)

牛的关系

授精表(Insem 记录)

特殊属性表

特殊属性记录表

特殊属性值表

小腿视图

牛状态视图

【讨论】:

  • 谢谢!我很感谢你解释得这么详细
  • 对您没有帮助吗?我们可以讨论需要改进的地方。
  • 如何防止公牛使用母牛状态?在授精表中,我们也可以添加公牛的ID
  • 您可以在 Cattle 表中添加一个 Gender 列,该列将包含值 Male 和 Female。然后在 Special_Attribute 表上,您可以添加一个名为 ForGender 的列,它还将包含男性和女性值。例如,怀孕的 ForGender 值为女性。最后,您可以在 Cattle 内部加入 Special_Attribute 表的 ON 子句中添加“AND Cattle.Gender = Special_Attribute.ForGender”。
  • 要添加授精,您可以告诉您的应用程序只获取性别为女性的牛。
【解决方案2】:

我认为为动物准备一张桌子,并与父亲和母亲建立自我关系是可行的方法。像这样的东西;

CREATE TABLE [dbo].[Animal](
    [AnimalID] [int] IDENTITY(1,1) NOT NULL,
    [Sex] [char](1) NOT NULL CONSTRAINT [Animal_Sex] CHECK  (([Sex]='F' OR [Sex]='M')),
    [Name] [varchar](100) NOT NULL,
    [Price] [money] NULL,
    [BirthDate] [date] NULL,
    [Father_AnimalID] [int] NULL,
    [Father_Sex]  AS (CONVERT([char](1),'M')) PERSISTED,
    [Mother_AnimalID] [int] NULL,
    [Mother_Sex]  AS (CONVERT([char](1),'F')) PERSISTED,
    [IsMilking] [char](1) NULL,
    [HealthStatus] [char](1) NULL,
    [FemaleStatus] [char](1) NULL,
    CONSTRAINT [PK_Animal] PRIMARY KEY CLUSTERED ([AnimalID]),
    CONSTRAINT [AK_Animal] UNIQUE NONCLUSTERED ([AnimalID], [Sex])
)

ALTER TABLE [dbo].[Animal] ADD CONSTRAINT [FK_Animal_Animal_Father] 
    FOREIGN KEY([Father_AnimalID], [Father_Sex]) REFERENCES [dbo].[Animal] ([AnimalID], [Sex])

ALTER TABLE [dbo].[Animal] ADD CONSTRAINT [FK_Animal_Animal_Mother] 
    FOREIGN KEY([Mother_AnimalID], [Mother_Sex]) REFERENCES [dbo].[Animal] ([AnimalID], [Sex])

注意我是如何添加几个常量计算列(Father_Sex 和 Mother_Sex)的——这让我可以为父亲和母亲创建一个更复杂的外键,强制父亲为男性,母亲为女性,并且间接阻止父亲和母亲成为同一种动物。

【讨论】:

  • 谢谢里斯!不过,我仍然对某些属性持怀疑态度
【解决方案3】:

创建一个包含所有人共有的属性和状态的 Animal 表。这将包括父 FK,如果血统不可用,则自引用未知动物

然后为特定性别或阶段的属性创建单独的“扩展”表。牛、公牛、小牛等。您可以将 Animal 表中的 PK 重新用作扩展表的 PK,因为它是 1:1 关系。

这也将允许动物状态与性别状态分开,因此您可以将健康的动物作为怀孕的牛。

我过去曾为收养机构申请这样做过。他们有一个包含通用属性的 people 表,但特定于生母或孩子的属性被放置在专用表中。每个都收集了 30 多个附加字段。出生妈妈/孩子记录仅占人员记录的 25-30%,因此将它们分开而不是在主表中添加 60 多个字段来保证为空是有意义的。

【讨论】:

  • 非常感谢韦斯。
猜你喜欢
  • 1970-01-01
  • 2010-10-09
  • 1970-01-01
  • 2018-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-12
  • 2018-07-10
相关资源
最近更新 更多