Кто хорошо разбирается в mysql?

1. Вантуз-мен (26.08.2009 / 15:27)
Иногда имеются вопросы, нужны на них ответы

2. Анатолий (26.08.2009 / 15:52)
я наверное ток процентов на 30-40 знаю sad
но если че, спрашивай)

3. Вантуз-мен (26.08.2009 / 16:56)
вот у меня есть такая база в ней 2 таблицы
CREATE TABLE news (
news_id INTEGER PRIMARY KEY NOT NULL,
news_title varchar(100) NOT NULL,
news_text TEXT NOT NULL,
news_author varchar(20) NOT NULL,
news_time INTEGER UNSIGNED NOT NULL,
news_comments INTEGER UNSIGNED NOT NULL DEFAULT '0'
);
CREATE INDEX index_news_id ON news (news_id);
CREATE TABLE comments (
comments_id INTEGER PRIMARY KEY NOT NULL,
comments_news_id INTEGER UNSIGNED NOT NULL,
comments_text TEXT NOT NULL,
comments_author varchar(20) NOT NULL,
comments_time INTEGER UNSIGNED NOT NULL,
comments_ip varchar(20) NOT NULL,
comments_brow varchar(25) NOT NULL
);

4. Вантуз-мен (26.08.2009 / 16:57)
я создаю триггер который делает пересчет комментариев в таблице comment и обновляет данные в news
CREATE TRIGGER trigger_comments_delete AFTER DELETE ON comments
FOR EACH ROW BEGIN
UPDATE news SET news_comments=(SELECT count(*) FROM comments WHERE news.news_id=comments.comments_news_id);
END;
правильный ли это запрос
UPDATE news SET news_comments=(SELECT count(*) FROM comments WHERE news.news_id=comments.comments_news_id);

5. Рома (26.08.2009 / 19:00)
А если делать не пересчет,а просто приплюсовывать по мере добавления? По моему проще будет

6. Александр (27.08.2009 / 16:07)
Если я тебя правильно понял...
<?php
$allcomment = 0;
$q = mysql_query("SELECT `id` FROM `comments` WHERE `news_id` ='". $comments_news_id) ."';");
while($a=mysql_fetch_array($q)) { $allcomment ++; } //Считаем колличество комментарий
mysql_query("UPDATE `news` SET `news_comments`='". $allcomment ."' WHERE `news_id`='". $news_id ."';"); //и записываем
?>
можно проще, но я функцию забыл...

7. Вантуз-мен (27.08.2009 / 19:52)
да мне для триггера надо было такое не пойдет, ладно уж я без триггера решил сделать

8. Вусал (28.08.2009 / 00:12)
иль проще
7. $allcomm = mysql_num_rows($q);
И потом обновляй
триггер лишнее...

9. Вантуз-мен (30.08.2009 / 14:56)
еще есть вопрос, при добавлении нового столбца в таблицу
к примеру
ALTER TABLE news ADD news_test INTEGER UNSIGNED NOT NULL значение не должно быть NULL но и не DEFAULT '' типа как при создании
news_test INTEGER UNSIGNED NOT NULL как быть в этой ситуации

10. Анатолий (30.08.2009 / 15:04)
А почему поле не должно быть NULL?
Вроде бы наоборот, если в таблице есть уже записи, то добавить поле со значением NOT NULL и без DEFAULT не получиться.

11. Вантуз-мен (30.08.2009 / 16:42)
ну вот это я и хотел узнать

12. Arab (07.09.2009 / 18:18)
возможно ли сделать чтоб в таблице в полях сохранялось только 2 значения?
например 1я запись:
id - 1, name - alex
после 2й записи:
id - 1, name - alex
id - 2, name - petya
после тетьей:
id - 2, name - petya
id - 3, name - vladimir
после 4й:
id - 3, name - vladimir
id - 4, name - jordan

13. Димон (07.09.2009 / 19:14)
mysql_query("INSERT INTO...");
$id = mysql_insert_id();
mysql_query("DELETE ... WHERE `id` = '".($id-2)."' LIMIT 1");

14. Вантуз-мен (07.09.2009 / 19:29)
"DELETE FROM table WHERE id < (
SELECT MIN(id) FROM
(
SELECT id FROM table
ORDER BY id DESC LIMIT 2
)
);

15. Arab (08.09.2009 / 20:35)
спасибо. еще вопрос:
что аза атрибут такой для полей UNSIGNED и BINARY ? В чате мазафаки в таблице писем такие атрибуты.. текст псем не виден из рнрМуАдмин

