【问题标题】:Model database to represent constraints模型数据库来表示约束
【发布时间】:2012-10-04 00:43:09
【问题描述】:

我正在构建一个数据库(用于一个类)来为零件订购应用程序建模。 “供应商”提供零件(不同的供应商可能各自提供一个或多个履行相同角色的零件,并且每个零件恰好履行一个角色),“经理”决定哪些零件将是可订购的(只有一个履行给定角色的零件可以订购),用户可以订购零件。

我目前处于 E-R 图绘制阶段。我不确定如何为零件、角色和可订购产品建模。我可以将每个可订购/角色表示为(概念)“客户部分”实体,并与“供应商部分”实体创建两个关系:

上面写着“试用版创建”看起来很俗气,但相信我,它比我的鸡抓字写得好。

但是,这里没有涵盖一个关键的约束条件。想象一下,您有两组供应商零件,每组履行一个角色。每组部件(每个角色)将由一个客户部件表示。但是,该模型不保证客户部件与在“订单”关系中履行正确角色的部件相对应。

我也尝试过使用三元关系和聚合对其进行建模,但我仍然无法捕获所有约束。

我的问题归结为:我有零件、角色和可订购的物品。 Roles 和 orderables 映射 1-1 并真正可以合并到一个实体中。我如何表示每个部分都与一个角色相关联,每个角色都与一个可订购对象相关联,反之亦然,并且每个可订购对象都与一个也与该可订购对象对应的角色相关联的部分相关联?

感谢您提供的任何见解。

【问题讨论】:

    标签: database data-modeling entity-relationship


    【解决方案1】:
    suppliers
    ---------
    PK supplier_id
    
    parts -- 1-1 part to role
    -----
    PK part_id
    FK role_id
    
    stocks -- suppliers' parts
    ------
    PK stock_id
    FK supplier_id
    FK part_id
    
    roles
    -----
    PK role_id
    
    managers
    --------
    PK manager_id
    
    selections -- part selected by a manager for a role
    ----------
    PK selection_id
    FK manager_id
    FK role_id
    FK part_id
    
    LEGEND: PK = Primary Key (assuming SERIAL PRIMARY KEY), FK = Foreign Key
    

    除了selections 表,您还可以将FK part_id 添加到roles

    【讨论】:

      【解决方案2】:

      我有点着急,我可能会迷失在你的要求中。 (但 +1 表示它们相当清楚。)让我们先解决简单的问题。我在这里主要使用自然键,因为自然键可以更容易地查看正在发生的事情。我认为,对你来说真正重要的部分是重叠的外键约束(接近尾声)。

      简单的东西——零件、供应商和角色的表格。

      create table test.parts (
        part_num varchar(15) primary key
      );
      
      insert into test.parts values 
      ('Part A'), ('Part B'), ('Part C');
      
      -- "Suppliers" provide parts.
      create table test.suppliers (
        supplier_name varchar(35) primary key
      );
      
      insert into test.suppliers values
      ('Supplier A'), ('Supplier B'), ('Supplier C');
      
      create table test.roles (
        role_name varchar(15) primary key
      );
      
      insert into test.roles values
      ('Role 1'), ('Role 2'), ('Role 3');
      

      一个要求:每个部分都恰好履行一个角色。 (有关 UNIQUE 约束的更多信息,以及关于使用此表而不是稍后简单地向“部分”添加一列。)

      create table test.part_roles (
        part_num varchar(15) primary key references test.parts (part_num),
        role_name varchar(15) not null references test.roles (role_name),
        unique (part_num, role_name)
      );
      
      insert into test.part_roles values
      ('Part A', 'Role 1'), ('Part B', 'Role 1'), ('Part C', 'Role 2');
      

      另一个要求 - 每个供应商可以提供一个或多个履行相同角色的零件。我认为这简化为“每个供应商提供多个零件”。 (存储有关部件所属角色的事实是不同表的责任。)

      create table test.supplied_parts (
        supplier_name varchar(35) not null 
          references test.suppliers (supplier_name),
        part_num varchar(15) not null references test.parts (part_num),
        primary key (supplier_name, part_num)
      );
      
      insert into test.supplied_parts values
      ('Supplier A', 'Part A'),
      ('Supplier A', 'Part B'),
      ('Supplier A', 'Part C'),
      ('Supplier B', 'Part A'),
      ('Supplier B', 'Part B');
      

      另一个要求——经理决定哪些零件可以订购。 (用 GRANT 和 REVOKE 处理经理。)只有一个满足给定角色的零件可以订购。 (这意味着对角色名称的主键约束或唯一约束。)除非有人提供,否则您不能订购零件。 (所以我们需要重叠外键约束。)

      这就是我前面提到的 test.part_roles (part_num, role_name) 的 UNIQUE 约束的用武之地。

      create table test.orderable_parts (
        role_name varchar(15) primary key references test.roles,
        part_num varchar(15) not null,
        foreign key (part_num, role_name) 
          references test.part_roles (part_num, role_name),
      
        supplier_name varchar(35) not null,
        foreign key (supplier_name, part_num) 
          references test.supplied_parts (supplier_name, part_num)
      );
      
      insert into test.orderable_parts values
      ('Role 1', 'Part A', 'Supplier A'),
      ('Role 2', 'Part C', 'Supplier A');
      

      我认为使用单独的 part_roles 表可能会更好。 (例如,比在零件中添加一列更好。)供应商通常会提供比您今天感兴趣的更多的零件今天,但企业通常希望提前计划,在承诺使用零件之前收集有关零件的信息他们(在您的情况下,担任特定角色)。

      【讨论】:

      • 谢谢!那应该很好地满足要求。赞一个!
      猜你喜欢
      • 2015-09-30
      • 2018-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-15
      • 2010-11-09
      相关资源
      最近更新 更多