Plain property vs OneToOne
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 17.05.08 07:25
Оценка: 2 (1) +1
Здравствуйте, <Аноним>, Вы писали:

А>Само собой не всегда они нужны сразу одной группой. Я бы хотел чтобы кто-нибудь привел действительно веские причины почему данные которые не всегда нужны нужно отделять в отдельную таблицу/класс. Как я уже сказал, email клиента не всегда нужен, что же, его отделять в отдельную таблицу/класс?

Различие принципиальное, вам говорили о нем выше... попробую пожевать сильнее:
  1. С одной стороны, есть некоторый набор свойств сущности, которыми независимо от обстоятельств обладает каждый представитель: к примеру, login/password, ФИО, паспортные данные и т.п. есть у каждого пользователя — если свойства пользователя дополнили полем e-mail, значит предполагается, что большинство пользователей пользуются электронной почтой.
  2. С другой стороны, есть некоторый набор свойств только некоторых представителей сущности: далеко не у каждого пользователя есть семья, машина и т.п. В этом случае использовать one-to-one — значит правильно класть колбасу на хлеб. Если расширяем основную таблицу, то имеем море записей с NULL, а значит познаем все прелести троичной логики в коде, который работает в основном по двоичной логике.

Рассмотрим на примере. В случае one-to-one предикат отсутствия данных о семье:
user.Family == null
- нет семьи, а значит нет записи в соответствующей таблице, а значит на уровне кода тоже ничего нет, а значит не генерируется никаких лишних выборок SQL-запросом — если нет данных о семье, объект Family попросту не будет создан. А в случае плоской таблицы предикат что-то вроде:
user.HasFamily
- вводится дополнительное NotNull-свойство, это еще более или менее нормально, а то ведь обычно происходит примерно такая бяка:
user.WifeHusbandName is DbNull
При этом происходит происходит практически SQL-мегазапрос типа
select * from Users
, то есть даже для пользователей без семей создаются структуры с DbNull-ами, а потому определение факта отсутствия данных о семье плавно переносится в код — дизайн достойный сожаления. Кроме того, во втором случае очень неудобно кодирование ленивой загрузки данных о семье.

Еще раз о различии user.Email и User.Family:
  1. Истинность:
    Users.email is null
    обычно означает факт отсутствия данных об электронной почте пользователя (то есть пока не знаем адрес, но скоро узнаем и укажем), предполагается, что это не должно означать то, что у пользователя нет электронной почты, но даже если и так, то это не страшно, если бизнес-логика приложения не требует различать эти факты. И это хорошо.
  2. Если результат запроса:
    select
        count(*)
    from UserFamilies
        join Users on
            UserFamilies.userId = Users.id
    where
        Users.id = @userId
    равен 0, это означает факт отсутствия семьи пользователя. Если > 0, имеем факт наличия семьи (быть может и не одной). То есть четкая определенность. Примечательно, что подобный запрос очень удобно кодируется для ленивой загрузки. И это все тоже хорошо.

    А вот что означает в случае плоской таблицы это:
    Users.WifeHusbandName is null
    То ли, что у пользователя нет семьи, то ли что просто пока имя супруги/супруга не известно. Эта неопределенность в большинстве случаев не есть хорошо, это есть очень плохо.

По теме можно прочитать вот это:
NULL, трехзначная логика и неопределенность в SQL: критика критики Дейта, Клод Рубинсон
Критика критики критики Дейта
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.