1

这是我的数据库结构。 在此处输入图像描述

这是我用来创建表格的脚本

use for_stkoverflow;

CREATE TABLE UserGroup (
    groupid MEDIUMINT NOT NULL AUTO_INCREMENT,
    groupname VARCHAR(100),
PRIMARY KEY (`groupid`)
);

CREATE TABLE User_det (
    Usrid MEDIUMINT NOT NULL AUTO_INCREMENT,
    usrname VARCHAR(255),
    groupid MEDIUMINT,
PRIMARY KEY (`Usrid`),
    Foreign Key (groupid)
        references UserGroup (groupid)
);

CREATE TABLE Accounts (
    acid MEDIUMINT NOT NULL AUTO_INCREMENT,
    groupid MEDIUMINT,
acname VARCHAR(255),
PRIMARY KEY (`acid`),
    Foreign Key (groupid)
        references UserGroup (groupid)
);

create table Ledger (
    ledgerid MEDIUMINT NOT NULL AUTO_INCREMENT,
ledgername VARCHAR(255),
    acid mediumint,
Usrid mediumint,
PRIMARY KEY (ledgerid),
    Foreign Key (acid)
        references Accounts (acid),
Foreign Key (Usrid)
        references User_det (Usrid)
);

我输入了以下数据

在此处输入图像描述

用户组

----------
- groupid groupname
--------------------
- 1   Group1
- 2   Group2

User_det

--------
- Usrid usrname groupid
-----------------------
- 1     User1       1
- 2     User2       2

账户

--------
- acid groupid acname
---------------------
- 1      1      ac1
- 2      2      ac2

账本

--------
-ledgerid ledgername acid Usrid
--------------------------------
- 1         ledger1 1   1
- 2         ledger2 2   2
- 3         ledger3 1   2
- 4         ledger4 2   1

SELECT t1.ledgerid, t1.ledgername,t2.acname,t3.usrname
  FROM Ledger AS t1 
INNER JOIN Accounts AS t2 ON t1.acid = t2.acid
Inner join User_det AS t3 ON t1.Usrid = t3.Usrid;

当前的表结构允许插入违反数据库完整性的数据。

条目 ledgerid 3 无效 ---------------------------------- 因为 acname ac1 属于 User2 所属的 group1不属于。条目分类帐 4 是

无效的

因为 acname ac2 属于 user1 不属于的 group2。

如何防止插入此类数据?

现在在应用程序中,我正在通过 BL 层中的 PHP 进行此检查。

我可以在数据库级别强制执行此操作吗,因为我在不使用 PHP 前端的情况下也从后端进行了一些导入。

4

2 回答 2

2

使用识别关系,类似于:

在此处输入图像描述

注意 UserGroup PK 如何从这个“菱形”的顶部迁移到“两侧”并在“底部”合并。由于底部的一行只包含一个标识顶部的字段,它不能与顶部的多行相关联。

如果您需要其他密钥用于其他目的和/或使上述密钥交替使用(即唯一约束),您仍然可以保留其他密钥...


顺便说一句,更一致地使用命名 - 我建议始终使用带有未缩写表名的单数和前缀 PK 字段......

于 2013-06-23T09:54:25.110 回答
0

旁注:我相信您在问题中提供了太多细节,所以如果我误解了,我深表歉意。

考虑到您使用的 mysql 没有可用于强制执行所需约束的物化视图,我看到了两个选项。
首先,您可以使用触发器[s] 和具有唯一约束的新表来模拟物化视图(它会起作用,但通常很难实现 - 您必须确保正确处理 3 个表上的所有 INSERT/UPDATE/DELETE通过相应的触发器)。
另一种方法是通过在( ) 和( ) 上添加groupIdtoLedger和“额外”唯一约束,并更改 FK in以使其不是in ,而是 to和不是 to ,而是 to来非规范化您的模式。UsersuserId, groupIdAccountsacid,groupIdLedgeruserIdUsersuserId,groupIdacidacid,groupId

我希望这会有所帮助。

于 2013-06-22T19:04:27.123 回答