【发布时间】:2013-11-16 20:07:45
【问题描述】:
在我的数据库中,我有客户、经理和客户的表格。客户和经理都有帐户。 Customer-Account 和 Manager-Account 之间存在一对一的关系。我在客户和经理表中都有 AccountID 作为 FK。问题是,现在没有什么可以阻止帐户同时与经理和客户绑定。我应该如何设计这种关系或者我应该如何实现这个东西。
【问题讨论】:
标签: sql foreign-keys relationship one-to-one
在我的数据库中,我有客户、经理和客户的表格。客户和经理都有帐户。 Customer-Account 和 Manager-Account 之间存在一对一的关系。我在客户和经理表中都有 AccountID 作为 FK。问题是,现在没有什么可以阻止帐户同时与经理和客户绑定。我应该如何设计这种关系或者我应该如何实现这个东西。
【问题讨论】:
标签: sql foreign-keys relationship one-to-one
用帐户类型标记每个帐户。对于给定帐户,此列只能有一个值。
CREATE TABLE Accounts (
account_id INT PRIMARY KEY,
account_type TINYINT NOT NULL,
UNIQUE KEY (account_id, account_type)
);
然后将每种类型的帐户都限制为一种特定的帐户类型。
CREATE TABLE Managers (
account_id INT PRIMARY KEY,
account_type TINYINT NOT NULL DEFAULT 1,
FOREIGN KEY (account_id, account_type)
REFERENCES Accounts(account_id, account_type)
);
CREATE TABLE Customers (
account_id INT PRIMARY KEY,
account_type TINYINT NOT NULL DEFAULT 2,
FOREIGN KEY (account_id, account_type)
REFERENCES Accounts(account_id, account_type)
);
这建立了默认值,但不能防止错误数据,例如在 Managers 中使用 account_type 4 创建一行。要建立该约束,您可以使用触发器、CHECK 约束或外键只有一个值的小表。
你的评论:
其工作方式是首先在 Account 中插入一行,然后选择一个 account_type:
INSERT INTO Accounts (account_id, account_type) VALUES (123, 1);
现在这一行只能被 account_type=1 的行引用。
如果您只向具有 account_type=1 的经理插入行,而从不向具有该 account_type 的客户插入行,则 Accounts 中的行只能由经理引用。
-- First example: works fine
INSERT INTO Managers (account_id, account_type) VALUES (123, 1);
-- Second example: wrong account_type for the Customers table
INSERT INTO Customers (account_id, account_type) VALUES (123, 1);
-- Third example: foreign key error, because Account 123 does not have account_type=2
INSERT INTO Customers (account_id, account_type) VALUES (123, 2);
客户和经理有自己的主键
这没关系。我在示例中使用 account_id 作为主键,但这是可选的。如果您有不同的主键列,它仍然有效。例如:
CREATE TABLE Managers (
id INT AUTO_INCREMENT PRIMARY KEY,
account_id INT NOT NULL,
account_type TINYINT NOT NULL DEFAULT 1,
FOREIGN KEY (account_id, account_type)
REFERENCES Accounts(account_id, account_type)
);
【讨论】:
Customers 和Managers 表不应该是Customer_Accounts 和Manager_Accounts 吗?否则,客户和经理怎么可能拥有多个帐户?