В этом посте я бы хотел поговорить о стандартах хранения цен и способах работы с такими стандартами. Представьте, что у вас есть услуга, цена на которую действует все лето. То есть с 1 июня по 31 августа. Разумно было бы хранить ее так.
CREATE TABLE [Costs]( [id] int NOT NULL PRIMARY KEY ,[cost] money NOT NULL ,[begin] [smalldatetime] NOT NULL ,[end] [smalldatetime] NOT NULL ); GO insert into [Costs] ([id],[cost],[begin],[end]) select 1, 500, convert(smalldatetime,'01.06.2012',104), convert(smalldatetime,'31.08.2012',104)
Давайте приблизим ситуацию к реальности, часто спрос на услуги зависит от дня недели. Например об аренде домика на озере в жаркие выходные стоит подумать заранее, при этом этот же домик с понедельника по четверг, скорее всего, будет стоять пустым. Бизнес это понимает и делает шаг на встречу клиентам, снижая цены по будням.
Теперь два раза в неделю цена на услугу будет изменять. Если мы будем действовать по старой схеме, вместо 1 записи указывающей цену на 3 месяца, придется заводить 2 записи на каждую неделю, которых в летние месяцы более 13(итого более 26 записей). Что довольно неприятно.
Во многих системах работающих в туристическом сегменте является практически стандартом хранения данных в следующем виде.
CREATE TABLE [Costs]( [id] int NOT NULL PRIMARY KEY ,[cost] money NOT NULL ,[begin] [smalldatetime] NOT NULL ,[end] [smalldatetime] NOT NULL ,[week] char(7) NOT NULL ); GO insert into [Costs] ([id],[cost],[begin],[end],[week]) select 1, 500, convert(smalldatetime,'01.06.2012',104), convert(smalldatetime,'31.08.2012',104), '....567' union all select 2, 400, convert(smalldatetime,'01.06.2012',104), convert(smalldatetime,'31.08.2012',104), '1234...'
Поле week хранит дни недели, в которые действует эта цена. Каждый день недели от понедельника до воскресенья пронумерован от единицы до семи соответственно. Для i от 1 до 7, если на i-ой позиции стоит i, то цена действует в этот день недели, если ".", то нет.
Решение неплохое. Позволяет сэкономить место на диске и время сотрудника вносящего информацию о ценах в систему. Осталась одна загвоздка, как преобразовать хранящиеся данные к набору не пересекающихся отрезков, и именно об этом пойдет речь под катом.
