繁体   English   中英

从长远来看,创建SQL表以轻松查询的最佳方法是什么?

[英]What is best approach to creating SQL tables to easily query in the long run?

我目前正在为客户进行项目。 他的需求已经改变,因此我的数据库结构也必须改变。

我的客户经营一家旅行社业务,他每天要注册许多人。 他想要实现的目标是能够对乘客进行分组。 因此,在管理界面中,单击要分组的乘客,然后瞧。 他们在一个小组中。

在每个组中,您可以分配额外的费用,例如午餐,饮料,租用设备,以便员工可以将价格映射到该组。

以下是我所需要的,我的问题是如何从中构建SQL表。 我目前正在阅读一对多关系,外键等。从长远来看,我希望能够毫无问题地查询数据库,在我过去的经验中有很多问题:

Groups
gp_ID    customer_ID    leader    fare_Type    dependant_Fare_Child    dependant_Fare_Adult

Tour_Extras
TE_ID    TE_Name

Tour_Extra_Price
TE_ID    TE_Price    fare_ID

Fare_Type
fare_ID    fare_Name

Group_Extras
gp_ID    TE_ID    quantity    fare_ID

包含该组中的所有乘客。 只有一位领导者,该客户的所有联系人个人的customer_ID将用作另一张表的参考。 fare_Type将是一个整数,它将引用Fare_Type表。 Dependant_Fare_Ch和Adult也是整数。 这将确定有多少儿童和按成人价格收费的儿童被分配给受抚养人。

Tour_Extras拥有团体可拥有的附加类型。 例如午餐,装备租赁

Tour_Extra_Price会保留特定额外费用的价格以及fare_ID,这将决定要收取的价格(儿童,成人,老人)

Fare_Type包含fare_Id和名称(儿童,成人,老人)

Group_Extras这是biggy 它将引用组,tour_extra以及可能的Fare_Type表。 这将用于确定该特定组的总金额。 例如:

gp_ID TE_ID quantity fare_ID
  1     1      3       1

对于ID为1的组,他们选择了TE_ID为1(例如午餐)并购买了数量(3),并将被计入fare_ID 1(例如儿童)

这可能对某些人有帮助:

Tour_Extras可以有许多Tour_Extra_Price

Tour_Extra_Price可以有一种Fare_Type

Group_Extras可以有多个Groups,Tour_Extras和/或Fare_Type(不确定是直接与Fare_Type链接,还是先经过Tour_Extras,然后依次浏览Tour_Extra_Price和Fare_Type)

我还有其他问题,例如是否需要外键? 最好在Group_Extras表上具有主键,而在其他表上具有外键?

很长的道歉,但我想尽一切办法,然后再研究该项目。

ps我几个小时都不会回来。 因此,请提出问题,我会在12小时内回答。

您的数据库结构通常适合于您描述的需求。 我建议您添加一个“组”表,该表可用于组成员共享的常用属性,例如ID,组名(如有必要)或时间戳。 您也可以在此处直接设置领导者的ID,而不是在groups表的每一行中都具有“ leader”标志。

除此之外,我会做出一个改变; 由于您使用的是MySQL,因此您可能会选择对FareType使用ENUM字段而不是Fare_Type表(因为我假设这3个值不太可能更改-如果更改,则可以轻松添加更多值)。 这将简化查询,因为您必须减少一次连接,并且还可以使数据库在调试时更具可读性。 从理论上讲,您的解决方案是正确的,我只是更改此设置即可使您的生活更轻松(并使数据库更具可读性)。 当然,如果用户要自己编辑fareType,则必须将其保存为单独的表。

从技术上讲,您不需要任何外键-如果您仅添加主键并在更新/删除/插入逻辑中牢记这些关系,则您的应用程序将可以正常工作。 如果添加外键,则会在表上添加约束,以免破坏其完整性。 例如,如果要删除Tour_Extra,则首先必须确保没有其他表具有引用,否则将得到约束错误。 尽管情况有所改善,但我并不是很想在MySQL中使用外键,但是以前存在很多问题。 如果选择使用它们,则无论如何都需要将表设置为InnoDB数据库引擎。

您的主键应该很清楚:

  • 组-> gp_ID(自动递增)
  • 组-> gp_ID,customer_ID
  • Tour_Extras-> TE_ID(自动递增)
  • Tour_Extra_Price-> TE_ID,fareType(枚举)
  • Group_Extras-> gp_ID TE_ID,fareType(枚举)

还有外键(如果选择分配它们):

  • 组-> gp_ID引用Group.gp_ID,customer_ID引用customer.customer_ID
  • Tour_Extra_Price-> TE_ID引用Tour_Extra.TE_ID
  • Group_Extras-> gp_ID引用Group.gp_ID,(TE_ID,fareType)引用(Tour_Extra_Price.TE_ID,Tour_Extra_Price.fareType)

显然,我们彼此相距几个小时,因此请求注释部分中的问题与答案往返花费了太多时间。 因此,我没有提出更多每天提出的问题,而是我的想法:

首先:customer_id实际代表什么? 您是否存储了客户,以便在他们重复预订旅行时识别他们? 在我看来,情况并非如此(无论如何,您将从中得到什么?)。 从我看来,对我来说,它更像是一个旅行预订。 因此,每次Mi​​ller先生预定行程时,他都会获得一个新的customer_id。 但是,如果是这样,customer_id是否已经代表了他的完整预订? 您不需要Miller太太的customer_id,因为她会包含在预订中。

所以我看到的是预订。 这由一个人的姓名和联系方式(在我的示例中为Miller先生)加上旅客人数组成。 那将是:

订餐

  • booking_id
  • tour_id
  • 名称
  • 地址
  • 电话

表预订_乘客

  • booking_id
  • fare_type_id (成人/儿童/老人)
  • 数量(该预订中有多少种类型

数据应始终在表中,而不是表名或列名。 因此,您将不会有诸如dependentant_Fare_Child和Dependant_Fare_Adult之类的列,而是具有带有fare_id列的表booking_passengers,因此您可以基于ID进行联接。

因此,预订(或您所说的客户)已经代表了一个团体。 您是否需要有关副乘客的更多详细信息,然后将保留每个乘客一个记录的表替换为booking_passengers:

表格booking_passenger

  • booking_id
  • fare_type_id (成人/儿童/老人)
  • 名称
  • 年龄

您的旅游额外费用结构看起来不错。 当我称呼您的客户或团体预订时,我的表格将是:

表booking_extras

  • booking_id
  • tour_extra_id (午餐/齿轮/ ...)
  • fare_type_id (成人/儿童/老人)
  • 数量

对于旅游价格,我假设有这样一张表格,顺便说一句:

表tour_price

  • tour_id
  • fare_type_id (成人/儿童/老人)
  • 价钱

上表中的主键为斜体。 您应该使用外键。 它们的存在是为了保证数据的一致性,例如不要让没有预订的乘客。 数据库人员总是将关系数据库中的外键视为理所当然,并且在数据一致性和可用索引方面都依赖于它们的存在。 因此,表booking_extras将具有主键booking_id + tour_extra_id + fare_type_id。 您将有一个外键,用于通过booking_id预订表,通过tour_extra_id预订tour_extra和通过fare_type_id预订fare_type。

希望这可以帮助。 如果我误解了什么,请在评论中告诉我,这样我将希望有时间相应地调整我的答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM