[Урок / Tutorial] SQL
#1

Всем привет, с вами Psycho. Сегодня расскажу о языке SQL-запросов и работой с ними.
Если вы полный ламер в MySQL, и БД это будет вам полезно. Базы данных работают
в десятки раз быстрее чем файлы и там удобно хранить информацию.

Как устроена таблица в БД:

Есть первичный ключ, есть все остальное. Я не знаю как это описать на словах.

Пример:
user_id -
username -
password -

Представим что user_id это первичный ключ. Что это значит?
Это значит что в таблице не должно быть одинаковых user_id. Точнее вы не сможете их добавить так как будет ошибка.

Представим что у нас есть таблица.

Таблица users, user_id - первичный ключ.

user_id user_name user_password

1 Psycho 123456
2 Crazy 654321
3 star-tR 123456

Как извлечь данные из таблицы.

Запускаем запрос: SELECT * FROM users WHERE user_id = '1'
MySQL это понимает как - "Взять всё из таблицы users, где user_id единица".
* - это значит что извлекаем все данные

Если нам нужно взять только имя пользователя, то делаем запрос: SELECT user_name FROM users WHERE user_id = '1'
Если нужно извлечь ещё и пароль то перечисляем через запятую: SELECT user_name, user_password WHERE user_id = '1'
Обратите внимание: Запятой перед оператором WHERE быть не должно.

Я привёл примере извлечения по user_id, хотя можно привести и по другим полям, например имени.
Конечно, мы можем извлечь и по имени. Но я не рекомендую, т.к первичный ключ у нас user_id, а не ник пользователя.
Ведь ник мы можем повторить, и будет извлечено два поля, а не одно.

Отвлечемся на основные типы данных MySQL:
VARCHAR - Обычный текст.
FLOAT - дробные числа/числа с плавающей запятой
INT - целые числа
TEXT - поле рассчитанное на большое кол-во текста, в том время как VARCHAR ограничивается фиксированным кол-вом.
DATETIME - Дата и время
Не указывайте слишком большой размер поля, если вы его не используете полностью. Иначе выделенный обьем памяти на данные будет работать в пустую.

Дополнитльные параметры поля: AUTO_INCREMENT(в дальнейшем AI)
Инкремент это прибавление к техущему числу 1, а декремент наоборот. AI удобно указывать в опциях первичного ключа.(хотя только там вы и можете их указывать)

Вернемся к SQL разметке. Теперь покажу как удалить запись.
Запукаем такой запрос: DELETE FROM users WHERE user_id = "1"
напоминаю: users - таблица, user_id - поле с параметром 1. Если у нас несколько полей где user_id 1, то удаляться все.

Как изменить запись.
UPDATE users SET `user_name` = 'ch3rryp0pp3r' WHERE user_id = '1'
Этим запросом мы меняем ник Psycho на ch3rryp0pp3r
Если нам нужно сменить несколько значений пользователю, то перечисляем их через запятую. Но SET используем один раз.
Напомню: Перед WHERE запятой не надо.

Подсчитать сколько в таблице записей.

SELECT COUNT(*) AS table_count FROM users
table_count - вернёт количество записей как поле с названием.

Есть ещё оператор LIMIT. Обычно ставиться в конце запроса.

LIMIT 0,10 извлечь записи с 0, по 10.
LIMIT 35, 50 Извлечь 50 записей начиная с 35ой
LIMIT 50, 250 Извлечь 250 записей начиная с 50ой.
ну логика понятна.

Вроде я все основное расписал как использовать язык SQL. А на практике так и не показал.
я не буду углубляться ни в lua, ни в pawn, ни в php.
скажу что в общем есть такие функции, FAQ по ним почитаете на wiki нужного вам языка.

mysql_connect - соединяемся с MySQL.
mysql_select_db - выбираем базу с которой будем работать.
mysql_query - отправляем запрос
mysql_num_rows - количество извлеченных столбцов.
mysql_num_fields - узнать количество извлеченных полей.
mysql_fetch_row - разбить столбец. Данные из mysql_query извлекаются как массив или хз что, поэтому нужно их довести до кондиции.
mysql_fetch_field - разбить поле.
mysql_fetch_array - разбить данные в массив
mysql_free_result - очистить память плагина после запроса. в PHP мне не приходилось использовать, но если в pawn я это не использовал то падал сервер.
mysql_close - закрыть соединение с базой данных. считаю хорошим тоном это делать, хотя всегда забываю применить.
mysql_ping - пингуем текущее соединение. Часто используется при работе с удалёнными БД, то есть не те которые на одном хосте.
mysql_errno, mysql_error - проверяем ошибки. Если вы уверены что все сделали правильно можете не использовать. Но на первых порах может пригодиться.

