2015-10-05 6 views
1

У меня вопрос относительно моделирования базы данных.SQL принудительное отношение 1: 1

Давайте предположим, что у меня есть пользователи таблицы:

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

И один USER_EMAILS:

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

добавить ограничение внешнего ключа на user_emails.user_id таким образом, что он должен соответствовать правильный вход в users.id.

Однако это не гарантирует, что у каждого пользователя будет электронное письмо.

Я знаю, что на уровне приложения я могу легко обеспечить соблюдение этого правила (т.е.: проверяя, что поле «email» в форме заполнено и т. Д.), Но мне было интересно, на уровне базы данных (sql) есть способ обеспечения полноты данных? (То есть в этом случае у каждого пользователя есть электронное письмо?)

Спасибо! :)

+1

просто добавьте не null, но вы говорите, что название отличается от вашего сообщения, говорится, что вы хотите применить соотношение 1: 1 или не нулевые значения. Если вы хотите первый вариант, просто забудьте таблицу user_emails и добавьте этот столбец в своих пользователей первичной таблицы, если вы хотите второй, просто поместите не пустой столбец или лучше используйте оба. –

+0

Почему бы не использовать триггер? –

+0

Как подскажите @JuanRuizdeCastilla просто добавьте ограничение NOT NULL на ваше электронное письмо: текстовое поле. – narendra

ответ

1

Вы должны повернуть вокруг

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

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

этого путем вы вынуждаете иметь отношение в электронном столе, и если вы установите значение электронной почты не нулевым, то вы вынуждаете иметь по крайней мере, запись в колонке

Редактировать на основе комментария: для достижения нескольких сообщений для пользователя, вы должны добавить: 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) 
+0

, поэтому первая вставка - user_emails, а следующая - пользователи, в которые входят пользователи user_emails.Это должно работать –

+0

Спасибо, расширившись на этом, есть ли способ разрешить несколько электронных писем для пользователя? – MrD

+0

, если вы разрешаете mulitple emials для пользователя, тогда это уже не отношение 1: 1 .... но вы можете добавить к нему таблицу отношений m: 0, чтобы достичь этой цели. – deterministicFail

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. Однако это не гарантирует, что пользователь будет таким же.

Возможно, вы также захотите добавить уникальное ограничение для самого электронного письма, поэтому разные пользователи не могут использовать одно электронное письмо.

+0

спасибо, это имеет смысл :) Дело в добавлении поле PrimaryEmail в таблицу «user». Я чувствую, что добавляю лишние накладные расходы. Система должна иметь возможность сделать вывод о том, что электронное письмо существует для пользователя, проверяя столбец email.person_id ... Но, может быть, это то, что лучше всего отложить до уровня приложения? – MrD

Смежные вопросы