如何创建一个数据库来显示一组公寓的可用性日历?

jam*_*mes 8 sql database postgresql database-design ruby-on-rails

语境:

最好的例子是 AirBnB。假设我有 5 套公寓。每间公寓都有一个日历,代表它的可用性。当度假者前往我的城市并使用给定的开始日期和结束日期搜索公寓时,如果该时间段在我的任何公寓的日历上显示为可用,我希望这些公寓显示在搜索结果中游客。

一点一点:

显然上面有很多。这个问题的范围是我应该如何为包含可用性的公寓列表设置数据库。在构建数据库之前,我花了一些时间在 Excel 中手动协调,以便在脑海中更清晰地了解一切应该是什么样子。在 Excel 中,我发现可以用作表格的列标题的是:

  • 公寓名称
  • 所有者_id
  • 公寓描述
  • 日历

现在的日历是我遇到的问题。从字面上看,在我的 Excel 中,列只是持续到永恒的日期。每当度假者提交请求时,我都会找到每个日期单元格为空(例如,可用)的所有公寓。然后我将这些公寓送给度假者。当他/她进行预订时,我会返回 Excel 并在所选的特定公寓的每个日期单元格中标记不可用。

我想获得更多意见......这是我应该在 PostGreSQL 中想象我的数据库的正确方式吗?如果是这样......我可以进行如下所示的迁移吗?

class CreateApartments < ActiveRecord::Migration
  def change
    create_table :apartments do |t|
      t.string  :apt_name
      t.integer :apt_owner
      t.text    :apt_description

      Date.today..Date.new(2034, 12, 31)).each do |date|
          t.date :date
      end

      t.timestamps
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

Tom*_*eif 7

您不应该存储可用性,而是相反(公寓是在特定日期预订的)。如果没有任何更深入的分析,我会做一些简单的事情:

owner
  owner_id
  owner_name

apartment
  apartment_id
  apartment_name
  apartment_description
  owner_id

customer
  customer_id
  customer_name

booking
  booking_id
  customer_id
  apartment_id
  booking_start
  booking_end
Run Code Online (Sandbox Code Playgroud)

如果可以预订不相交的日子:

booking
  booking_id
  customer_id
  apartment_id

booking_calendar
  booking_id
  booking_date
Run Code Online (Sandbox Code Playgroud)

在任何情况下,您都可以很容易地返回可用公寓的列表。

select
 *
from
 apartments a
 where not exists 
  (select 
     1
   from 
     bookings b 
   where 
      a.apartment_id = b.apartment_id 
      and (
        <<required_start>> between booking_start and booking_end
        or
        <<required_end>> between booking_start and booking_end
        )
Run Code Online (Sandbox Code Playgroud)

  • 虽然在大多数情况下没有预订的公寓确实有空房,但您可能会遇到由于维修或类似原因而没有空房的情况。您可能还想跟踪此类“不可用”的情况,然后返回可用的房间。 (2认同)