Есть ещё другие функции, но я описал те что смог вспомнить.

Совет: Используйте phpMyAdmin или какую нибудь программу для работы с базой. Там есть целый набор инструментов по работе с базой.
Можно проверить свой запрос, создать базу, организовать связи между таблицами. (FOREIGN KEY, кому интересно почитайте)
Можно одним запросом извлекать данные из нескольких таблиц, основываясь на равенстве данных выбранных таблиц (INNER JOIN / OUTER JOIN / LEFT JOIN / RIGHT JOIN)
Погуглите, можно сделать свою работу с БД очень простой и быстрой.


Это только основная часть, самое простое. На самом деле по БД есть целая наука. Наука громко сказано, скорее учение.
Я не специалист по БД, но хорошо разбираюсь. Эти знания вам помогут не только в игровом скриптинге но и в других языках программирования.
И язык разметки SQL единый для всех БД. Что Oracle, что MySQL, что SQLite и.т.п Язык будет один, но всё таки в работе с каждой БД есть свои нюансы, так что читайте документацию.

На заметку: В мире MySQL на больших проектах не используют, а отдают предпочтение Oracle. Он платный и более оптимизирован под данные.
Также там не возникает проблем с кодировками. В общем о всех плюсах не расскажу, но знайте что Oracle лучше. Но он для профессионалов и для огромных бд, где идет большое количество процессов.
Но если же у вас сайт клана или игровой сервер - вам с головой и больше хватит MySQL

Если найду время и желание свою лень напишу FAQ с примерами по процедурам. Хотя можно обойтись без них, но если научиться их грамотно использовать то можно оптимизировать свои запросы и ваши скрипты будут "летать".

Psycho 28 / 08 / 2010

Спрашивайте если есть непонятки.
Reply
#2

Float - координата отжог, скьл это самыи в мире легкии яызк, больше похоже на скрытую рекламу, если честно.
Reply
#3

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

То что я расписал это действительно легко. Если не касаться процедур и прочего.

рекламу убрал, действительно похоже.
Reply
#4

Молодец вообщем. Что ещё сказать. Теперь видно, что стараешься на благо человечества. Даю пять, ты правильно отметил INT, можно было в точности наоборот назвать и float, т.е дробное число (:
Reply
#5

перемести это в релизы.
Reply
#6

php.su намного приятней и понятней пишет! (:
Reply
#7

Мм,хорошо
Забыл про INSERT
Reply
#8

Code:
stock db_GetMaxValue(table[],column[],col2[],i,up = 1) {
	new str[20];
	if (up) set(str,"DESC");
	else set(str,"ASC");
	format(DBQuery, MAX_STRING, "SELECT %s FROM %s ORDER BY %s %s LIMIT %d, 1;",col2,table,column,str,i);
	Result = db_query(DataBase, DBQuery);
	db_get_field(Result, 0, DBQuery, MAX_STRING);
	db_free_result(Result);
	return DBQuery;
}
этот код позволяет отсортировать все данные(по возрастанию или убыванию), и вытаскивает данные по нужному вам порядковому номеру
в функции я использую оператор ORDER BY для сортировки в таблице(сами данные в таблице не меняются, и идут в алфавитном или нумерном порядке по первичному ключу)

ну и допустим можно использовать так:
Code:
if (!strcmp(cmdtext,"kills")) {
		    SendClientMessage(playerid,COLOR_RED,"--Top 5 Num kills--");
		    SendClientMessage(playerid,COLOR_RED,"  name      kills");
		    for (i=0;i<5;i++) {
				format(string,256,"%d. %s \t%s",i+1,db_GetMaxValue("records","kills","name",i),db_GetMaxValue("records","kills","kills",i));
				SendClientMessage(playerid,COLOR_RED,string);
			}
			SendClientMessage(playerid,COLOR_RED,"__________________________");
			return 1;
		}
п.с. можно, конечно, в смысле оптимизации, сделать и получше, но я не стал заморачиватся, и так быстро )
п.с.с. в шапке исправьте:
INT - целое число
FLOAT - число, с плавающей точкой.
Reply
#9

Aleks10, интересный код, особенно это:
Quote:

format(DBQuery, MAX_STRING, "SELECT %s FROM %s ORDER BY %s %s LIMIT %d, 1;",col2,table,column,str,i);

выбрать начиная с i одну строку!
Смысл сортировать одну строку?
Reply
#10

Quote:
Originally Posted by Stepashka
View Post
Aleks10, интересный код, особенно это:выбрать начиная с i одну строку!
Смысл сортировать одну строку?
потому что вначале идёт сортировка, а патом из сортированного списка я беру нужную строку..
Reply
#11

Quote:
Originally Posted by Romanius
View Post
вообще то язык запросов SQLite очень отличается от MySQL
Язык запросов называется SQL.

Quote:
Originally Posted by Romanius
View Post
1. Имя таблицы, полей там нужно вводить в квадратных скобках т.е. [users]
не правда.
Quote:
Originally Posted by Romanius
View Post
3. Обычное число там задается не INT, а INTEGER
Вроде как INT там тоже есть, но если создаешь PRIMARY KEY, то надо писать INTEGER.
А в MySQL разве нет типа INTEGER?
Quote:
Originally Posted by Romanius
View Post
если писать там обычным синтаксисом от MySQL то бд начинает подвисать
будь добр объясни, что ты здесь имеешь в виду ))
Reply
#12

