简体   繁体   English

创建PostgreSQL表+关系 - 问题与关系 - 一对一

[英]Creating PostgreSQL tables + relationships - PROBLEMS with relationships - ONE TO ONE

So I am supposed to create this schema + relationships exactly the way this ERD depicts it. 所以我应该完全按照ERD描述它的方式创建这个模式+关系。 Here I only show the tables that I am having problems with: 这里我只显示我遇到问题的表格:

我应该有一对一,但我得到一个很多

So I am trying to make it one to one but for some reason, no matter what I change, I get one to many on whatever table has the foreign key. 所以我想尝试一对一,但出于某种原因,无论我改变什么,我都会在有外键的任何表上获得一对多。

This is my sql for these two tables. 这是我对这两个表的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 )

        );

Here I get the same thing. 在这里,我得到同样的东西。 I am not getting the one to one relationship but one to many. 我不是一对一的关系,而是一对一的关系。 Invoiceline is a weak entity. Invoiceline是一个弱势实体。

它需要一对一

And here is my code for the second image. 这是我的第二张图片的代码。

        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 )

        );

I would appreciate any help. 我将不胜感激任何帮助。 Thanks. 谢谢。

One-to-one isn't well represented as a first-class relationship type in standard SQL. 一对一没有很好地表示为标准SQL中的第一类关系类型。 Much like many-to-many, which is achieved using a connector table and two one-to-many relationships, there's no true "one to one" in SQL. 就像使用连接器表和两个一对多关系实现的多对多一样,SQL中没有真正的“一对一”。

There are a couple of options: 有几种选择:

  • Create an ordinary foreign key constraint ("one to many" style) and then add a UNIQUE constraint on the referring FK column. 创建一个普通的外键约束(“一对多”样式),然后在引用的FK列上添加一个UNIQUE约束。 This means that no more than one of the referred-to values may appear in the referring column, making it one-to-one optional. 这意味着引用列中不得出现多于一个引用值,使其成为一对一可选项。 This is a fairly simple and quite forgiving approach that works well. 这是一种相当简单且非常宽容的方法,效果很好。

  • Use a normal FK relationship that could model 1:m, and let your app ensure it's only ever 1:1 in practice. 使用可以模拟1:m的普通FK关系,并让您的应用确保它在实践中只有1:1。 I do not recommend this, there's only a small write performance downside to adding the FK unique index and it helps ensure data validity, find app bugs, and avoid confusing someone else who needs to modify the schema later. 我不建议这样做,添加FK唯一索引只有很小的写入性能下降,它有助于确保数据有效性,查找应用程序错误,并避免混淆其他需要稍后修改架构的人。

  • Create reciprocal foreign keys - possible only if your database supports deferrable foreign key constraints. 创建互惠外键 - 仅当您的数据库支持可延迟的外键约束时才可能。 This is a bit more complex to code, but allows you to implement one-to-one mandatory relationships. 这对代码来说有点复杂,但允许您实现一对一的强制关系。 Each entity has a foreign key reference to the others' PK in a unique column. 每个实体在唯一列中都有对其他PK的外键引用。 One or both of the constraints must be DEFERRABLE and either INITIALLY DEFERRED or used with a SET CONSTRAINTS call, since you must defer one of the constraint checks to set up the circular dependency. 其中一个或两个约束必须是DEFERRABLE并且是INITIALLY DEFERRED或与SET CONSTRAINTS调用一起使用,因为您必须推迟其中一个约束检查以设置循环依赖关系。 This is a fairly advanced technique that is not necessary for the vast majority of applications. 这是一种相当先进的技术,绝大多数应用都不需要。

  • Use pre-commit triggers if your database supports them, so you can verify that when entity A is inserted exactly one entity B is also inserted and vice versa, with corresponding checks for updates and deletes. 如果您的数据库支持预先提交触发器,请使用预提交触发器,这样您就可以验证插入实体A时是否还插入了一个实体B,反之亦然,并相应地检查更新和删除。 This can be slow and is usually unnecessary, plus many database systems don't support pre-commit triggers. 这可能很慢并且通常是不必要的,而且许多数据库系统不支持预提交触发器。

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

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