powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Посоветуйте, как организовать таблицу и индексы
9 сообщений из 9, страница 1 из 1
Посоветуйте, как организовать таблицу и индексы
    #39113371
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Делаю БД для веб-сайта, в котором в том числе будет осуществляться регистрация сессий посетителей.
Особенности сайта таковы, что под одним логином может быть только одна активная сессия; если при авторизации пользователя под этими учетными данными уже есть ранее созданная активная сессия, она должна быть закрыта.
У меня будут использоваться следующие запросы:
Код: sql
1.
2.
3.
4.
5.
select * from SESSION where ID = ?;
select * from SESSION where SESSION = ?;
select * from SESSION where USERNAME = ? and ACTIVE = 1;
update SESSION set ACTIVE = 0 where USERNAME = ? and ACTIVE = 1;
insert into SESSION (USERNAME, ACTIVE) values (?, 1);



Посоветуйте структуру таблицы и индексы?
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
1 - CREATE TABLE SESSION (
	ID INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
	SESSION VARCHAR(40) NOT NULL,
	ACTIVE ENUM('0','1') NOT NULL,
	USERNAME VARCHAR(40) NOT NULL,
	PRIMARY KEY (ID),
	UNIQUE INDEX SESSION (SESSION),
	INDEX USERNAME (USERNAME)
);

2 - CREATE TABLE SESSION (
	ID INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
	SESSION VARCHAR(40) NOT NULL,
	ACTIVE INT(1) NULL,
	USERNAME VARCHAR(40) NOT NULL,
	PRIMARY KEY (ID),
	UNIQUE INDEX SESSION (SESSION),
	UNIQUE INDEX USERNAME (ACTIVE, USERNAME)
);

3 - CREATE TABLE SESSION (
	ID INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
	SESSION VARCHAR(40) NOT NULL,
	ACTIVE INT(1) NULL,
	USERNAME VARCHAR(40) NOT NULL,
	USERNAME_ACTIVE VARCHAR(40) NULL,
	PRIMARY KEY (ID),
	UNIQUE INDEX SESSION (SESSION),
	UNIQUE INDEX USERNAME (USERNAME_ACTIVE),
	INDEX USERNAME (USERNAME)
);



Вариант 1 - это обычная БД, которую обычно советуют в разных статьях.

Вариант 2 - с MSSQL я не работал уже довольно давно и могу заблуждаться, но ЕМНИП в нем можно создать уникальный индекс, который тем не менее будет игнорировать значения с NULL. Если в MySQL есть что-то подобное, то мне это кажется хорошим решением.

Вариант 3 - будет дополнительное поле USERNAME_ACTIVE по которому будет создан уникальный индекс; в этом поле буде указываться USERNAME для активных сессий и NULL или ID для неактивных сессий. И соответственно update-запрос нужно будет немного переделать (set ACTIVE=0, USERNAME_ACTIVE=ID).

________________________
Мы смотрим с оптимизмом...
...в оптический прицел.
...
Рейтинг: 0 / 0
Посоветуйте, как организовать таблицу и индексы
    #39115633
Гуляев Гоша
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я считаю что правильней будет организовать так (я по крайней мере так делаю):
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
TABLE session (
      id         INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
      sessKey    CHAR(32)
)

TABLE session_active (
      id         INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
      sessKey    CHAR(32),
      lastCheck  INT UNSIGNED NOT NULL
)

TABLE userAuth (
      id         INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
      sessID     INT UNSIGNED NOT NULL,
      userID     INT UNSIGNED NOT NULL,
      FOREIGN KEY sessID REFERENCES session(id) ON DELETE CASCADE ON UPDATE CASCADE,
      FOREIGN KEY userID REFERENCES users(id) ON DELETE CASCADE ON UPDATE CASCADE
)


В этом случае в session у меня хранится архив сессий (на случай там чего-то когда-то узнать), в session_active хранятся только активные сессии, которые удаляются по параметру lastCheck (в случае если пользователь минут 5 допустим не был на сайте), а в userAuth связь активных сессий с авторизованными пользователями.

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

В целом идея такая. Плюс в том, что поиск активной сессии не будет замедляться со временем, так как таблицы session_active и userAuth не разрастаются.
...
Рейтинг: 0 / 0
Посоветуйте, как организовать таблицу и индексы
    #39115969
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гуляев ГошаПлюс в том, что поиск активной сессии не будет замедляться со временемИ сильно он у вас замедлялся?
...
Рейтинг: 0 / 0
Посоветуйте, как организовать таблицу и индексы
    #39115997
Гуляев Гоша
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Перешёл на такую схему после года работы веб приложения. Тогда замедление стало проявляться, так как проверка информации из таблицы с сессиями при каждом обращении к страничке происходит. На тот момент кол-во сессий в таблице было около 400 000.