Вот вам учебник по MySQL


На счет скобок. Почитай на офф сайте sqlite
Reply
#13

Quote:
Originally Posted by Romanius
View Post
Вот вам учебник по MySQL


На счет скобок. Почитай на офф сайте sqlite
Ну и что
посмотрел на сайте...
вот коды(неважно что делают):
Code:
strcpy(sqlStr,"CREATE TABLE Main (");
       strcat(sqlStr,"ID INTEGER PRIMARY KEY AUTOINCREMENT,");
       strcat(sqlStr,"Name1 VARCHAR(50) COLLATE NOCASE,");
       strcat(sqlStr,"Name2 VARCHAR(128) COLLATE NOCASE,");

sprintf(SqlStr, "INSERT INTO TypeNumbers (MainID,Type,CurrentNumber) VALUES(%u, 4, 0);", PrimKey);

  SELECT strftime('%s','now') - strftime('%s','2004-01-01 02:34:56');
что то тут не видно особо этих скобок...

про integer тоже ахинея..
:
Code:
INT
INTEGER
TINYINT
SMALLINT
MEDIUMINT
BIGINT
UNSIGNED BIG INT
INT2
INT8
всё это относиться к INTEGER(Resulting Affinity)

п.с. ты вообще захадил на офф сайт?
Reply
#14

заходил. там находил что если использовать mysql синтаксис то он тоже поддерживается но не полностью

Я уже и к этому привык

И я говорил о SQLite
Reply
#15

PHP Code:
enum DATA
{
  
Float:x
}
new 
bData[MAX_DATA][DATA];
new 
Field3[256];
new 
DBResult:Result4;
Result4 db_query(Database"SELECT * FROM `COORDINATS` `X`");
for(new 
i=0;i<sizeof(bData);i++)
     {
db_get_field_assoc(Result4"X"bData[i][x], 20);

если делать так, то выдается warning 213: tag mismatch. (последняя строка), подскажите что неверно?
Reply
#16

Quote:
Originally Posted by serpip
View Post
PHP Code:
enum DATA
{
  
Float:x
}
new 
bData[MAX_DATA][DATA];
new 
Field3[256];
new 
DBResult:Result4;
Result4 db_query(Database"SELECT * FROM `COORDINATS` `X`");
for(new 
i=0;i<sizeof(bData);i++)
     {
db_get_field_assoc(Result4"X"bData[i][x], 20);

если делать так, то выдается warning 213: tag mismatch. (последняя строка), подскажите что неверно?
1) на дату темы смотрел?
2) db_get_field_assoc() третий параметр должен быть строкой.
Reply
#17

Quote:
Originally Posted by Stepashka
View Post
1) на дату темы смотрел?
2) db_get_field_assoc() третий параметр должен быть строкой.
Извиняюсь,что задал вопрос не в той теме. Не совсем понял что значит "параметр должен бть строкой". Так что ли:
PHP Code:
new Float:posX;
db_get_field_assoc(Result4"X"posX20); 
?Просто, допустим в ini, для изъятия чисел с запятой используется iniGetFloat, а есть ли подобная функция в SQL?
Reply
#18

Code:
new a; //десятичное целое число
new Float:b; //дробное число
new bool:c; //булевое значение true/false
new s[20]; //строка длиной 20 символов
Reply
#19

Quote:
Originally Posted by Stepashka
View Post
Code:
new a; //десятичное целое число
new Float:b; //дробное число
new bool:c; //булевое значение true/false
new s[20]; //строка длиной 20 символов
Ну так если делать
PHP Code:
new posX[20]; 
db_get_field_assoc(Result4"X"posX20); 
то чисто же должно быть дробное, а у меня получается, что переменная posx при таком раскладе будет просто строкой. Или и так сойдёт?
Reply
#20

Quote:
Originally Posted by serpip
View Post
Ну так если делать
PHP Code:
new posX[20]; 
db_get_field_assoc(Result4"X"posX20); 
то чисто же должно быть дробное, а у меня получается, что переменная posx при таком раскладе будет просто строкой. Или и так сойдёт?
учите мат часть floatstr
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)