Научите меня правильно строить сложные запросы к базе данных

Аватара пользователя
vadimiron

Научите меня правильно строить сложные запросы к базе данных

Сообщение vadimiron »

Пhедположим такая ситуация

Есть 2 таблицы: users, ids

В первой есть строки name, email

Во второй: name, id

Задача запроса: вывести name, email из первой таблицы когда name из 1 равен name из 2 и id равен 5



Я пишу:

select A.name, A.email from users A, ids B where A.name=B.name and B.ids=5



Но такой вариант не проходит

Подскажите плиззз где у меня ошибка



[s]Исправлено: vadimiron, 1:48 22-05-2004[/s]
Аватара пользователя
Prisoner

Re: Научите меня правильно строить сложные запросы к базе данных

Сообщение Prisoner »

Для MySql (есть стандарт, но его, имхо, мало кто придерживается или стандартов много Изображение):



Код:

Код: Выделить всё

select A.name, A.email from users as A, ids as B where (A.name=B.name) and (B.id=5)

На счет запросов понятно... непонятна организация данных. ID это уникальный номер пользователя? Тогда вторая таблица вообще не нужна, вторая таблица в большинстве таких случаев необходима для связи "1-n" - один ко многим. К примеру нужно хранить права конкретного человека на редактирование тех или иных частей сайта, файло или еще чего. То есть таких "еще чего" - много, вот и получается связь один ко многим. Вообще существует механизм (математический) по построению БД. Надо проанализировать рабочую область данных, выявить сущности (объекты области, скажем пользователь, страница и т. д.) ее атрибуты (они в последствии станут полями), связи (связи в последствии могут стать отдельными таблицами в зависимости от вида связи), построить ER-диаграмму (часто опционально, но жутко полезно), потом провести проверку на Нормальные Формы: 1НФ, 2НФ, 3НФ и "иногда" НФ Бойса-Кодда. В общем это надо до создания работать еще, правда на не сложных БД можно сделать все и так - просто интуитивно ясно где и как организовать таблицы и их поля, интуитивно избегнуть избыточности и интуитивно же понять где избыточность компенсируется быстродейсвием.



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



[s]Исправлено: Prisoner, 5:16 22-05-2004[/s]
Аватара пользователя
vadimiron

Re: Научите меня правильно строить сложные запросы к базе данных

Сообщение vadimiron »

Да я учил всё это, но с моим объёмом и сложностью базы данных, я не стал так серьёзно подходить к делу Изображение



Этот вариант тоже не проходит Изображение

В браузер выводится: Warning: mysql_fetch_row(): supplied argument is not a valid MySQL result resource - то есть запрос почему то не правильно построен



Может я что с индексами начудил???



первая таблица: много информации о юзере (в том числе name, email-которые мне сейчас нужны, верней только email, так как name я уже знаю)

вторая таблица: три столбца по сессии: id-уникальный номер сессии, name-имя юзера, который открыл сессию, time-время открытия сессии



И вот как мне сделать подобный запрос к таким таблицам???



И ещё как правильно здесь было бы организовать индексы???



Добавлено:



УУУУУУпс Изображение



у меня была одна лишняя скобка Изображение

Поэтому ничего не работало



Но в любом случае объясните, нужно ли в данной ситуации вводить индексы (сейчас у меня и без них всё работает), верней то, что нужно, я знаю, поиск намного быстрей, но самое главное как в данной ситуации организовать индексы, на каких полях и тд.



И почему создатели PHP не сделали хотя простейшую проверку синтаксиса запросов mysql??

Тогда бы я полдня бы не ломал голову, хотя эо было всего лишь лишняя скобка
Аватара пользователя
mar

Re: Научите меня правильно строить сложные запросы к базе данных

Сообщение mar »

1) насчет id (и всего остального - респект Изображение - согласна с Prisoner (соответственно, связь через id)

2) id скорее всего должен быть auto_increment и PRIMARY KEY (те генериться автоматически и быть первичным ключем - те тоже своего рода индексом)

3) я вообще предпочитаю стиль, когда свой такой id вводится в каждой таблице

4) в другой таблице надо соответственно ввести поле - что-то вроде user_id и на него посадить индекс

3) индексом стоит наградить все поля, по которым будут идти выборки, но следует иметь в виду, что при небольшом количестве записей работать они (индексы), при запросах все равно скорей всего не будут

4) Проверить что и как работает можно при помощи оператора
EXPLAIN
*

работать у тебя будет, кстати говоря и без индексов, но при увеличении объема базы работать будет все медленнее (для того индексы в бд и существуют, чтобы по ним быстро шерстить)

Кстати, в апрельском номере
PHP inside


опубликован перевод очень неплохой статьи "Шаблоны баз данных в MySQL" Рассела Дайера. *
Аватара пользователя
vadimiron

Re: Научите меня правильно строить сложные запросы к базе данных

Сообщение vadimiron »

mar



id у меня не связан с юзером, id-это номер сессии, а уже в этой же таблице есть столбец name, который указывает на открывшего данную сессию пользователя
Аватара пользователя
mar

