ID записи ноль или -1?

Духовность™

Продвинутый новичок
ID записи ноль или -1?

На сегодняшний день в таблице пользователей есть строка, символизирующая пользователя-гостя. Имеет ID = -1

Хочу поле сделать unsigned и соответственно ID этой записи изменить на ноль.

База Mysql.

Опытные господа ученые, чем может грозить ID = 0? Есть какие-то подводные камни в работе с таким primary key?
 

Духовность™

Продвинутый новичок
пришлось уже отказаться. у меня везде примерно такие коды

if ($object->id)

исправлять все лень
 

filipchuk

Новичок
а зачем в таблице пользователей (с реальными логинами, паролями и т.д) хранить "гость"-пользователя, у которого никаких данных нет (кроме придуманного с трудом PK :) )?
 

zerkms

TDD infected
Команда форума
triumvirat
с точки зрения mysql - пофиг, будь там -42 или 0
а у себя в коде сделай для юзера метод user::is_logged_in(), чтобы определять, прошёл юзер аутентификацию, или нет. (естественно выпилив проверку на id)

-~{}~ 20.06.10 20:16:

filipchuk
затем, что в миллион раз проще работать и писать читаемый код, когда между неавторизованным и авторизованным пользователями нет никакой разницы. (а между ними и вправду, с точки зрения программирования, разницы никакой нет - в обоих вариантах это просто клиент)
 

Духовность™

Продвинутый новичок
а у себя в коде сделай для юзера метод user::is_logged_in(), чтобы определять, прошёл юзер аутентификацию, или нет. (естественно выпилив проверку на id)
м... не понятно, зачем выпиливать эту проверку.

Как ты сказал, "между неавторизованным и авторизованным пользователями нет никакой разницы". Поэтому я каждый раз создаю объект пользователя, вне зависимости от того, является ли он гостем или нет. Если он гость, то я тупо запрашиваю запись с ID = -1:

PHP:
protected function loadCurrentUser()
{
    $user_mapper = new Module_User_Mapper_User();

    if (!empty($this->request->getCookie()->id_user) &&
        !empty($this->request->getCookie()->user_hash))
    {
        $this->current_user = $user_mapper->findByLoginMd5($this->request->getCookie()->id_user,
                                                           $this->request->getCookie()->user_hash,
                                                           Base_Registry::getInstance()->config->user_cookie_salt
                                                          );

        // Если у пользователя невалидные cookie, убиваем их.
        if (!is_object($this->current_user) || $this->current_user->getId() == 0)
        {
            $this->destroyCurrentUser();
        }
        // иначе обновляем информацию о пользователе
        else
        {
            $user_mapper->updateActualInfo($this->current_user);
        }
    } // гость
    else
    {
        // думаю, может лезть в базу за анонимным пользователем
        // каждый раз не стоит, может сериализовать объект анонимного пользователя? 
        $this->current_user = $user_mapper->findById(-1);
    }
}
т.е. в базу приходится лезть постоянно.
 

filipchuk

Новичок
разве наличие в таблице записи для "гостя" это необоходимое условие, чтоб они были одного типа (класса)? например, у меня проверка, или пользователь гость примерна такая: $user->getId() === NULL, тоесть при получении свойств объекта маппер вернул нулевой результат, поэтому $this->_id === NULL
а в целом конечно же, и авторизированный, и "гость" являются экземплярами класса User
 

fixxxer

К.О.
Партнер клуба
я бы сделал как то иначе

class UserFactory {
static function constructById
static function constructByCookie
...
}

abstract class User

class Guest extends User
class Member extends User

и в гесте вообще базу не юзал, нафига оно там.
 

filipchuk

Новичок
создается доменный объект
потом маппер делает запрос в БД
если данные найдены, они устанавливаются как свойства для объекта
возвращается доменный объект
примерный код:
$model = new Object();
$options = $this->find($id);//получение данных из БД
if ($options) {
$model->setOptions($options)
}
return $model;


но в случае с юзером, маппер ищет пользователя не в БД, а в сессии
 

fixxxer

К.О.
Партнер клуба
ну и id был бы у гостя человеческий null а не это извращение, соответственно скажем message от гостя имел бы user_id=null etc
 

Духовность™

Продвинутый новичок
abstract class User

class Guest extends User
class Member extends User
красиво, но в моем случае бесполезно. Разница между гостем и пользователем - в ID. И всё.

-~{}~ 20.06.10 14:11:

как может сущность иметь ИД=null? NULL - это нет значения. У гостя ест свой ID, конкретное значение, которое можно записать в БД.
 

zerkms

TDD infected
Команда форума
ну и id был бы у гостя человеческий null а не это извращение, соответственно скажем message от гостя имел бы user_id=null etc
PK = null ты не сможешь сделать. да и user_id IS NULL не более человечный, чем user_id = 0
более того, такой подход заставляет для пользователя "zerkms" и для пользователя "guest" делать разные запросы на получение комментов.

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

filipchuk

Новичок
fixxxer
кстати, с фабрикой мне нравится вариант, надо взять на вооружение

triumvirat:
по поводу id у гостя должно конкретное значение, отличное от NULL - в таком случае, все гости - это один пользователь, что не есть логично. Значение NULL подходит более правильно, так как ID пользователя не определен, и множество разных гостей имею неопределенный PK (равный NULL)
 

fixxxer

К.О.
Партнер клуба
>> PK = null ты не сможешь сделать

а зачем? в юзерах вообще такой записи нет, зачем она там. а foreign key вполне может иметь значение null, как отсутствие ссылки.

-~{}~ 20.06.10 16:16:

Код:
template1=# create table users(id int  primary key);
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "users_pkey" for table "users"
CREATE TABLE
template1=# create table comments(id int primary key, user_id int, foreign key (user_id) references users(id) );
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "comments_pkey" for table "comments"
CREATE TABLE
template1=# insert into users values(1),(2);
INSERT 0 2
template1=# insert into comments values (1,1),(2,null),(3,2);
INSERT 0 3
template1=# select comments.id, users.id from comments left join users on (users.id = comments.user_id);
 id |   id   
----+--------
  1 |      1
  2 | (null)
  3 |      2
(3 rows)
что не так?
 

zerkms

TDD infected
Команда форума
fixxxer
тогда для гостей и негостей придётся делать разные обработчики.

например - выборка комментариев с авторами.
1. придётся LEFT JOIN вместо INNER
2. придётся во время вывода проверять, кого мы выбрали

все гости - это один пользователь, что не есть логично
почему нет? гость - это пользователь, который не прошёл аутентификацию. чем такой пользователь принципиально отличается от пользователя, который ввёл свой один и тот же логин/пасс на 3 разных машинах?
 
Сверху