【问题标题】:Should a common data pattern be separated into its own sql table?是否应该将通用数据模式分离到自己的 sql 表中?
【发布时间】:2015-12-11 23:54:07
【问题描述】:

将多个表的公共子集分成具有类型键的自己的表是否有优先级?

示例: Hipmunk 允许您搜索带有“行程详情”的航班

{
   departure_location: Orlando,
   destination_location: Miami,
   departure_date: 2016-05-05,
   return_date: 2016-05-10
}

搜索后会有一个最近的搜索跟踪器,您可以将航班保存到“我保存的航班”中。此外,如果您预订了航班,那么大概也有记录。所以下面的表格都会有共同的“旅行细节”加上其他一些内容。

那么复制所有表中的列或为这个公共对象创建一个公共表是否有好处。如果所有 3 个表都具有 from、to、departure、arrival 或者将其抽象为一个 trip_details 表是否有好处从,到,到达,离开,类型。类型将是用于搜索、保存、预订的枚举。

我被要求提供一些示例表,所以他们在这里

方法 1

recent -> id,from,to,departure,return,user_id
saved  -> id,from,to,departure,return,user_id,flight_id
booked -> id,from,to,departure,return,user_id,flight_id,confirmation_number,payment_type... etc

方法 2

trip_details -> id,from,to,departure,return,user_id, type(recent,saved,booked)

recent -> id, trip_details_id, user_id
saved  -> id, trip_details_id, user_id, flight_id
booked -> id, trip_details_id, user_id, confirmation_number, payment_type... etc

注意: 行程详情行将永远不会在 3 个表格之间共享。方法2不会减少冗余数据

编辑 为了帮助澄清,这些不是我的表格,我试图在摘要中弄清楚这一点。也可能编程的一个例子会有所帮助。 请不要太在意实现细节,因为我正在试图弄清楚“如果 3 个表都有 5 个相同类型的列并且在概念上代表一个对象,如果该 '对象' 存在自己的表?即使移到自己的表也不会减少数据冗余?”

var recentSearch = {
    tripDetails: {
        departure_date: '2015-01-05',
        return_date: '2015-01-10',
        from: 'Orlando',
        to: 'Chicago' 
    }
}

var savedSearch = {
    tripDetails: {
        departure_date: '2015-01-05',
        return_date: '2015-01-10',
        from: 'Orlando',
        to: 'Chicago' 
    }
}

var booked = {
    flight_id: 1234,
    confirmation_number: 3456,
    book_date: '2015-12-12'
    tripDetails: {
        departure_date: '2015-01-05',
        return_date: '2015-01-10',
        from: 'Orlando',
        to: 'Chicago' 
    }

}

【问题讨论】:

  • 听起来您将从了解更多关于normalized databases 的信息中受益。这是有用的信息。
  • 将它们移动到 trip_details 不会有助于减少数据冗余,因为搜索可以存在与保存的航班相同的详细信息。看来规范化只适用于防止数据重复
  • 您只需要三个表。旅行,保存,预订。最近没看懂
  • trips 将是 all_trips_available,save 只是保存的其中一个行程,没有任何冗余细节。预订将有预订详情 + trip_id + “当前行程详情可能会在较长时间内发生变化”的日志

标签: sql database database-design


【解决方案1】:

首先,是的,一般的想法主要是尽可能减少数据冗余/重复数据。

但是也有像你介绍的那种情况,让我们总结一下,如果我在某处的解释有误,请告诉我:

三个地方 1. 行程详情 2. 我保存的航班 3. 预订航班

这里的行程详细信息是对可用行程的通用搜索,您已将其保存在“行程”表中

“我保存的航班”是一个选项,人们可以在其中保存该行程,这样他们就不必搜索了。

迄今为止最好的方法:
在“My_Saved_Flights”表中,使用“saved_on_date”和“User_ID”等数据保存“Trip”表中的“trip_ID”
现在,当您显示“我的已保存航班”时,您会使用 LEFT JOIN 获得行程及其当前价格和状态。

现在第三个是已预订的航班
这已成为历史,因此您需要看到通常的旅行时间是否会在某天或其他时候发生变化?如果需要,您需要存储这些详细信息,否则您可以存储 ID。

我更喜欢部分存储,即像这样在单个文本列中存储哪怕是最有可能发生变化的东西

{departure_location: Orlando,destination_location: Miami,departure_date: 2016-05-05,return_date: 2016-05-10}

