SQL强制执行1:1关系

时间:2015-10-05 16:21:30

标签: mysql sql

我对数据库建模有疑问。

假设我有一个表用户:

users
-------
id:int
name:text

一个user_emails:

user_emails
-----------
id:int
user_id:int
email:text

我在user_emails.user_id上添加了一个外键约束,使其必须与users.id中的有效条目匹配。

但是,这并不能保证每个用户都会收到电子邮件。

我知道在应用程序级别我可以轻松地执行此操作(即:通过验证表单中的“电子邮件”字段是否已填充等)但我想知道,在数据库(sql)级别是否有办法强制执行数据的完整性? (也就是说,在这种情况下,每个用户都有一封电子邮件?)

谢谢! :)

2 个答案:

答案 0 :(得分:1)

你必须转动你的fk

users
-----
id:int
name:text
user_emails_id:int (NOT NULL)

user_emails
-----
id:int
email:text (NOT NULL)

这样你强制在电子邮件表中建立关系,如果你设置的电子邮件值不为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)

答案 1 :(得分:1)

据推测,您希望允许用户拥有多封电子邮件,但只是为了保证至少有一封电子邮件。通过执行以下操作,您可以非常接近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就足够了。但是,这并不能保证用户是一样的。

您可能还想为电子邮件本身添加唯一约束,因此不同的用户无法共享一封电子邮件。