Re: Научите меня правильно строить сложные запросы к базе данных

Сообщение mar »

vadimiron

я об этом и писала - подумай сам: какие поля занимают больше места? какие поля легче индексируются? наконец за уникальностью каких полей легче следить?

в твоем случае проще ихмо что-то вроде:

Первая таблица:



Код:

Код: Выделить всё

CREATE TABLE users (
 *id int(11) NOT NULL auto_increment, -- уникальный id 
 *name varchar(32) NOT NULL default '', -- логон
 *password varchar(32) NOT NULL default '', -- пароль
 *perms varchar(255) NOT NULL default 'user', -- права (если разные)
 *realname text NOT NULL, -- настоящее имя
 *email varchar(255) NOT NULL default '',
 *comments text, -- комментарии
 *created_by int(11) NOT NULL default '0', -- кем создана запись
 *is_enabled int(11) NOT NULL default '1', -- активна
 *deleted int(11) NOT NULL default '0', -- удалена
-- и всякое прочее по вкусу и необходимости
 *PRIMARY KEY *(id),
 *KEY email (email),
 *KEY username (name) 
 *-- и прочие ключи, какие там еще
) TYPE=MyISAM; -- или в зависимости от версии MySQL

Вторая таблица:



Код:

Код: Выделить всё

CREATE TABLE ids (
 *id int(11) NOT NULL auto_increment, -- уникальный id 
 *user_id, -- id юзера из первой таблицы
 *date timestamp(14) NOT NULL, -- время открытия сессии
 *PRIMARY KEY *(id),
 *KEY user_id (user_id),
 *KEY date (date)
) TYPE=MyISAM; -- или в зависимости от версии MySQL



[s]Исправлено: mar, 20:31 23-05-2004[/s]
Аватара пользователя
vadimiron

Re: Научите меня правильно строить сложные запросы к базе данных

Сообщение vadimiron »

Всё хорошо и красиво только у id я не смогу auto_increment поставить, так как id устанавливается функцией rand при заходе юзера, то есть я усвтанавливаю свои значения для id, auto_increment не подходит
Аватара пользователя
Vlad Drakula

Re: Научите меня правильно строить сложные запросы к базе данных

Сообщение Vlad Drakula »

vadimiron

пример сложного запроса:



Код:

Код: Выделить всё

//чдение из базы информации о постах
$postlist=mysql_query('SELECT post.post,
                              post.n as postn,
                              post.date,
                              post.ip,
                              avatar.avatar,
                              users.name,
                              users.id,
                              users.nposts,
                              users.regdate,
                              users.email,
                              users.showemail,
                              users.showip,
                              users.signature,
                              users.undername,
                              users.nrewords,
                              users.admin,
                              users.moder
                         FROM post,
                              users,
                              avatar
                        WHERE post.topicid='.$topicdata['id'].'
                          and users.id=post.userid
                          and avatar.id=users.avatar
                     ORDER BY post.n
                        LIMIT '.$start.', '.$end.' ;');

vadimiron

скорее всего проблемма не в запросе, а в самом скрипте!



можеть выложить весь кусок кода?



vadimiron

ты не правильно понял смысл ошибки!
Аватара пользователя
Prisoner

Re: Научите меня правильно строить сложные запросы к базе данных

Сообщение Prisoner »

Ой, а можно я тоже "сложным" запросом похвастаюсь? Изображение А то самокритика ведет - 333:1 Изображение.

             

Код:

Код: Выделить всё

SELECT DISTINCT
                 `news`.`n_id`,
                 `news`.`n_desc`,
                 `news`.`n_dt`,
                 `regions`.`r_name`,
                 `news`.`n_cap`,
                 `categories`.`c_name`
               FROM
                 `news`,
                 `n_c`,
                 `n_r`,
                 `regions`,
                 `categories`
               WHERE
                 (`news`.`n_id` = `n_c`.`n_id`) AND
                 (`news`.`n_id` = `n_r`.`n_id`) AND
                 (`news`.`n_dt` = \''.$DateE.'\') AND
                 (`n_r`.`r_id` = `regions`.`r_id`) AND
                 (`n_c`.`c_id` = `categories`.`c_id`) AND
                 (`n_r`.`r_id` = 1) AND
                 (`n_c`.`c_id`>100) AND
                 (`n_c`.`c_id`





На счет проверки синтаксиса запроса нужно обращаться по адресу Изображение. Зачем php об этом думать, если это не его задача? Другой вопрос, что он знает об ошибке последнего запроса, знает и молчит, заставит же его говорить об этом функция mysql_error().
Аватара пользователя
Vlad Drakula

Re: Научите меня правильно строить сложные запросы к базе данных

Сообщение Vlad Drakula »

Prisoner

я думаю что у vadimiron в функцию mysql_fetch_row() передается не то чно нужно!



т.к. PHP выдает свою ошибку а не ошибку MySQL!
Ответить

Вернуться в «Вебмастеру»