希望对你有帮助

【讨论】:

  • 所以您更喜欢将入住详情完全非规范化为 json 对象并将其存储在单个列中?我不确定我是否在关注你。
  • 只有这种情况,并且仅针对十年后可能会改变的那些细节进行新闻报道。或者您可以创建一个 json 格式的日志文件,并将日志的 ID 存储在 DB 中。
  • 据我所知,所有数据都将来自使用 Trip_ID 的行程表 [在前两个表上],但每年/每月的日志文件将存储 json 以及为预订表生成的 id 等历史记录预订表将来自日志,而不是行程表。
  • 仅供参考:我所说的仅适用于重叠数据,任何特定于表格的数据,如金额、日期、预订时间都将正常存储在数据库中。我想你明白了。日志只会包含尽可能少的动态数据
【解决方案2】:

一般来说,您应该在整个数据库中的所有表中只让每个数据单元表示一次。例如,如果您希望用户预订航班,您将使用三个表:

用户,

飞行,

预订,

用户应包含与用户相关的所有数据(姓名、密码、地址等)。

航班应包含与航班相关的所有数据(飞机、出发时间、目的地等)。每个飞机旅程都会在表格中用一行来描述它。

然后 Booking 将保存您保存的所有航班信息以及对其他两个表的引用(因此它必须包含 userId 和 flightId 作为外键,但之后您可以根据需要添加其他信息)。

预订表也将兼作已保存的航班列表。

编辑:澄清一下,如果您想保存未预订航班的航班,您有两种选择。 1) 为保存的航班制作一个单独的表格。 2) 在您的 Booking/trip 表中添加一列,指明航班是否已预订或保存。

我个人会使用选项 2,除非与常规预订相比,有可能保存大量搜索。

EDIT2:您应该重新设计此数据库。那里有三个表,都存储相同的信息。 “最近”和“已保存”没有理由成为单独的表,或者根本就没有“最近”表。

考虑到上述模式,尝试重新设计。因此,每个航班应该在您的数据库中表示一次且仅一次,每个用户仅表示一次,然后预订的航班将是一个只有用户唯一 ID 和航班唯一 ID 的表。

如果您想在不预订的情况下保存航班,您可以复制预订航班表并将其命名为已保存的航班,或者只需将它们添加到同一个表中,并使用一些属性确定航班是已预订还是刚刚保存。

我在这里看到的最大问题是您的所有表格都包含属性(从、到、出发和返回)。所有这些都可以保存在一个表中,并在此处使用单个属性(flight_id)进行跟踪。

即使您想将保存的、最近的和预订的表分开,您也可以这样做。就目前而言,您有四个属性出现在三个表中,如果信息重复,这应该只是一个属性。

简答:

这样做:

Flight(id(pk),departmentTime,from,to,return)

用户(id(pk)、姓名等)

最近的(id(pk), User_id(fk), Flight_id(fk))

Booked(id(pk)、User_id(fk)、Flight(fk)、confirmation_no 等)

这应该可以解决您 99% 的问题。您将通过查询数据库而不是您的布局方式来处理您的其余功能。

【讨论】:

  • 我选择的表格非常重要,因为如果您在我的 3 个表格中绘制数据的 ven 图,它们就会有重叠的“旅行详细信息”交叉点。你没有这样的
  • 您没有说任何关于 ven 图的内容...无论哪种方式,将 Booking 重命名为旅行详细信息,您就可以开始了。重叠不是一件好事,你应该只有一个重叠的值,这样你就可以加入表格。其他任何事情都是冗余和糟糕的设计。任何重叠的东西都应该是一个单独的表格。
  • 数据永远不会重叠,只会重叠数据类型。因此,初始搜索将被复制为保存,以便仍然有最近的搜索和保存的搜索,保存的搜索可能会被修改,因此数据被复制。
  • 你能提供你的表格,这样问题就不会那么模棱两可了吗?另外,数据类型能够重叠是什么意思?数据类型是数据的格式,如 varchar 或 enum,它们不能重叠,每个属性一个。从您在这里所说的来看,您似乎想要保存查询,这是您可以使用包含 2 个属性 (UserId, QueryText) 的表来做的事情
  • 在问题中添加了一些示例数据源
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-21
  • 1970-01-01
  • 2012-05-12
  • 1970-01-01
  • 1970-01-01
  • 2012-03-05
相关资源
最近更新 更多