0

鉴于这些业务规则:

  • 用户有 0 个或多个帐户,并且所有帐户都与单个用户关联
  • 用户拥有 0 个或多个资产,并且所有资产都与单个用户相关联
  • 资产可能与单个帐户相关联。如果将其分配给任何帐户,则该帐户必须属于与资产关联的用户。

假设以下建议的模式:

User
-id

Account
-id
-user_id

Asset
-id
-user_id
-account_id (Nullable)

这种模式似乎存在一个弱点,因为资产可以分配给属于与该资产不同的用户的帐户。这是通过导致更好模式的正常形式之一解决的吗?如果没有通过规范化覆盖它是最好的约束,那么在业务逻辑方面呢?

4

2 回答 2

1

规范化可能处理的唯一部分(如下)是可为空的列。在 Chris Date 的理解中,如果一个列允许 NULL,那么关系就不是 1NF。

如果你试图严格遵循关系模型,我认为你会用断言来处理这个问题。但是大多数 SQL 平台不支持断言。在 SQL 中,我相信您正在寻找类似的东西。我在 PostgreSQL 中对此进行了测试。

create table users (
  user_id integer primary key
);

create table accounts (
  user_id integer not null references users (user_id),
  account_id integer not null unique,
  primary key (user_id, account_id)
);

create table assets (
  user_id integer not null references users (user_id),
  asset_id integer not null unique,
  account_id integer null,
  primary key (user_id, asset_id),
  foreign key (user_id, account_id) references accounts (user_id, account_id)
 );

-- Insert 3 users.
insert into users values (1), (2), (3);

-- User 1 has two accounts, user 2 has 3 accounts, user 3 has none.
insert into accounts values 
(1, 100),
(1, 101),
(2, 102),
(2, 103),
(2, 104);

-- User 1 has 1 asset not assocated with an account.
insert into assets values (1, 200, null);

-- User 1 has 1 asset associated with account 101
insert into assets values (1, 201, 101);

-- User 1 tries to associate an asset with account 102, which doesn't belong to user 1.
insert into assets values (1, 202, 102);
[Fails with foreign key violation]

-- User 2 has two assets not associated with an account.
insert into assets values
(2, 500, null),
(2, 501, null);
于 2012-05-03T23:42:26.923 回答
-1

我建议从表 Asset 中完全删除 account_id 外键。由于 account_id 与您的用户表相关,您可以连接资产和用户,然后执行从用户到帐户的左连接(如果这是 account_id 为主键的表)。如果您从左连接获得结果,则资产链接到一个帐户并且用户是相同的。通过这种方式,您可以强制执行该约束。

希望这会有所帮助,问候

埃尔切

于 2012-04-30T21:15:29.560 回答