|
50.9 Кб |
|
| Пишу админку.
Есть отели, типы номеров в них, в номерах - атрибуты(удобства).
Есть даты заезда в эти отели в определенный тип номера.
2 даты заезда к определенному типу номера пишутся в колонке сверху. См. рисунок в аттаче.
У меня подозрение, что относительно даты и цен я спроектировала неправильно.
Потому как не получается вывести столбцы в таблицу с датой и ценами за эти даты к определенному типу номера.
CREATE TABLE `rnt1_hotel` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;
CREATE TABLE `rnt1_room` (
`id` int(11) NOT NULL auto_increment,
`type_room` varchar(255) NOT NULL,
`id_hotel` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `id_hotel` (`id_hotel`)
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;
CREATE TABLE `rnt1_date` (
`id` int(11) NOT NULL auto_increment,
`date` date NOT NULL,
`id_type_room` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `id_type_room` (`id_type_room`)
) ENGINE=MyISAM AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 AUTO_INCREMENT=9 ;
CREATE TABLE `rnt1_price` (
`id` int(11) NOT NULL auto_increment,
`price` int(11) default NULL,
`id_hotel` int(11) NOT NULL,
`id_type_room` int(11) NOT NULL,
`id_date` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `id_hotel` (`id_hotel`,`id_type_room`,`id_date`)
) ENGINE=MyISAM AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 AUTO_INCREMENT=9 ;
|
| |
|
|
|
|
|
|
|
для: Лена
(22.12.2010 в 13:57)
| | дата заезда - сама по себе не сущность, а атрибут оной.
Если я правильно понимаю, то сущностью является заезд, аренда, бронирование или что-то подобное.
Вот у него уже и есть атрибут даты. | |
|
|
|
|
|
|
|
для: Trianon
(22.12.2010 в 14:29)
| | У каждого отеля есть определенные дни заезда - в таблице пишется по две даты в одном столбце.
Все это касается бронирования отелей.
Получается, дата - аттрибут отеля и выходит, надо делать таблицу даты и в ней поле id_hotel - соотнесенность даты к определенному отелю. | |
|
|
|
|
|
|
|
для: Лена
(22.12.2010 в 14:51)
| | Ээээ...это как?
В другие дни отель не допускает заселение ни для кого?
Что-то не верю вообще. | |
|
|
|
|
|
|
|
для: Trianon
(22.12.2010 в 14:53)
| | Запуталась совсем...
Не так. В отеле есть типы комнат. В определенные дни доступны по определенной цене какие-то типы комнат. Каждую дату, получается, надо привязать к определенному отелю и к определенному типу комнат в нем. Только там в столбце по две даты. Каждую из них мы привяжем, а как их вместе вывести по парам? | |
|
|
|
|
|
|
|
для: Лена
(22.12.2010 в 15:09)
| |
отели типы номеров
\ /
-- связка с датой и ценой -
|
| |
|
|
|
|
|
|
|
для: Trianon
(22.12.2010 в 15:34)
| | что ж это получается...
мне надо таблицу-связку делать, где я укажу id_hotel - id_room_type - id_date - id_price?
таблица с датами, и таблица с ценами тогда остается | |
|
|
|
|
|
|
|
для: Лена
(22.12.2010 в 17:18)
| | почему id_date и id_price?
почему не просто дату и цену?
Нет ну то есть если эта цена - некоторое специальное коммерческое предложение, имеющее сввою запись в таблице прайса с кучей сопутствующих свойств - тогда конечно.
Но на пустом месте-то зачем? | |
|
|
|
|
5.6 Кб |
|
|
для: Trianon
(22.12.2010 в 18:11)
| | Исправила, спасибо.
Все равно делаю вывод и в выводе не получается ни даты, ни цены вывести.
Уже один запрос с JOIN`ами разбила на несколько, каждый из которых работает только с одной таблицей, все равно шапка таблицы, где дата, выводится неправильно. Лишнее выводится.
Получается теперь я вывожу в цикле отели, внутри этого цикла - типы комнат в отеле, внутри этого - еще один цикл, который служит для вывода дат и цен.
Но у меня даты и цены к датам выводятся в разных местах таблицы.
Я скрипт для наглядности прикрепила. | |
|
|
|
|
|
|
|
для: Лена
(23.12.2010 в 01:35)
| | >Исправила, спасибо.
какая структура получилась в результате? | |
|
|
|
|
|
|
|
для: Trianon
(23.12.2010 в 08:58)
| |
-- Структура таблицы `rnt1_hotel`
--
CREATE TABLE `rnt1_hotel` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(255) NOT NULL,
`visible` varchar(2) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;
CREATE TABLE `rnt1_room` (
`id` int(11) NOT NULL auto_increment,
`type_room` varchar(255) NOT NULL,
`id_hotel` int(11) NOT NULL,
`visible` varchar(2) NOT NULL,
PRIMARY KEY (`id`),
KEY `id_hotel` (`id_hotel`)
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;
CREATE TABLE `rnt1_room_attrs` (
`id` int(11) NOT NULL auto_increment,
`price` int(11) NOT NULL,
`date` date NOT NULL,
`id_room` int(11) NOT NULL,
`id_hotel` int(11) NOT NULL,
`visible` varchar(2) default NULL,
PRIMARY KEY (`id`),
KEY `id_hotel` (`id_hotel`),
KEY `id_room` (`id_room`),
KEY `id_room_2` (`id_room`)
) ENGINE=MyISAM AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 AUTO_INCREMENT=9 ;
|
| |
|
|
|
|
|
|
|
для: Лена
(23.12.2010 в 10:13)
| | Как оказалось, даты - это интервалы стоимости, например,
интервал1
даты 28.12.2010-09.01.2011 стоимость 120дол для определенных типов номеров,
интервал2
даты 01.11.2010-01.04.2011 стоимость 90дол
После эти интервалы вводятся в поиске, т.е. нужно будет делать сортировку по начальной и конечной дате интервала.
Получается, надо создавать отдельную таблицу для интервалов дат:
id - date_start - date_end и связывать ее по ключу с таблицей, где лежит цена. | |
|
|
|
|
|
|
|
для: Лена
(23.12.2010 в 16:09)
| | >Получается, надо создавать отдельную таблицу для интервалов дат:
>id - date_start - date_end и связывать ее по ключу с таблицей, где лежит цена.
Конечно.
Сам мучался когда делал, кстати, сами даты я хранил по другому, но неизвестно, правильно ли: у меня дата как timestamp, так удобно считать периоды и чего-то ещё, уже не помню, но проблема возникнет при смене года, все интервалы разом устареют и их для правильной работы придётся обновить. Другого способа хранить интервал пока не придумал, вот скоро вернусь к этой задаче. | |
|
|
|
|
|
|
|
для: Лена
(23.12.2010 в 16:09)
| | Именно.
Только интервалы удобнее задавать открытыми справа отрезками. [a b[
Иначе код, вычисления пересечения окажется сильно сложным, соответственно усложнятся запросы по условию наложения интервалов, а значит и прикладной код добавления нового интервала. | |
|
|
|
|
|
|
|
для: Trianon
(23.12.2010 в 23:56)
| | >Только интервалы удобнее задавать открытыми справа отрезками. [a b[
ммм... то есть? только даты начала периода?
но ведь это не отменяет проблему смены года.
для Лены: и ещё, у вас возможно всплывёт вопрос с високосными годами и минутами-секундами. | |
|
|
|
|
|
|
|
для: Zilog
(24.12.2010 в 00:11)
| | >>Только интервалы удобнее задавать открытыми справа отрезками. [a b[
>ммм... то есть?
математика, 4-й класс.
только даты начала периода?
только дата начала - это уже луч.
почему?
момент завершения периода тоже хранить нужно.
>для Лены: и ещё, у вас возможно всплывёт вопрос с високосными годами и минутами-секундами.
Ниичего там не всплывет. (То есть всплывет, и многое, оно всяко не это :))
моменты времени абсолютные, потому что цены привязаны к сезонам конкретного года. | |
|
|
|
|
|
|
|
для: Trianon
(24.12.2010 в 00:21)
| | >момент завершения периода тоже хранить нужно.
ну, так так и храним. Я не понял формулировку про "открытые отрезки". Что значит открытые? Не серчай, 4 класс давно был :)
>>для Лены: и ещё, у вас возможно всплывёт вопрос с високосными годами и минутами-
>Ниичего там не всплывет. (То есть всплывет, и многое, оно всяко не это :))
>моменты времени абсолютные, потому что цены привязаны к сезонам конкретного года.
Ну как не всплывёт? Если время в начало/конец периода указывать 00:00:00/23:59:59, то конечно не всплывёт. А если просто датами оперировать - то всплывёт, ибо при записи в БД он туда текущую сунет. А тут это важно — ибо расчёт в гостиницах требует точности, более того, там ещё куча нюансов. Например, если ОТ в этом году, ДО - в следующем. Или между ОТ и ДО целиком несколько периодов, но это уже другая задача.
upd1. Да, ещё помню был геморой с переводом часов в летнее/зимнее время — так вообще пришлось к грнвичу прибегнуть.
upd2. Да, високосные не причём. Перепутал с переводом стрелок, а то помню что с чем-то намучился :) | |
|
|
|
|
|
|
|
для: Zilog
(24.12.2010 в 01:14)
| | >>момент завершения периода тоже хранить нужно.
>
>ну, так так и храним. Я не понял формулировку про "открытые отрезки". Что значит открытые? Не серчай, 4 класс давно был :)
Неужто давнее, чем у меня? :)
к примеру, эта неделя (по российской локали):
Закрытый отрезок [20 декабря .... 26 декабря]
Открытый отрезок [20 декабря .... 27 декабря[
Эти сутки:
Закрытый отрезок: [24дек/00:00 ... 24дек/23:59]
Открытый отрезок [24дек/00:00 ... 25дек/00:00[
и т.п.
>>>для Лены: и ещё, у вас возможно всплывёт вопрос с високосными годами и минутами-
>>Ниичего там не всплывет. (То есть всплывет, и многое, оно всяко не это :))
>>моменты времени абсолютные, потому что цены привязаны к сезонам конкретного года.
>
>Ну как не всплывёт? Если время в начало/конец периода указывать 00:00:00/23:59:59, то конечно не всплывёт. А если просто датами оперировать - то всплывёт, ибо при записи в БД он туда текущую сунет.
В поле data кроме даты сложно что-то сунуть. Хотя с точными моментами возни меньше. | |
|
|
|
|
|
|
|
для: Trianon
(24.12.2010 в 01:34)
| | >Неужто давнее, чем у меня? :)
не думаю, скорее всего у меня в этой части мозга регенерация памяти нестабильно работает :)
>к примеру, эта неделя (по российской локали):
>Закрытый отрезок [20 декабря .... 26 декабря]
>Открытый отрезок [20 декабря .... 27 декабря[
ясно, спасибо. Я хранил данные закрытыми отрезками. Сейчас выясняется, что лучше открытыми. Чем? Как это упростит работу?
В своей админке я сделал так: юзер задаёт только даты начала периодов. Конечная дата ("закрытая") вычисляется автоматически. Проблем с расчётом цен по сезонам особых не помню (только на гринвича пришлось перейти), алгоритм получился не такой уж и сложный. Так чем открытые даты могут упростить код?
>Иначе код, вычисления пересечения окажется сильно сложным, соответственно
>усложнятся запросы по условию наложения интервалов, а значит и прикладной код
>добавления нового интервала.
Вот как у меня это работало:
код нашёл, но что то он слишком великоват, что бы его сюда постить. может дейстительно стоит подумать над оптимизацией? :)
|
| |
|
|
|
|
|
|
|
для: Zilog
(24.12.2010 в 01:45)
| | Если есть интервалы времени, обычно (при добавлении очередного интервала чаще всего, но не только) приходится решать задачи вычисления пересечения интервалов, а иногда разности и объединения.
Дано: ааааааааааааа
bbbbbbbb
Найти: ссссс
|
На открытых отрезках оно вычисляется на раз.
На закрытых - нудно и противно.
А если это вычисление нужно в условие JOIN ON закатать, так там вообще крышка настает. | |
|
|
|
|
|
|
|
для: Trianon
(24.12.2010 в 02:38)
| | >На открытых отрезках оно вычисляется на раз.
>На закрытых - нудно и противно.
>А если это вычисление нужно в условие JOIN ON закатать, так там вообще крышка настает.
Тема интересная, важная. Надо будет в отдельный топик вынести, наверняка ещё много кому понадобится. | |
|
|
|
|
26 Кб |
|
|
для: Zilog
(24.12.2010 в 01:14)
| | У меня формат даты в базе - date.
Только что поиск дописала, запросы были типа:
SELECT *
FROM rnt1_room_attrs
WHERE id_hotel =1
AND (
(
date_start >= '2010-12-01'
AND date_start < '2010-12-24'
)
OR (
date_end >= '2010-12-01'
AND date_end < '2010-12-24'
)
)
AND price <=100
LIMIT 0 , 20
Не получается разложить таблицу в админке. Диапазоны дат - указала, цены неправильно выводятся. В чем проблема, я поняла, как из нее выйти, не знаю.
Должно получиться так, как на картинке - см. аттач. Значения, обведенные красным, не должны быть - здесь окна должны быть пустыми.
Как делала.
Вывела даты в шапке, берем диапазоны, которые принадлежат определенному отелю:
$q2 = "SELECT * FROM rnt1_room_attrs WHERE id_hotel=" . $row['hid'];
дальше в цикле я вывожу шапку.
Цены мне надо вывести ниже, причем сделать столько столбцов. как в шапке.
Делаю ниже еще раз этот запрос, и опять вывожу в цикле цены.
И получается, что у меня во всех ячейках - одинаковые значения. Т.е. там, где за определенный диапазон даты цены нет(в ячейке должно быть пусто), у меня заполнено.
Привожу кусок кода, который выводит одну строку таблицы:
ТИП КОМНАТЫ- ЦЕНЫ ЗА ПЕРИОДЫ
<tr bgcolor="#DFE0FF">
<td align="center" >
<input type="checkbox" name="sel[]" value="<?php print $row1['id']?>" <?php print $checked;?>>
</td>
<td width="300" align="center"><nobr><span style="padding:7px;">
<?php print $row1['type_room']?></span></nobr>
</td>
<td>
<table border="1" width="100%" cellpadding=5 cellspacing=0><tr>
<?php
$qw = "SELECT * FROM rnt1_room_attrs rra1
WHERE id_hotel=" . $row['hid'];
$resw = mysql_query($qw);
if(!$res5) exit("Error in " . $qw . mysql_error());
while($roww=mysql_fetch_assoc($resw)){
if(ЗДЕСЬ НАДО ЗАДАТЬ ДЛЯ ЦЕНЫ УСЛОВИЕ, ЧТОБЫ СОГЛАСОВАТЬ ЦЕНУ С ДАТОЙ){
?>
<td width="50" align="center"><input type="text" value="<?php print $roww['price']?>" name="price1"></td>
<?php
}else{
?> <td width="50" align="center"><input type="text" value="" name="price1"></td>
<?php
}
}
?>
</tr></table>
</td>
</tr>
|
Как мне правильно разложить таблицу по горизонтали?
Если кто-то делал, помогите, пожалуйста. | |
|
|
|
|
|
|
|
для: Лена
(24.12.2010 в 01:39)
| | >Как мне правильно разложить таблицу по горизонтали?
>Если кто-то делал, помогите, пожалуйста.
Лена, почитайте, что мы с Трианоном тут наговорили. Боюсь, если вы не внесётсе на этом этапе существенные изменения в логику работы вашего алгоритма, потом вам придётся очень много переделывать. А таблицу разложить всегда можно успеть.
Да, думаю задачка не так проста, как она вам представляется. | |
|
|
|
|
|
|
|
для: Лена
(22.12.2010 в 13:57)
| | может поможет http://red-stones.ru/test/reserve/ | |
|
|
|
|