Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql SQL强制1:1关系_Mysql_Sql - Fatal编程技术网

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)
);
这保证:

  • 每个用户只有一封主电子邮件
  • 每封电子邮件都有一个用户
  • 主电子邮件的用户与指定的用户相同
注意funky外键关系的使用。引用
UserEmailId
就足够了。但是,这不能保证用户是相同的


您可能还希望为电子邮件本身添加一个唯一的约束,以便不同的用户不能共享一封电子邮件。

只需添加not null,但您的标题所说的与您的帖子所说的不同,您希望强制1:1关系或not null值?。如果需要第一个选项,只需忘记user_emails表,并将该列添加到主表users中,如果需要第二个选项,只需将notnull列,或者最好两者都使用。为什么不使用触发器呢?正如@JuanRuizdeCastilla所建议的那样,只需在您的电子邮件:文本字段中添加NOTNULL约束。NOTNULL约束不足以保证每个用户都有一封电子邮件,请看我的回答。所以,首先插入的是用户电子邮件,然后是用户通过用户电子邮件签名的用户。这是应该的谢谢,在此基础上扩展,我有没有办法允许一个用户有多封电子邮件?如果你允许一个用户有多封电子邮件,那么它就不再是1:1的关系了。。。。但是你可以向它添加一个n:m关系表来实现这个目标,这很有意义:)通过向“用户”表添加一个PrimaryEmail字段,我觉得我在增加开销。系统应该能够通过检查email.person\u id列推断用户存在电子邮件。。。但也许这是最好推迟到应用层的事情?