2013-02-23 111 views
8

所以我应该创建这个模式+关系,就像这个ERD描述它的方式一样。在这里,我只能说明我有问题的表:创建PostgreSQL表格+关系 - 带关系的问题 - 一对一

I am supposed to have ONE TO ONE but I get ONE TO MANY

所以我想使它一对一,但出于某种原因,不管我改变,我得到一对多就什么表具有外键。

这是我的这两个表的sql。

 CREATE TABLE lab4.factory(

      factory_id  INTEGER   UNIQUE, 
      address   VARCHAR(100) NOT NULL, 
      PRIMARY KEY (factory_id) 

     ); 

     CREATE TABLE lab4.employee(

      employee_id  INTEGER   UNIQUE, 
      employee_name VARCHAR(100) NOT NULL, 
      factory_id  INTEGER   REFERENCES  lab4.factory(factory_id), 
      PRIMARY KEY (employee_id) 

     ); 

这里我得到了同样的结果。我没有得到一对一的关系,而是一对多的关系。 Invoiceline是一个弱的实体。

it needs to be ONE TO ONE

这里是我的第二图像的代码。

 CREATE TABLE lab4.product(

      product_id  INTEGER  PRIMARY KEY, 
      product_name INTEGER  NOT NULL 

     ); 


     CREATE TABLE lab4.invoiceLine(

      line_number  INTEGER  NOT NULL, 
      quantity  INTEGER  NOT NULL, 
      curr_price  INTEGER  NOT NULL, 
      inv_no   INTEGER  REFERENCES  invoice, 
      product_id  INTEGER  REFERENCES  lab4.product(product_id), 
      PRIMARY KEY (inv_no, line_number) 

     ); 

我将不胜感激任何帮助。谢谢。

+1

您如何预测建立1:1关系?在外键列上有'UNIQUE'约束?有相互可推迟的外键约束? – 2013-02-23 05:21:05

+0

@CraigRinger,我希望我有知识基础来回答你的问题,但我只是在我的第一个DB类中的几个讲座。我的问题如下:我如何创建一对一的关系?出于某种原因,我们主要讨论了多对多和多对多 – 2013-02-23 05:26:48

回答

22

一对一在标准SQL中没有被很好地表示为第一类关系类型。很像多对多,这是使用连接器表和两个一对多关系实现的,SQL中没有真正的“一对一”。

有几个选项:

  • 创建一个普通的外键约束(“一对多”的风格),然后在指FK列中添加一个UNIQUE约束。这意味着引用列中不会出现超过一个被引用的值,因此它是一对一可选的。这是一个相当简单,相当宽容的方法,效果很好。

  • 使用一个可以模拟1:m的正常FK关系,并让您的应用程序确保它在实践中只有1:1。我不建议这样做,添加FK唯一索引时只有很小的写入性能下降,它有助于确保数据有效性,查找应用程序错误并避免让其他需要稍后修改架构的人感到困惑。

  • 创建互惠外键 - 只有当您的数据库支持可延迟外键约束时才可能。这对代码来说更复杂一些,但允许您实现一对一的强制关系。每个实体都有一个唯一列中的其他PK的外键引用。其中一个或两个约束条件必须是DEFERRABLEINITIALLY DEFERRED或与SET CONSTRAINTS调用一起使用,因为您必须推迟其中一个约束检查以设置循环依赖关系。这是一项相当先进的技术,对绝大多数应用来说不是必需的。

  • 如果您的数据库支持它们,请使用预先提交触发器,这样您就可以验证插入实体A时是否插入了一个实体B,反之亦然,并进行相应的更新和删除检查。这可能很慢并且通常是不必要的,而且许多数据库系统不支持预先提交触发器。

+0

,所以在我的情况下,factory_id必须是UNIQUE,因为我已经通过employee表进行了参考。 – 2013-02-23 05:38:13

+0

@GeorgiAngelov是的,'lab4.employee.factory_id' *引用方*可以标记为'UNIQUE'。考虑一下:独特的FK列最多可以容纳所提到的PK列的每个值中的一个。当你在不止一个地方使用这个名字时,只是说'factory_id'有点像在机场上说的“坐上Quantas飞机” - *哪个飞机?*请注意,这会在引用端创建一个可选的关系; *最多*一名员工可以管理一家工厂,但不要求任何一家工厂都有经理。 – 2013-02-23 05:39:43

+0

谢谢。这真的澄清了事情。我感谢您的帮助。 – 2013-02-23 05:46:46