16. Arab (08.09.2009 / 20:37)
спасибо. еще вопрос:
что за атрибуты такие для полей UNSIGNED и BINARY ? В чате мазафаки в таблице писем такие атрибуты.. текст писем не виден из рнрМуАдмин
Редактированный: Араб

17. DmitryDick (08.09.2009 / 23:22)
С атрибутом unsigned числовые поля становятся беззнаковыми, их максимальное значение увеличивается. Например timyint диапазон от -127 до 128, а без знака от 0 до 255

18. DmitryDick (08.09.2009 / 23:28)
tiNyint*

19. Анатолий (09.09.2009 / 12:52)
BINARY - бинарный тпи. запись побитовая. можно, например, картинки хранить.

20. Удаленный (10.09.2009 / 00:05)
4.А зачем в таблице news указывать id_news?Ведь и так ясно что это ид новостей,можно просто id

21. Tony V (10.09.2009 / 00:10)
21, Как кодеру хочется назвать столбец, так он и называет.

22. AlkatraZ (10.09.2009 / 01:02)
Превед уважаемые smile
Честно говоря, читал тему, но ничего ниасилил?
Зачем такая сложность? Неужели задача того стоит?
"Гениальность заключается в простоте"
Простые скрипты, но с ПРАВИЛЬНЫМ алгоритмом всегда работают лучше.
Если задачу можно решить без всяких извращений в виде триггеров и прочих нестандартных атрибутов полей, это надо делать!

23. AlkatraZ (10.09.2009 / 01:05)
Сама задача поставлена неправильно.
Типа, "хочу триггер, чтоб то-то и то-то", но вначале нужно понять, а зачем вообще этот триггер?
Что нужно сделать?
---
К примеру, когда что-то делаем, у нас есть КОНЕЧНАЯ цель. Ее то и нужно четко ставить. А уж потом, будем искать кратчайшие пути ее достижения smile

24. Валерий (12.09.2009 / 18:30)
1. Чем отличается тип INT(11) от например типа INT(6)?
2. Чем чревато использовать не тот тип в плане тормознутости или объёма базы?
3. Что за тип VARCHAR и в каких ситуациях его лучше использовать?

25. Валерий (12.09.2009 / 18:44)
4. Какой тип должно иметь поле, у которого может быть только 2 значения (1 или 0)

26. DmitryDick (12.09.2009 / 20:45)
25, 26, не окуел ли ты? При переходе из его анкеты на его сайт, стоит переадресация на изменение его авторитета, т.е. ему плюс.

27. Анатолий (12.09.2009 / 20:53)
25,
1. Длинной, т.е. максимально возможным значением.
2, при использовании не того типа:
а) тип преувеличен (можно TINYINT a есть например INT) при возростании числа записей в таблице растет пустующий размер - неэффективное использование ресурсов;
б) уменьшен. придется записать данные в базу, а их автоматически уменьшит до максимально возможного значения данного типа.
3. VARCHAR(количество) это символ. в скобках указывают макс. кол-во символов в поле.
Удобно использовать для ограниченых полей типа логин, пароль, где заведомо извесно, что значение не привысит данной длинны.
4, в таком случае можно использовать BIN - бинарный тип данных

