Mysql SQL强制1:1关系
我有一个关于数据库建模的问题 假设我有一个表用户:Mysql SQL强制1:1关系,mysql,sql,Mysql,Sql,我有一个关于数据库建模的问题 假设我有一个表用户: users ------- id:int name:text 和一个用户的电子邮件: user_emails ----------- id:int user_id:int email:text 我在user\u email.user\u id上添加了一个外键约束,以便它必须与users.id中的有效条目相匹配 但是,这并不保证每个用户都有一封电子邮件 我知道在应用程序级别,我可以很容易地强制执行这一点(即:通过验证表单中的“电子邮件”字段是
users
-------
id:int
name:text
和一个用户的电子邮件:
user_emails
-----------
id:int
user_id:int
email:text
我在user\u email.user\u id
上添加了一个外键约束,以便它必须与users.id
中的有效条目相匹配
但是,这并不保证每个用户都有一封电子邮件
我知道在应用程序级别,我可以很容易地强制执行这一点(即:通过验证表单中的“电子邮件”字段是否已填充等),但我想知道,在数据库(sql)级别,是否有一种强制执行数据完整性的方法?(也就是说,在这种情况下,每个用户都有一封电子邮件?)
谢谢!:) 你必须扭转你的fk
users
-----
id:int
name:text
user_emails_id:int (NOT NULL)
user_emails
-----
id:int
email:text (NOT NULL)
通过这种方式,您可以强制在电子邮件表中有一个关系,如果您将电子邮件值设置为非空,那么您可以强制在列中至少有一个条目
根据评论进行编辑:
要为一个用户实现多封电子邮件,您必须添加一个n:m表
users
-----
id:int
name:text
user_emails_reference_id:int (NOT NULL referencing user_email_references)
user_email_references
-----
id:int
user_email_id:int (NOT NULL Referencing user_emails)
user_id:int (NOT NULL Referencing users)
user_emails
-----
id:int
email:text (NOT NULL)
想必,您希望允许用户有多封电子邮件,但只是为了保证至少有一封。通过执行以下操作,您可以非常接近MySQL约束:
create table Users (
UserId int not null primary key, . . .
. . .
PrimaryEmailId int not null,
constraint fk_PrimaryEmailId foreign key (UserId, PrimaryEmailId) references UserEmails(UserId, UserEmailId)
);
create table UserEmails (
UserEmailId int not null primary key,
UserId int not null,
. . .,
unique (UserId, UserEmailId),
constraint fk_UserEmails_UserId foreign key (UserId) references Users(UserId)
);
这保证:
- 每个用户只有一封主电子邮件
- 每封电子邮件都有一个用户
- 主电子邮件的用户与指定的用户相同
UserEmailId
就足够了。但是,这不能保证用户是相同的
您可能还希望为电子邮件本身添加一个唯一的约束,以便不同的用户不能共享一封电子邮件。只需添加not null,但您的标题所说的与您的帖子所说的不同,您希望强制1:1关系或not null值?。如果需要第一个选项,只需忘记user_emails表,并将该列添加到主表users中,如果需要第二个选项,只需将notnull列,或者最好两者都使用。为什么不使用触发器呢?正如@JuanRuizdeCastilla所建议的那样,只需在您的电子邮件:文本字段中添加NOTNULL约束。NOTNULL约束不足以保证每个用户都有一封电子邮件,请看我的回答。所以,首先插入的是用户电子邮件,然后是用户通过用户电子邮件签名的用户。这是应该的谢谢,在此基础上扩展,我有没有办法允许一个用户有多封电子邮件?如果你允许一个用户有多封电子邮件,那么它就不再是1:1的关系了。。。。但是你可以向它添加一个n:m关系表来实现这个目标,这很有意义:)通过向“用户”表添加一个PrimaryEmail字段,我觉得我在增加开销。系统应该能够通过检查email.person\u id列推断用户存在电子邮件。。。但也许这是最好推迟到应用层的事情?