我正在编写一个应用程序来管理酒店的房间,我设计数据库来管理折扣价格。 我已经制作了房间和价格表,现在我已经创建了一些表格,我可以根据某些条件存储管理员可以应用的折扣。管理员也可以创建新的折扣。 例如:
所以,这是我的简化表(我省略了与问题无关的字段和关系):
房间
id | name
---|----------------
1 | Trafalgar Square
2 | Piccadilly
价格:
id | room_id | base | promotion
---|----------|------|-----------
1 | 1 | 10 | 8
2 | 2 | 25 | 20
如何存储上述条件?
我正在使用Rails,我想到的第一个解决方案是创建一个表,我可以存储折扣,并应用它的条件。
我认为字段条件是一个SQL片段;像Reservation.start_date > [date]
之类的东西,因此我可以在Rails中应用更多折扣连接它们。
但这是一个非常难看的解决方案,并且与DBRMS相结合,所以我想避免这种选择。
你知道我怎样才能解决这个问题? 我希望能够清楚地解释这个问题。
答案 0 :(得分:2)
我强烈建议您调查使用某种类型的规则引擎进行处理。
问题在于,与许多行业一样,酒店使用极其流畅的定价方式。有些看似异想天开,有些与思想几乎没有相似之处,而且很难为其创造一种结构化的方法。
例如,如果预订一晚并且客户在晚上11:00之后进行预订,则客房将享受10%的折扣优惠...除非是周五或周六晚或酒店的客房容量为80%+。 / p>
如果1月标准折扣为15%,则此规则可能会被中断。
如果会议安排在城镇,那么该规则可能会中断。此时房价提高了30%。
另一种方法是简单地放弃让系统自动计算房价,而是依靠酒店工作人员在预订时设置它们。在这种情况下,您只需显示一些关于当前“特价”的指南。
当然,这并不像自动做那样性感,但如果有问题的酒店不会购买已经这样做的COTS,那么他们可能无法支付正确的费用。发展它。
答案 1 :(得分:2)
很棒的问题。
我从未参与过酒店预订系统,但曾参与过有折扣策略的电子商务项目,坏消息是这可能会非常复杂。
例如,您可能有多个适用于特定预订的折扣,如果累积或相互排斥(如果有“每次预订的10%”折扣,并且预订符合条件,则需要计算出来)一个“新婚25%的报价”,你给10%,25%或35%?)。如果你必须处理税收,它甚至更奇怪 - 如果总预订有多个产品,具有不同的税率,你如何在应用折扣后计算税收?
如果您正在建立一个允许用户指定新(折扣类型)系统的系统,并且所有规则都与之相符,那么您的项目将变得相当大,非常复杂,并且对折扣很着迷发动机。
如果那是你所处的世界,那就听@Chris Lively的回答。投资规则引擎,并准备花费下一个重要时间来解释折扣如何运作,“和”,“或”,“xor”等等。
但理想情况下,您可能会花费更多时间来完善实际的当前要求。如果您只需要解决5个实例,那么选项比构建通用折扣引擎要有限。查看策略模式和复合模式。如果它不是“通用”,那么制作“2012夏季”折扣策略并不会感到羞耻,因为有效日期是硬编码而不是存储在数据库中。
答案 2 :(得分:2)
通常情况下,预订人员有权申请不同的折扣。换句话说,折扣的规则只是回顾性地进行现场检查。
让系统自动检查给定折扣的资格将很快变为:
折扣往往是营销问题。在这种情况下,您想知道客户要求的折扣(“琼斯婚礼折扣”),而不是通过规则严格控制折扣的资格。
折扣系统的一个更有用的方面是签入系统,以查看折扣是否要求客户显示折扣资格证明,如果是,则提示办理登机手续。如果在预订中使用公司的合同折扣率,请询问员工ID。
酒店预订和房间管理系统非常复杂。您应该了解为什么酒店没有使用COTS(商业现货)软件。
答案 3 :(得分:0)
这是我评论的扩展版本。我同意在数据库中放入SQL /可执行代码通常是一个坏主意,我认为在这种情况下你可以避免这种情况。
我会这样做:
promotion ------------------------------------------------------------ id (pk) | shortname (uniq) | params? | serialised_params? 1 | september_promo | ... | 2 | long_stay | ... | ------------------------------------------------------------ room_promotion ---------------------------------------------------- room_id (fk) | promotion_id (fk) | serialised_params 1 | 1 | { discount=10; start_date=x; end_date=y } 2 | 2 | { length=14 } ----------------------------------------------------
此方法为您提供了可能要运行的各种促销活动的最大灵活性。由于每个促销都有许多参数,具体取决于业务逻辑,我建议在每个房间的情况下,您有一列序列化参数,因此您不必拥有大量未使用的列这张桌子。 请记住,这确实打破了一些关系规则,但是谨慎使用并且意识到其局限性,这是一种有用的方法。
您也可以同时针对每个促销行设置参数或序列化参数(例如,如果您知道' long_stay'促销的所有用途将持续14天)。
注意我已安排了' room_promotion'表格,以便可以将多个促销应用于房间。如果您确定始终只 ,那么您可以将(room_id, promotion_id)
作为主键。
好的,所以现在你有一个促销规则的机制'可以应用。但是,业务逻辑仍然属于您的代码。因此,查找短名称,驼峰式案例,然后在Ruby中使用动态查找机制来应用折扣。我没有使用Ruby,但在PHP草图形式中它可能看起来像这样:
Get object $Bill (prior to discount being applied) $Discount = DiscountFactory::getInstance( 'september_promo', unserialize($serialised) ); $Bill->applyDiscount($Discount); Display modified bill
在内部,我认为september_promo
被转换为SeptemberPromo
,这是一个类(抱歉,PHP再次):
class SeptemberPromo extends Promotion { // Add in concrete implementation of abstract method here public function executeDiscount($Bill) { ... } }
反过来,促销可以有一个抽象方法,由applyDiscount()
用来确定要应用的折扣,给定每个房间的值,每个促销价值和账单的详细信息。
只要您的折扣业务逻辑保持相当通用,您的酒店经理就可以使用序列化参数对其进行自定义,而不是每次新的促销都需要新的Ruby代码(除非他们想要促销类型< / em>这是新的)。考虑到这一点, SeptemberPromo 可能过于具体 - 也许 MonthSpecial ?
显然,您需要构建一个用户界面,让酒店经理存储新的promotion
和room_promotion
行,但这应该非常简单。