FAQ канала #MySQL

Даная страничка является наобором ответов на наиболее часто задаваемые в канале #mysql вопросы irc сети RusNet.

0. а как | где | почему | .. ?
http://dev.mysql.com/doc/
1. а как мне дамп в базу залить?
mysql -uroot -p dbName < dbFile.sql
2. а как обновить пароль юзера?
update user set Password = PASSWORD('password') where Host = '%' and User = 'root';
3. как посчитать строки с условием?
select count(if(b=1,id,null))) as b1, count(if(b=2,id,null))) as b2 from table
4. если в зависимости от того верно ли условие в первой строке [не]нужно подсчитать остальные то тут надо пользовать вот такое:
set @c:=1;SELECT count(if(@c=1,id,null)), count(if(@c:=2,null,null)) as a FROM groups
5. при инсерте ошибка вроде: Column doent mutch value count at row ! (текст взят добуквенно из канала, автор Stan36214)
число столбцов в таблице не совпадает с кол-вом указаных значений. укажите и пересчитайте столбцы а-ля: insert into table (a,b,c) values (1,2,3); при этом число запятых в первых скобках должно _совпадать_ числу значений справа. удивительно, но факт.
6. Как выбрать по ОДНОМУ максимальному/минимальному значению с соответствующими столбцами. например по Н самых ПОСЛЕДНИХ по дате сообщений от КАЖДОГО юзера в таблице. если подзапросы использовать запрещает религия. мега решение by issay :)).
select user, max(time) as m, substring_index((group_concat(msg order by time desc separator 'zhut')),'zhut' ,1) from msgs group by user при этом неплохо сначала выполнить set session group_concat_max_len = 1024; где 1024 максимальный размер возможного нужного вам поля. по умолчанию стоит 1024. чем меньше выставите, тем лучше будет - ибо меньше памяти сожрётся, плюс возможно оптимизатор не будет собирать все лишние поля, а возьмёт примерно сколько вам нужно.
7. что делать если я "забыл" пароль от mysql?
запустить сервер с ключём мускула: --skip-grant-tables
записать новый пароль на бумажку
поменять пароль
выполнить mysqladmin flush-privileges
спрятать бумажку в надёжное место.
8. как изменить позицию столбца в таблице?
ALTER TABLE таблица change old_col_name column_definition [FIRST|AFTER] col_name
например: ALTER TABLE groups CHANGE path varchar(255) AFTER parent
при использовании first указывать col_name не надо, столбец будет первым.
9. Client does not support authentication protocol
http://dev.mysql.com/doc/refman/5.0/en/old-client.html
10. Проблемы с русским в >= 4.1
http://phpclub.ru/faq/Mysql41Rus
так же смотри пункт 18
11. как узнать последнее значение auto-increament в таблице?
show table status like 'таблица'.
с 5й версии можно посмотреть в information_schema.
12. как увидеть значение последнего сгенерёного auto-increament сразу после вставки
select last_insert_id()
стоить помнить, что:
- работает "по-коннектово". т.е. отдаёт последний созданный ид в данном коннекте к базе.
- при генерации многих значений сразу (например - при вставке одним инсертом 3-х строк) отдастся первое сгенерёное значение, а не последнее.
13. переход к 5й версии mysql, нужно ли конвертить базы?
да, нужно. для этого есть спец.утилита mysql_upgrade.
более того, в 5.0 и в 5.1 изменилась не только структура таблиц, но и поведение некоторых sql операторов. поэтому настоятельно рекомендуем прочесть доку к 5.0 или 5.1 в зависимости от того, что вам нужно. конкретно по обновлению баз c 4.1 до 5.0 инфу можно прочесть здесь.
14. а как сгенерить случайную дату?
например так: select from_unixtime(rand()*1000000000)
если хочется из заданного интервала то можно так:
select from_unixtime(floor(от+rand()*(до-от)))
15. а как выбрать строки где значение поля времени отличается от предыдущей строки более чем на 3 минуты?
можно так:
select t.event, substring_index((group_concat(t2.event order by t2.time separator 'issay')),'issay' ,1) as sleduushaia from times as t left join times as t2 on (t2.event>t.event) where t2.time>t.time and t2.time<addtime(t.time,'00:03:00') group by t.event
где поле event определяет, какая строка является "следующей".

а если хочется получить все строки следующие за текущей в пределах 3х минут, а не только первой таковой, то можно сделать так:
select t.event, group_concat(t2.event order by t2.time separator ',') as sleduushaia from times as t left join times as t2 on (t2.event>t.event) where t2.time>t.time and t2.time<addtime(t.time,'00:03:00') group by t.event

©issay
16. есть табличка (событие;время). интересует выборка:
(временной_интервал1;количество_событий1);
(временной_интервал2;количество_событий2);
.....;
(временной_интервалn;количество_событийn);

