所以我应该完全按照ERD描述它的方式创建这个模式+关系。在这里,我只显示我遇到问题的表格:
所以我想尝试一对一,但出于某种原因,无论我改变什么,我都会在任何有外键的桌子上得到一对一。
这是我对这两个表的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是一个弱势实体。
这是第二张图片的代码。
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 )
);
我将不胜感激任何帮助。感谢。
答案 0 :(得分:23)
一对一没有很好地表示为标准SQL中的第一类关系类型。就像使用连接器表和两个一对多关系实现的多对多一样,SQL中没有真正的“一对一”。
有几种选择:
创建普通的外键约束(“一对多”样式),然后在引用的FK列上添加UNIQUE
约束。这意味着引用列中不得出现多于一个引用值,使其成为一对一可选项。这是一种相当简单且非常宽容的方法,效果很好。
使用可以建模1:m的正常FK关系,并让您的应用确保它在实践中只有1:1。我不建议这样做,添加FK唯一索引只有很小的写入性能下降,它有助于确保数据有效性,查找应用程序错误,并避免混淆其他需要稍后修改架构的人。
创建互惠外键 - 仅当您的数据库支持可延迟的外键约束时才可能。这对代码来说有点复杂,但允许您实现一对一的强制关系。每个实体在唯一列中都有对其他PK的外键引用。其中一个或两个约束必须是DEFERRABLE
和INITIALLY DEFERRED
,或者与SET CONSTRAINTS
调用一起使用,因为您必须推迟其中一个约束检查以设置循环依赖关系。这是一种相当先进的技术,绝大多数应用都不需要。
如果您的数据库支持预先提交触发器,则使用预提交触发器,这样您就可以验证实际插入实体A时是否也插入了一个实体B,反之亦然,并相应地检查更新和删除。这可能很慢并且通常是不必要的,而且许多数据库系统不支持预提交触发器。