如何在Mysql中对不相关的表实施外键约束?
这是我的数据库结构。 这是我用来创建表的脚本如何在Mysql中对不相关的表实施外键约束?,mysql,database-design,foreign-key-relationship,data-integrity,Mysql,Database Design,Foreign Key Relationship,Data Integrity,这是我的数据库结构。 这是我用来创建表的脚本 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, usr
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
用户数据
--------
- 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;
当前表结构允许插入违反DB完整性的数据
条目3无效
----------------------------------因为acname ac1属于User2不属于的group1。第4项是
无效的
因为acname ac2属于User1不属于的group2
如何防止插入此类数据
现在,在应用程序中,我通过PHP在BL层中执行此检查
我是否可以在DB级别强制执行此操作,因为我也可以在不使用PHP前端的情况下从后台进行导入。旁注:我相信您在问题中提供了太多细节,因此如果我误解了,我很抱歉 考虑到您使用的mysql没有可用于实施所需约束的物化视图,我看到了两个选项。
首先,您可以使用触发器和具有唯一约束的新表来模拟物化视图(它可以工作,但通常很难实现-您必须确保3个表上的所有INSERT/UPDATE/DELETE都由相应的触发器正确处理)。
另一种方法是通过将
groupId
添加到Ledger
,并对Users
(userId,groupId
)和Accounts
(acid,groupId
)添加groupId
),以及更改Ledger
中的FKs,从而在Users
中不引用userId
,来反规范化模式,但是对于userId,groupId
,而不是acid
,而是acid,groupId
我希望这会有所帮助。使用识别关系,类似于:
请注意,用户组PK是如何从“菱形”的顶部向下迁移到“两侧”并在“底部”合并的。由于底部的一行只包含一个标识顶部的字段,因此它不能与顶部的多行相关
如果出于其他目的需要其他关键点,您仍然可以保留这些关键点和/或将上述关键点替换(即唯一约束)
顺便说一句,更一致地使用命名-我建议始终使用单数并在PK字段前面加上未命名的表名