[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Перемещение данных по таблицам
Марафонец
Доброго времени суток!

Долгое время использовал PHP на уровне "подкрутить чужой код" с помощью мануала и поисковиков. Сейчас понадобилось написать скрипт с нуля. В общем, можно сказать, что я новичок, и пришел за советом...


Если кратко задача такая: Пользователи работают с таблицей заказов, редактируют их, создают и удаляют. Как только наступает новый месяц нумерация заказов у них меняется, сортировка должна затрагивать только заказы текущего месяца. В тоже время нужна возможность работать с заказами трех прошедших месяцев.

Я создал 4 таблицы (текущий, прошедший, позапрошлый, позапозапрошлый). Как только наступает новый месяц происходить перемещение данных по таблицам. Поскольку я только начинающий поэтому думаю, что код можно упростить и улучшить, вот только не знаю в какую сторону копать...

<?php

//Растасовка таблиц по месяцам

function sortByMonth() {

// Определяем текущий месяц в цифровом формате
$cur_month = date('n');

// Прошлый месяц, нафига он тут, еще не знаю
$month_first = date('n',strtotime('-1 month'));

// Позапрошлый месяц
$month_second = date('n',strtotime('-2 month'));

// Позапозапрошлый месяц
$month_third = date('n',strtotime('-3 month'));

// Проверяем месяц последней записи

$result = db_query('Select * FROM zn order by id desc limit 0,1');
// цикл по всем выбранным записям
while($row = mysql_fetch_array($result))
//месяц хранится в столбце rezerv2
$out = $row['rezerv2'];
// уничтожаем результат
mysql_free_result($result);



// Если месяц последней записи отличается от текущего, то выполняем нужные действия над таблицами в БД
if($out == $cur_month)
{
// А вдруг потребуются какие либо действия
}
else
{
//Удаляем самую старую таблицу
db_query('DROP TABLE IF EXISTS third_last');
//Копируем в самую старую данные из предыдущей
db_query('create table `third_last` as select * from `sec_last` where 1 ');

//Делаем еще одно перемещение данных
db_query('DROP TABLE IF EXISTS sec_last');
db_query('create table `sec_last` as select * from `first_last` where 1 ');

//И еще одно
db_query('DROP TABLE IF EXISTS first_last');
db_query('create table `first_last` as select * from `zn` where 1 ');

//Чистим активную таблицу
db_query('TRUNCATE zn');

//Вставляем в таблицу системную строку с указанием текущего месяца
//чтобы небыло безконечного перемещения таблиц

$nar_sys = 0;
$datetime_sys = 'system';
$sroki_sys = $comment_sys = $rezerv1_sys = '';
db_query_ex('INSERT INTO zn (nar, sroki, comment, rezerv1, rezerv2,
datetime) VALUES(?, ?, ?, ?, ?, ?)'
, $nar_sys, $sroki_sys,
$comment_sys,$rezerv1_sys, $cur_month, $datetime_sys);

}
}




Просьба сильно не хохотать :rolleyes:



Спустя 24 минуты, 52 секунды (3.12.2010 - 22:59) kirik написал(а):
А зачем четыре таблицы, и такая сложная система копирования? smile.gif

Спустя 7 минут, 17 секунд (3.12.2010 - 23:06) Марафонец написал(а):
Цитата (kirik @ 3.12.2010 - 19:59)
А зачем четыре таблицы, и такая сложная система копирования? smile.gif

Когда скрипт уже был готов, оказалось что нужно для каждого месяца своя нумерация заказов, по быстрому написал вот ЭТО huh.gif

Я понимаю что если подойти грамотней к задаче, можно просто сконструировать одну таблицу и работать с ней, но поскольку нужно было быстро, написал первое что пришло в голову smile.gif

Насколько ресурсозатратны такие копирования, если примерно в каждой таблице не больше 1000 записей?

Спустя 20 минут, 7 секунд (3.12.2010 - 23:27) kirik написал(а):
Цитата (Марафонец @ 3.12.2010 - 15:06)
Насколько ресурсозатратны такие копирования, если примерно в каждой таблице не больше 1000 записей?