Понимаю что это не много, но и железо на котором работает сервер у меня обычный "писюк". На котором кроме собственно БД крутится ещё и почта, сайты и самба.
...
Рейтинг: 0 / 0
Посоветуйте, как организовать таблицу и индексы
    #39124536
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пришел к такой схеме:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
CREATE TABLE `AUTH_SESSION` (
	`ID` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'Идентификатор записи.',
	`KEY` VARCHAR(100) NOT NULL COMMENT 'Ключ авторизации.',
	`SOURCE` VARCHAR(80) NOT NULL COMMENT 'Провайдер авторизации.',
	`USERNAME` VARCHAR(80) NOT NULL COMMENT 'Имя пользователя.',
	`UID` VARCHAR(80) NOT NULL COMMENT 'Идентификатор пользователя.',
	`SID` VARCHAR(80) NOT NULL COMMENT 'Идентификатор сессии.',
	`IP` VARCHAR(20) NOT NULL COMMENT 'IP-адрес посетителя при авторизации.',
	`UA` VARCHAR(200) NULL DEFAULT NULL COMMENT 'UserAgent посетителя при авторизации.',
	`HDR` TEXT NULL COMMENT 'Заголовки посетителя при авторизации.',
	`STATUS` ENUM('active','inactive','closed','expired','invalid') NOT NULL COMMENT 'Статус сессии.',
	`STARTED` DATETIME NOT NULL COMMENT 'Дата и время начала сессии.',
	`EXPIRED` DATETIME NULL DEFAULT NULL COMMENT 'Дата и время прекращения сессии.',
	`REASON` VARCHAR(200) NULL DEFAULT NULL COMMENT 'Причина прекращения сессии.',
	`NEW_ID` INT(10) UNSIGNED NULL DEFAULT NULL COMMENT 'Ссылка на новую сессию, которая прервала настоящую сессию.',
	PRIMARY KEY (`ID`),
	UNIQUE INDEX `KEY` (`KEY`),
	INDEX `NEW` (`NEW_ID`),
	INDEX `USERNAME` (`SOURCE`, `UID`, `STATUS`),
	CONSTRAINT `FK_AUTH_SESSION_NEW` FOREIGN KEY (`NEW_ID`) REFERENCES `AUTH_SESSION` (`ID`)
)
COMMENT='Список сессий пользователей.'
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;

CREATE TABLE `AUTH_ACTIVE` (
	`ID` INT(10) UNSIGNED NOT NULL COMMENT 'Идентификатор сессии.',
	`KEY` VARCHAR(100) NOT NULL COMMENT 'Ключ авторизации.',
	`ALIVE` TIMESTAMP NULL DEFAULT NULL COMMENT 'Временная отметка последней активности сессии.',
	PRIMARY KEY (`ID`) USING HASH,
	UNIQUE INDEX `KEY` (`KEY`) USING HASH
)
COMMENT='Список активных сессий.'
COLLATE='utf8_general_ci'
ENGINE=MEMORY
;



Основная таблица сессий это AUTH_SESSION, в ней хранится вся информация по сессиям и пользователям.
Кроме этого создана memory-таблица AUTH_ACTIVE, в которой хранится информация только по активным сессиям (с индексами HASH для быстрой выборки).
Кроме того в memory-таблице хранится поле ALIVE; это специальное поле, которое обновляется при любой активности пользователя на сайте. А memory - чтобы частые операции обновления не писать в БД.

Не посоветуете, что улучшить?
...
Рейтинг: 0 / 0
Посоветуйте, как организовать таблицу и индексы
    #39124542
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.
Код: sql
1.
`IP` VARCHAR(20) NOT NULL COMMENT 'IP-адрес посетителя при авторизации.',

Для хранения обычного ip-адреса вполне достаточно 4-байтового поля unsigned int.


Alibek B.
Код: sql
1.
`HDR` TEXT NULL COMMENT 'Заголовки посетителя при авторизации.',

Не рекомендую использовать тип TEXT без нужды, если можно обойтись VARCHAR-ом. Для некоторых типов запросов наличие в выборке BLOB/TEXT-полей автоматически означает создание временного файла на диске.
Alibek B.
Код: sql
1.
UNIQUE INDEX `KEY` (`KEY`),

Слово KEY является зарезервированным словом. И хотя формально его можно употреблять в правильных кавычках, лучше этого не делать. Кроме того, не стоит называть разные объекты БД одинаковым именем.
Alibek B.
Код: sql
1.
`REASON` VARCHAR(200) NULL DEFAULT NULL COMMENT 'Причина прекращения сессии.',

Эти причины могут быть произвольно-разнообразными?
Если нет (т.е. если это ограниченный набор вариантов), то лучше вынести это в отдельную таблицу-справочник, а тут оставить ссылку на нее.
...
Рейтинг: 0 / 0
Посоветуйте, как организовать таблицу и индексы
    #39124622
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoftДля хранения обычного ip-адреса вполне достаточно 4-байтового поля unsigned int.
Возможно я потом заменю на binary.
Но пока что я не разобрался, как передавать параметры подобного типа (в параметрических запросах) через PDO.
Кроме того есть IPv6.

miksoftНе рекомендую использовать тип TEXT без нужды, если можно обойтись VARCHAR-ом.
Понял. Вынесу в отдельную таблицу.

miksoftСлово KEY является зарезервированным словом
Я знаю. В запросах я всегда использую кавычки для имен объектов.

miksoftЭти причины могут быть произвольно-разнообразными?
Да, это произвольный текст.
...
Рейтинг: 0 / 0
Посоветуйте, как организовать таблицу и индексы
    #39125748
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.Но пока что я не разобрался, как передавать параметры подобного типа (в параметрических запросах) через PDO.как, как... да как обычные параметры
Код: sql
1.
inet_aton(:parameter)
...
Рейтинг: 0 / 0
Посоветуйте, как организовать таблицу и индексы
    #39125992
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я не про int, а про binary/varbinary.
Сейчас уже точно не помню, но были какие-то у меня сложности с тем, чтобы такие параметры использовать в PDO.
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Посоветуйте, как организовать таблицу и индексы
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]