Как обрабатывать необязательные поля в MySQL? - PullRequest
3 голосов
/ 09 сентября 2009

У меня есть таблица MySQL, которая записывает классифицированные списки Мы не вынуждаем пользователей присоединяться к публикации, и поэтому с этим списком не всегда ассоциируется user_id.

Поэтому мне нужен способ записи электронной почты автора, если он не вошел в систему.

Плохо ли создавать столбец email, который иногда будет пустым, а иногда заполнен?

Или есть лучший способ, который я не понимаю?

Ответы [ 4 ]

6 голосов
/ 09 сентября 2009

Это плохая практика для создания столбца адрес электронной почты, который иногда будет пустым и иногда заполняться?

Это неплохая практика, нет: просто используйте столбец NULL - вот почему они существуют ;-)
См. 12.1.17. Синтаксис CREATE TABLE : в части column_definition запроса создания таблицы вы можете указать NULL или NOT NULL.

Кстати: использование NULL, что буквально означает «нет значения», лучше, чем использование какого-то «невозможного значения», такого как пустая строка: NULL действительно означает «нет значения» и делает вашу точку зрения очевидной - пока пустое Строка может означать ошибку в вашем коде.

И я действительно не вижу другого "логического" пути, на самом деле ...

Обратите внимание, однако, что вам придется обрабатывать значение NULL для электронной почты, конечно же, в коде вашего приложения; -)

2 голосов
/ 09 сентября 2009

это именно то, для чего NULL. но вы уже знали, что, поскольку ваш столбец user_id также иногда будет иметь значение NULL, верно?

1 голос
/ 10 сентября 2009

У меня есть таблица MySQL, в которой записаны классифицированные списки. Мы не вынуждаем пользователей присоединяться к публикации, и поэтому с этим списком не всегда ассоциируется user_id.

Поэтому мне нужен способ записи электронной почты автора, если он не вошел в систему.

Каков бизнес-ключ вашей пользовательской сущности? Или, более прямо: что является вашей пользовательской сущностью? Является ли каждый отдельный адрес электронной почты ключом для сущности «Пользователь», когда некоторые пользователи зарегистрировались, а их адрес электронной почты задан в каком-то профиле, а другие не зарегистрированы и дают адрес электронной почты каждый раз, когда они публикуют? Или у вас есть две разные сущности, RegisteredUser и UnknownPosterWithEmailAddress, их атрибуты хранятся в разных местах?

В последнем случае вы бы использовали NULLable user_id и NULLable поле электронной почты, как вы предложили, но затем запросы типа «для данного сообщения, найти адрес электронной почты, на который должен быть отправлен ответ», будут неудобны например, список всех постов с соответствующими адресами ответов будет выглядеть так:

select post.id, 
   case when post.user_id is not null then user.email
        else post.email end as email
   from post
   left join user on user.id=post.user_id;

Через некоторое время это может стать очень грязным.

Я бы предпочел использовать первый подход: каждая строка в User представляет собой постер dsitinct с уникальным адресом электронной почты, не равным NULL, и суррогатным ключом в качестве внешнего ключа в сообщениях:

create table user(id integer primary key,
                  email text not null unique,
                  is_registered boolean default false);
create table post(id integer primary key,
                  user_id integer not null references user(id),
                  content text);

Если незарегистрированный пользователь вводит адрес электронной почты, вы просматриваете его в таблице пользователей и извлекаете user.id, добавляя новую запись в пользователя, если это необходимо. В результате вы можете ответить на такие вопросы, как: для данного адреса электронной почты, сколько сообщений сделал этот пользователь за последнюю неделю? через поле внешнего ключа, без необходимости сравнивать строки в некотором поле атрибута NULLable.

Когда пользователь выбирает регистрацию, вы можете добавить регистрационные данные либо в самом пользователе, либо в какую-то отдельную таблицу (опять же с user.id в качестве внешнего ключа, некоторые могут утверждать, что логическое поле is_registered тогда фактически избыточно). Дополнительные преимущества:

  • Если он публиковал сообщения ранее под тем же адресом электронной почты, теперь все его старые сообщения автоматически связываются с его новой зарегистрированной личностью.
  • Если пользователь изменяет свой адрес электронной почты в своем профиле, все ответы на старые сообщения его "видят" новый обновленный адрес электронной почты.
1 голос
/ 09 сентября 2009

Я думаю, что изложенный вами подход вполне приемлем. Как указывает longneck, это то, для чего используется NULL в базах данных SQL.

Однако, если вы действительно обеспокоены этим, вы можете сэкономить место (возможно, значительное количество, в зависимости от типа столбца и количества строк), если вы используете столбец user_id для идентификатора пользователя и адрес электронной почты, а затем есть еще один логический столбец, скажем is_email , чтобы определить, какой тип значения хранится в столбце user_id . Это может упростить вам ситуацию, потому что вполне вероятно, что ваше приложение во многих местах не заботится о том, являются ли данные на самом деле user_id или адресом электронной почты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...