28. AlkatraZ (13.09.2009 / 00:22)
#28 насчет бинарных данных, ты абсолютно неправ.
Что интересно, не один ты так ошибаешься. мне уже приходилось исправлять скрипты с таким же недоразумением.
---
#26 - правильный ответ, это тип BOOLEAN, хотя, когда его создашь, увидишь, что на самом деле это TINYINT длиной (1)
---
Бинарный тип (как советовал #28) работает, но у него серьезные проблемы с сортировкой и выборкой.

29. AlkatraZ (13.09.2009 / 00:28)
Щас объясню, почему у бинарного типа есть проблемы.
---
То, что спросил #26 обычно используем для чекбоксов (есть-нету, открыто-закрыто и др.). Это Булевой тип данных (логический, истина-ложь).
Когда создаешь Булевое поле, ставишь по умолчанию 0, а скрипт если надо, записывает 1.
Для Бинарного типа (как советовал 28) НЕЛЬЗЯ выставить значение по умолчанию, поэтому, кроме 1 и 0 появляется третье значение NULL. Вроде подумаете, в чем же разница, между 0 и NULL, но попробуйте сделать запрос с сортировкой и поймете, что разница большая.
Потому то и нельзя в Булевых полях использовать Бинарный тип.

30. Валерий (13.09.2009 / 08:51)
29,30 спасибо за разьяснения, я сам всё время использовал binary, подозревая неладное, но я всегда устанавливал значение по умолчанию, и проблем с этим вроде не было, да и сортировать такие поля обычно не нужно.

31. Валерий (13.09.2009 / 08:54)
Ещё вопрос по типам родился:
Чем отличается тип INT(1) и TYNYINT(1) ?

32. Вантуз-мен (15.09.2009 / 21:40)
Помогите составить запрос
имеются 2 таблицы
inbox (id - user - author - time)
outbox (id - user - author -time)
нужно сделать что-то типа просмотра переписки
вывести все данные из 2 таблиц если inbox.user=$log и inbox.author=$uz
а также вывести если outbox.user=$uz и outbox_author=$log
и отсортировать по общему time

33. KingNLO (15.09.2009 / 22:58)
SELECT id.inbox,id.outbox FROM inbox,outbox WHERE user.inbox='".$uz."' ORDER BY time DESC
Ну и тому подобное...

34. KingNLO (15.09.2009 / 22:59)
Прошу прощения)
Правильно вот так:
SELECT inbox.id,outboxid FROM inbox,outbox WHERE outbox.user='".$uz."' ORDER BY time DESC


35. AlkatraZ (16.09.2009 / 00:23)
#33 Ты напрасно решил Inbox и Outbox разбить на отдельные таблицы.
Более правильно (и проще) сделать дак:
ID, SENDER_ID, RECIPIENT_ID, TEXT, TIME
Тогда будет легко всего ддним несложным запросом вывести данные с любой сортировкой для любого юзера.

36. AlkatraZ (16.09.2009 / 00:25)
Фигассе, форум глючит.
Хотел вставить запрос, дает ошибку:
---
Method Not Implemented
GET to /forum/index.php not supported.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.

37. Удаленный (16.09.2009 / 00:26)
Vantuz,хочешь мотор на мускуле сделать))

38. Вантуз-мен (16.09.2009 / 00:57)
AlkatraZ, да я так думал, но если юзер который получит письмо удалит его сразу,то у другого оно уже не будет в отправленных, а с метками возится не охота, да и мне как-то удобнее когда отправленные отдельно, это сервер че-то там не пропускает, давно прошу хостеров разобраться
35. KingNLO твой запрос никуда не годится, даже без попробуй

39. Вантуз-мен (16.09.2009 / 00:59)
вот типа такого что-то должно быть,
но может как-то проще можно
SELECT * FROM inbox WHERE inbox_user=$uz AND inbox_author=$log UNION ALL SELECT * FROM outbox WHERE outbox_user=$uz AND outbox_author=$log ORDER BY inbox_time DESC;

40. AlkatraZ (16.09.2009 / 09:55)
#39 с метками полюбому придется возиться.
Как же ты будешь отслеживать, прочитал юзер письмо, или нет?

41. Валерий (16.09.2009 / 12:27)
#33 Как то так
SELECT inbox.id,outbox.id FROM inbox,outbox WHERE (inbox.user='$log' AND inbox.autor='$uz') OR (inbox.autor='$log' AND inbox.user='$uz') ORDER BY inbox.time,outbox.time;


42. Валерий (16.09.2009 / 12:30)
Исправляюсь
SELECT inbox.id AS inbox_id,outbox.id AS outbox_id FROM inbox,outbox WHERE (inbox.user='$log' AND inbox.autor='$uz') OR (inbox.autor='$log' AND inbox.user='$uz') ORDER BY inbox.time,outbox.time;
Вот так лучше.

43. Димон (16.09.2009 / 15:10)
#36, поддерживаю. Запрос будет быстрее выполняться из одной таблицы чем из двух.

44. Вантуз-мен (17.09.2009 / 13:53)
44. NEx в данном примере да быстрее, а если нужно отделить входящие от отправленных и когда сообщений очень много, тогда лучше делать в разных таблицах, например на висави в данный момент около 20мб приватных входящих сообщений только, а фактически максимальный (20кб*2500юзеров) /1024 = 48 мб, это если никто почту чистить не будет