Тут скорее вопрос наскольно они нужны эти копирования? smile.gif Если нумерация заказов нужна по месяцам, то можно сделать все в одной таблице, просто добавить еще одну колонку, в которую будет записываться месячная нумерация.

Спустя 16 минут, 49 секунд (3.12.2010 - 23:43) Марафонец написал(а):
Цитата (kirik @ 3.12.2010 - 20:27)
Тут скорее вопрос наскольно они нужны эти копирования? smile.gif Если нумерация заказов нужна по месяцам, то можно сделать все в одной таблице, просто добавить еще одну колонку, в которую будет записываться месячная нумерация.

Очень не хотелось менять структуру таблицы и переписывать запросы sad.gif Понимаю, что костыль придумал... ну ладно, сейчас набросаю структуру новой таблицы и буду тут спрашивать, если что, надо же как-то учиться хорошо программировать smile.gif

Спустя 22 минуты, 31 секунда (4.12.2010 - 00:06) Марафонец написал(а):
Застопорился вот на каком моменте, какой тип столбца указывать для номера заказа? SMALLINT или INT? Разница только в допустимом максимальном значении? Или же если указать SMALLINT то таблица будет меньше жрать ресурсов на сервере?

Заранее спасибо rolleyes.gif

Спустя 10 минут, 58 секунд (4.12.2010 - 00:17) waldicom написал(а):
INT или BIGINT

Спустя 6 минут, 10 секунд (4.12.2010 - 00:23) kirik написал(а):
Цитата (Марафонец @ 3.12.2010 - 15:43)
надо же как-то учиться хорошо программировать

Поддерживаю!


Цитата (Марафонец @ 3.12.2010 - 16:06)
Разница только в допустимом максимальном значении? Или же если указать SMALLINT то таблица будет меньше жрать ресурсов на сервере?

Да, разница только в максимальном значении. Если есть уверенность что всего заказов не будет больше 65535, то указывайте SMALLINT unsigned как уникальный номер заказа, и, если ежемесечно не будет более 255 заказов, то TINYINT unsigned для столбца с месечным номером заказа.
В любом случае вы всегда сможете поменять на более "широкий" тип.

ЗЫ.
про типы можно посмотреть тут.

Спустя 31 минута, 27 секунд (4.12.2010 - 00:54) Марафонец написал(а):
Читаю по ссылке требования к памяти можете разъяснить, если указать тип int запись сожрет 4 байта памяти, даже если число будет не больше 65535?

Вопрос конечно не праздный, но мне интересно просто, сколько можно выиграть на определении более "узкого" типа данных

И вопрос совершенно идиотский )) при определении типа данных в скобках можно указать максимальный размер вывода, это что? число знаков? т.е. int(5) может иметь максимальное значение 99999?


Спустя 3 часа, 4 минуты, 42 секунды (4.12.2010 - 03:59) kirik написал(а):
Цитата (Марафонец @ 3.12.2010 - 16:54)
тип int запись сожрет 4 байта памяти, даже если число будет не больше 65535?

Так точно. Просто под разные типы резервируется разное количество байт.

Цитата (Марафонец @ 3.12.2010 - 16:54)
сколько можно выиграть на определении более "узкого" типа данных

Если сравнивать int и smallint - выйгрыш по скорости доступа будет не значительный (если вообще будет). Тут не столько дело в скорости, сколько в выйгрыше дискового пространства. Тоесть если указать int, хотя использоваться будет максимум smallint мы выйграем 2 байта с каждой записи: 2*65535=127KB не много, но все равно приятно smile.gif

Цитата (Марафонец @ 3.12.2010 - 16:54)
ри определении типа данных в скобках можно указать максимальный размер вывода, это что? число знаков? т.е. int(5) может иметь максимальное значение 99999?

В мане по типам данных написано:
Цитата (http://dev.mysql.com/doc/refman/5.0/en/numeric-types.html)
For example, a column specified as SMALLINT(3) has the usual SMALLINT range of -32768 to 32767, and values outside the range permitted by three digits are displayed in full using more than three digits.
When used in conjunction with the optional (nonstandard) attribute ZEROFILL, the default padding of spaces is replaced with zeros. For example, for a column declared as INT(4) ZEROFILL, a value of 5 is retrieved as 0005.
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.