за указанный период времени
на вход мускулу - табличка с событиями
начальное время, размер интервала, количество интервалов
решить без привлечения ЯП и хранимых процедур
SET @a:=0;
SELECT COUNT(events.event) AS cnt ,FUNC(t.a) AS start, FUNC(t.a+1) AS end
FROM
(SELECT @a:=IF(@a IS NULL,0,@a)+1 AS a FROM fake) t
LEFT JOIN
events
ON events.time>=FUNC(t.a) AND events.time<FUNC(t.a+1)
WHERE a<NUMBER_OF_INTERVALS
GROUP BY a;

где FUNC() - функция, вычисляющая время начала интервала по порядковому номеру (обычно это START_TIME+INTERVAL_SIZE*I, где I - номер интервала);
NUMBER_OF_INTERVALS - количество интервалов
fake - табличка, в которой есть достаточно количество записей (т.е. не меньше, чем число интервалов)

©boda
17. А где можно почитать про SQL вообще?
вот есть такая книжка
ещё есть доки на citforum.ru
18. а почему у меня выводятся вопросики?
как же вы достали с этим вопросом..

в общем эта проблема имеет три разных потенциальных источника, пройдём их все по очереди.
1. вы создаёте базу данных (или же она у вас уже есть).
вам НУЖНО указать, какой набор символов базе использовать для хранения. кодировку можно указывать для базы, таблиц, столбцов. соответственно кодировка указанная для столбца перекрывает указанную для таблицы и т.п.
для создания базы используем такой синтаксис:
CREATE DATABASE db_name DEFAULT CHARACTER SET cp1251 DEFAULT COLLATE cp1251_general_ci
если база уже есть, и таблицы уже есть, то можно сменить указанную таблицам кодировку на нужную. при этом можно это сделать двумя путями:
а) когда кодировка соответствует данным, но вы хотите, чтобы кодировка изменилась, и изменилась вместе с данными:
для базы: ALTER DATABASE db_name DEFAULT CHARACTER SET cp1251 DEFAULT COLLATE cp1251_general_ci
для таблицы: ALTER TABLE tbl_name DEFAULT CHARACTER SET cp1251 COLLATE cp1251_general_ci
б) кодировка у таблицы указана неверно, а данные уже там:
ALTER TABLE t1 CHANGE c1 c1 BLOB, CHANGE c2 c2 BLOB; ALTER TABLE t1 CHANGE c1 c1 TEXT CHARACTER SET cp1251, CHANGE c2 c2 TEXT CHARACTER SET cp1251;
ну понятно, что вместо TEXT вам нужно указать ваш тип столбца.
Внимание: boda тут подметил, что на старых версиях вроде 4ки, если у вас фиксированые поля, например char (а не варчар), то конвертация в blob тихим сапом превратит char в varchar. есть несколько вариантов этого избежать, например конвертить не в блоб, а в binary. но там свои нюансы. в общем посовещавшись мы пришли к выводу, что лучше всего конвертить вышеуказанным способом, НО все столбцы таблицы одним запросом. в этом случае и в 4ке всё работает.
итак, мы счастливо позаботились о том, чтобы хранилище знало в каком виде у нас данные, и хранило их верно. теперь переходим ко второму шагу.

2. импортирование данных из дампа.
дамп по-умолчанию делается в utf8. но у вас может быть дамп в какой угодно кодировке. поэтому мы должны первым делом сообщить mysqld в какой кодировке у нас данные. для этого мы первой строкой вставляем в дамп: set names cp1251

cp1251 заменяем на название кодировки, которую имеют ваши данные. это гарантирует нам успешную заливку данных.
надо ещё добавить, что неплохо бы проверить, что в описаниях баз и таблиц в дампе указана нужная вам кодировка, как описано в пункте №1.

3. выставление переменных mysqld указывающих в какой кодировке данные поступают из клиента, в какой их клиенту отдавать, и в какой их обрабатывать.
все эти три переменные могут быть выставлены одной командой: set names cp1251. эту команду следует посылать сразу после коннекта первой строкой, переменные сохранятся в нужном нам состоянии до закрытия коннекта.
если есть доступ к конфигу сервера (my.cnf на *nix и my.ini под виндой), то можно выставить переменные сразу в нём для всех клиентов. делаем это так:
находим там секцию [client] и добавляем туда:
default-character-set = cp1251
character-sets-dir = /usr/local/mysql4/share/charsets

где первое нужная вам кодировка, а второе путь до папки с ними.

находим там секцию [mysqld] и добавляем туда:
default-character-set=cp1251

находим (или добавляем, если нету) секцию [mysql] и добавляем туда:
default-character-set=cp1251

не забываем пеерзагрузить сервер.
проверить, что кодировка теперь выставлена можно выполнив команды:
SHOW VARIABLES LIKE 'character_set%';
SHOW VARIABLES LIKE 'collation%';
эти нехитрые процедуры решают примерно 99% проблем с кодировкой и избавят добрых и честных посетителей канала от сальных шуточек над вами.

(c) issay

Если есть комметерии по факу, или желание добавить чего в него, то обращайтесь на канале к issay, boda, или к другим операторам канала, кто в даный момент в онлайне.


на генерацию страницы было затрачено: 15.45523 минут.


 


Hosted by uCoz