45. Вантуз-мен (17.09.2009 / 13:58)
Нужна еще помощь, как лучше сделать полноценный поиск по базе
Каким образом лучше искать, Я так понял LIKE ищет не очень быстро
Как искать например если пользователь ввел сразу три слова и надо найти не по И а по ИЛИ
я делаю сейчас примерно так
<?php
Database::$forum->sqliteCreateFunction ('utflower' , 'rus_utf_tolower');
$querysearch = Database::$forum->query("SELECT * FROM topics WHERE utflower(topics_title) LIKE '%".rus_utf_tolower($findme)."%' ORDER BY topics_last_time ASC;");
dump($querysearch->fetchAll());
Все нормально, но это ищет точное сходство, я думаю сделать что-то типа если слов несколько то разбивать их и добавлять в поиск условие ... OR LIKE %...% OR LIKE %...% ... как по производительности кто знает?

46. Андрюха (17.09.2009 / 14:21)
Сильно я думаю не нагрузит,норм

47. AlkatraZ (17.09.2009 / 16:13)
#45 Нет, ты не выйграешь от разделения.
Таблицы абсолютно одинаковой структуры и хранят одинаковые данные. Потому, смело можно хранить в одной таблице и потом сортировать выборкой.
К примеру, в твоем варианте:
время 1-го запроса + время 2-го запроса + время посылки 1 SQL + время посылки 2-го SQL
Время посылки, я имею ввиду комманду mysql_query() ибо она тоже съедает определенное время на обработку.
Для дной таблицы, общее время получается меньше. А если еще правильно проиндексируешь, вообще быстро будет.

48. AlkatraZ (17.09.2009 / 16:15)
#46 Насчет времени поиска - всецело зависит от размера базы и правильной индексации.
К примеру, если ищешь в поле TEXT, то если нужен быстрый поиск, надо создать полнотекстовый индекс. Да, зохавает до 30% дополнительного пространства базы, но зато при поиске, все будет максимально быстро и снизится нагрузка на базу.

49. Вантуз-мен (18.09.2009 / 00:23)
C поиском что-то сложновато
при обработке своей функцией sqliteCreateFunction ('utflower' , 'rus_utf_tolower');
и выборке из 50 тыс сообщений уходит 4 сек,
если использовать встроенную функция LOWER() или UPPER() то 0.4 сек, но при этом не преобразовывает UTF8.
Все это из-за преобразования в верхний или нижний регистр
Индексация не сильно помогает, а база увеличилась более чем в 2 раза, было 12.5мб, стало 28мб
Не знаю даже что и делать

50. Nu3oN (10.06.2011 / 23:39)
Vantuz (16 Сентября 2009 / 00:59)
вот типа такого что-то должно быть,
но может как-то проще можно
SELECT * FROM inbox WHERE inbox_user=$uz AND inbox_author=$log UNION ALL SELECT * FROM outbox WHERE outbox_user=$uz AND outbox_author=$log ORDER BY inbox_time DESC;
Решил я по твоему методу сделать, так сто раз пожалел =)
Решил сделать примерно такую структуру

CREATE TABLE `rotorcms`.`privat` (
    `privat_id` int NOT NULL AUTO_INCREMENT,
    `privat_type` enum('in', 'out') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
    `privat_inbox` varchar(21) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
    `privat_otbox` varchar(21) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
    `privat_time` int NOT NULL,
    `privat_text` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
    `privat_read` bool NOT NULL,
    PRIMARY KEY (`privat_type`, `privat_inbox`, `privat_otbox`, `privat_id`),
    INDEX ( `privat_id` ) 
) 
ENGINE = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;


51. Ден (10.06.2011 / 23:47)
50, жесскую тему откопал....

52. shifty (10.06.2011 / 23:49)
51. Денис Сергеевич, ))

53. Nu3oN (10.06.2011 / 23:53)
Ковырялся в гугле, и наткнулся на нее)))
Сейчас сижу по новой приват пишу))

54. ramzes (13.06.2011 / 17:39)
блин, подскажите, че делать
делаю экспорт бд
выходит такая шняга..
-- Дамп данных таблицы `alert`
--

INSERT INTO `alert` (`id`, `alert_user`, `alert_autor`, `alert_message`, `alert_time`, `alert_close`) VALUES
(1208, 4, 1, 'Личное сообщение от <b>ramzes</b><br /><a href="/private/chat/1/"><b>Re[32]: Изменение авторитета</b></a>', 1307971874, '0');
уже все перепробовал вроде..
кодировка и сравнение utf8
файл сохранения соответственно тоже, и ни фига((

URL: https://visavi.net/topics/373