|
8 Кб |
|
| Не соображу возможны-ли какие-нибудь проблемы если так и оставить эти CONSTRAINT ... FOREIGN KEY .....
CREATE TABLE IF NOT EXISTS `files` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
`msgs_id` INT UNSIGNED NOT NULL ,
`cmnts_id` INT UNSIGNED NULL,
`u_id` INT UNSIGNED NOT NULL ,
`last_dt` TIMESTAMP NOT NULL,
`first_dt` TIMESTAMP NOT NULL,
`fname` VARCHAR(100) NOT NULL ,
`u_name` TINYTEXT NULL,
`dop` VARCHAR(255) NULL,
PRIMARY KEY (`id`) ,
INDEX `u_id` (`u_id` ASC) ,
INDEX `msgs_id` (`msgs_id` ASC) ,
INDEX `cmnts_id` (`cmnts_id` ASC) ,
CONSTRAINT `u_id`
FOREIGN KEY (`u_id` )
REFERENCES `users` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `msgs_id`
FOREIGN KEY (`msgs_id` )
REFERENCES `msgs` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `cmnts_id`
FOREIGN KEY (`cmnts_id` )
REFERENCES `cmnts` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = MyISAM;
|
интересно всегда-ли MyISAM будет просто игнорировать эти CONSTRAINT ... FOREIGN KEY .....
просто с ними картинки (прикрепил) получаются понятнее :)
Но основной вопрос вот в чём , хранить или не хранить в таблицах с сообщениями имена зарегистрированных пользователей.
Структура например примерно такая как на картинке ( почему-то не хочется делать вместо msgs и cmnts всего одну таблицу , в msqs пишут только зарегистрированные,
в противовес этому пришлось сделать два FULLTEXT msg. (как я понял не бывает один FULLTEXT индекс по двум таблицам ) + (по сообщениям в msgs ещё своя отдельная навигация и не приходится утяжелять запросы ещё одним условием)
Например если в msgs достаточно хранить только id пользователей а выводить уже вместе с именами, то как быть в cmnts и files ? Добавлять-ли везде имена или создать таблицу незарегистрированных ? Как должно быть оптимальнее ? | |
|
|
|
|
|
|
|
для: heed
(24.09.2010 в 12:57)
| | >Но основной вопрос вот в чём , хранить или не хранить в таблицах с сообщениями имена зарегистрированных пользователей.
> почему-то не хочется делать вместо msgs и cmnts всего одну таблицу , в msqs пишут только зарегистрированные,
аргумент слабый... Или в зависимости от того, зарегистрирован пользователь или нет, подключение к MySQL идет от разных эккаунтов?
>в противовес этому пришлось сделать два FULLTEXT msg. (как я понял не бывает один FULLTEXT индекс по двум таблицам ) + (по сообщениям в msgs ещё своя отдельная навигация и не приходится утяжелять запросы ещё одним условием)
Главное, чтоб индекс мог быть построен подходящий.
>Например если в msgs достаточно хранить только id пользователей а выводить уже вместе с именами, то как быть в cmnts и files ? Добавлять-ли везде имена или создать таблицу незарегистрированных ?
и чем тогда одни будут отличаться от других? | |
|
|
|
|
18.3 Кб |
|
|
для: Trianon
(24.09.2010 в 15:48)
| | >и чем тогда одни будут отличаться от других?
там было-бы у всех id=NULL и тёзки в большом колличестве :)
Вообще-то да. В таблице online незарегистрированныv наверное размещать надо
>Главное, чтоб индекс мог быть построен подходящий.
Это да. Таблицу комментов всё-таки убрал, хоть и местами колличество запросов не уменьшилось, стало просторнее.
// прикрепил новую картинку , `ban` это я так назвал 'online' :) | |
|
|
|
|
|
|
|
для: Trianon
(24.09.2010 в 15:48)
| | Забуксовал на том что не выберу как лучше ссылаться на сообщения основной группы.
Вот например такие две таблицы.
--DROP TABLE IF EXISTS `users`, `msgs`, `files`, `tech_msgs`, `ban`, `tmp_msqs`;
-- -----------------------------------------------------
-- Table `users`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `users` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
`perm` SMALLINT UNSIGNED NOT NULL DEFAULT 0 ,
`last_dt` TIMESTAMP NOT NULL ,
`first_dt` TIMESTAMP NOT NULL ,
`pswrd` CHAR(32) NOT NULL DEFAULT '' ,
`u_name` TINYTEXT NOT NULL ,
`img` TINYTEXT NULL DEFAULT NULL ,
`dop` TEXT NULL DEFAULT NULL ,
PRIMARY KEY (`id`) )
ENGINE = MyISAM
DEFAULT CHARACTER SET = utf8;
-- -----------------------------------------------------
-- Table `msgs`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `msgs` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
`to_id` INT UNSIGNED NULL DEFAULT NULL ,
`hide` TINYINT UNSIGNED NOT NULL DEFAULT 0 ,
`razd` SMALLINT UNSIGNED NOT NULL DEFAULT 0 ,
`u_id` INT UNSIGNED NOT NULL DEFAULT 0 ,
`last_dt` TIMESTAMP NOT NULL ,
`first_dt` TIMESTAMP NOT NULL ,
`u_name` TINYTEXT NULL DEFAULT NULL ,
`m_name` TINYTEXT NULL DEFAULT NULL ,
`msg` TEXT NULL DEFAULT NULL ,
`info` TEXT NULL DEFAULT NULL ,
PRIMARY KEY (`id`) ,
FULLTEXT INDEX `msg` (`m_name` ASC, `msg` ASC) ,
INDEX `to_id` (`to_id` ASC) ,
INDEX `u_id` (`u_id` ASC) ,
CONSTRAINT `to_id`
FOREIGN KEY (`to_id` )
REFERENCES `msgs` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `u_id`
FOREIGN KEY (`u_id` )
REFERENCES `users` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = MyISAM
DEFAULT CHARACTER SET = utf8;
|
Заполнить можно выполнив в phpmyadmin например сразу такое
INSERT INTO `users` ( `id`, `perm`, `first_dt`, `pswrd`, `u_name`)
VALUES (NULL, 0, NULL, '', 'Гость'),
(NULL, 65535, NULL, MD5('admin'), 'admin');
SET @x=0;
INSERT INTO `msgs` (`id`, `to_id`, `u_id`, `first_dt`, `u_name`, `m_name`, `msg`)
SELECT (@x:=@x+1), IF((@x&15)-1, @x-((@x-1)&15), NULL),
(@x&1)+1, NULL , IF((@x&1), 'admin', 'Гость') , `name` ,
CONCAT( `description` , '\n\n', `example` , '\n\n', `url` )
FROM `mysql`.`help_topic`;
|
На основных страницах всё понятно например как
SELECT `id`, `to_id`, `u_id`, `u_name`, `m_name`, `msg`
FROM `msgs`
WHERE ISNULL(`to_id`)
LIMIT 5,5;
| урезано чем-то вроде INSERT( msg, (LOCATE(' ', msg, 155)), -1
, CONCAT(' ...<h5><a href="./?' . $q1s . '_', id, '">читать дальше</a></h5>'))
Навигация просто по порядковым номерам.
//На остальных страницах с комментариями, только такие-же куски этих сообщений, с такими-же ссылками.(Ссылки на комментарии так и остаются с id)
Но если ссылка например /?id=xx с id сообщения, то навигацию, на странице просмотра одного сообщения, всмысле навигацию по таким-же отдельным страницам, приходится делать запрашивая два раза , c бОльшими и c мЕньшими id , union например применять приходится.
Если /?id=порядковый номер, просто высчитываются порядковые номера других страниц, запрашивается только сообщение,
Но тут чтобы сделать как на страницах php-мануала ссылки "Предыдущая","следующая" с описаниями, тоже надо делать запрос.
Например с простым LIMIT выбрать названия предыдущего текущего и следующего.
вижу только две причины почему так стараются не делать: поисковые роботы, и сдвиг номеров при удалении старых сообщений.
Но часто таких удалений не предвидится.
Или ещё есть другие причины почему такое не применяется?
Возможно просто снова придумываю велосипед.
// и нужно-ли делать индекс там где TIMESTAMP, если сортировка (или группировку лучше применять) по TIMESTAMP. | |
|
|
|
|
|
|
|
для: heed
(25.09.2010 в 18:52)
| | почему union а не join ?
практицки ниасилил. | |
|
|
|
|
|
|
|
для: Trianon
(25.09.2010 в 19:40)
| | Я о таком примерно:
SELECT x.id, x.m_name, y.id, y.m_name
FROM `msgs` x , `msgs` y
WHERE ISNULL( x.to_id ) AND ISNULL( y.to_id ) AND x.id <401 AND y.id >401
GROUP BY x.id DESC
LIMIT 5
|
join кроме такого не смог прикрутить, не пойму по чему можнт быть связано.
Что ни делал, выбирает одинаковыми или предшествующие или последующие записи, DISTINCT тоже вроде не то. | |
|
|
|
|
|
|
|
для: heed
(25.09.2010 в 20:53)
| | про висящие по group by поля я тут пишу, чтоб не соврать, в среднем раз в пару месяцев, все три с лишним года.
Я не хочу, и не буду смотреть запросы, неоднозначные по group by.
в конце концов чтоб сервер сделать небрезгливым - достаточно выключить режим only_full_group_by
у меня иного просто нет. От селектов с кривыми GROUP BY меня почти физически тошнит. | |
|
|
|
|
|
|
|
для: Trianon
(25.09.2010 в 21:05)
| | извиняюсь :) просто уже что попало вставлял в запрос , и только с таким GROUP BY первые два поля не дублировались.
С любыми group by не смог заставить mysql возвращать, кроме как с uniion такие записи,
Пробовал вместо NULL сделать 0 (там где IF((@x&15)-1, @x-((@x-1)&15), NULL)) , тогда начинали работать LEFT JOIN USING(to_id), но или что-то непонял или ещё что-то.
Надо попробовать подзапросами, и опять думать не отказаться-ли от передачи id вместо порядкового номера в ссылке. | |
|
|
|
|