Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: структуры таблиц и пользователи
 
 автор: heed   (24.09.2010 в 12:57)   письмо автору
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 ? Добавлять-ли везде имена или создать таблицу незарегистрированных ? Как должно быть оптимальнее ?

  Ответить  
 
 автор: Trianon   (24.09.2010 в 15:48)   письмо автору
 
   для: heed   (24.09.2010 в 12:57)
 

>Но основной вопрос вот в чём , хранить или не хранить в таблицах с сообщениями имена зарегистрированных пользователей.

> почему-то не хочется делать вместо msgs и cmnts всего одну таблицу , в msqs пишут только зарегистрированные,

аргумент слабый... Или в зависимости от того, зарегистрирован пользователь или нет, подключение к MySQL идет от разных эккаунтов?


>в противовес этому пришлось сделать два FULLTEXT msg. (как я понял не бывает один FULLTEXT индекс по двум таблицам ) + (по сообщениям в msgs ещё своя отдельная навигация и не приходится утяжелять запросы ещё одним условием)

Главное, чтоб индекс мог быть построен подходящий.

>Например если в msgs достаточно хранить только id пользователей а выводить уже вместе с именами, то как быть в cmnts и files ? Добавлять-ли везде имена или создать таблицу незарегистрированных ?

и чем тогда одни будут отличаться от других?

  Ответить  
 
 автор: heed   (25.09.2010 в 00:48)   письмо автору
18.3 Кб
 
   для: Trianon   (24.09.2010 в 15:48)
 

>и чем тогда одни будут отличаться от других?
там было-бы у всех id=NULL и тёзки в большом колличестве :)
Вообще-то да. В таблице online незарегистрированныv наверное размещать надо

>Главное, чтоб индекс мог быть построен подходящий.
Это да. Таблицу комментов всё-таки убрал, хоть и местами колличество запросов не уменьшилось, стало просторнее.

// прикрепил новую картинку , `ban` это я так назвал 'online' :)

  Ответить  
 
 автор: heed   (25.09.2010 в 18:52)   письмо автору
 
   для: 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.

  Ответить  
 
 автор: Trianon   (25.09.2010 в 19:40)   письмо автору
 
   для: heed   (25.09.2010 в 18:52)
 

почему union а не join ?

практицки ниасилил.

  Ответить  
 
 автор: heed   (25.09.2010 в 20:53)   письмо автору
 
   для: 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 тоже вроде не то.

  Ответить  
 
 автор: Trianon   (25.09.2010 в 21:05)   письмо автору
 
   для: heed   (25.09.2010 в 20:53)
 

про висящие по group by поля я тут пишу, чтоб не соврать, в среднем раз в пару месяцев, все три с лишним года.

Я не хочу, и не буду смотреть запросы, неоднозначные по group by.
в конце концов чтоб сервер сделать небрезгливым - достаточно выключить режим only_full_group_by
у меня иного просто нет. От селектов с кривыми GROUP BY меня почти физически тошнит.

  Ответить  
 
 автор: heed   (25.09.2010 в 22:49)   письмо автору
 
   для: 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 вместо порядкового номера в ссылке.

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования