[英]Doctrine query: best approach to creating a select query joining three tables?
[英]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实际代表什么? 您是否存储了客户,以便在他们重复预订旅行时识别他们? 在我看来,情况并非如此(无论如何,您将从中得到什么?)。 从我看来,对我来说,它更像是一个旅行预订。 因此,每次Miller先生预定行程时,他都会获得一个新的customer_id。 但是,如果是这样,customer_id是否已经代表了他的完整预订? 您不需要Miller太太的customer_id,因为她会包含在预订中。
所以我看到的是预订。 这由一个人的姓名和联系方式(在我的示例中为Miller先生)加上旅客人数组成。 那将是:
订餐
表预订_乘客
数据应始终在表中,而不是表名或列名。 因此,您将不会有诸如dependentant_Fare_Child和Dependant_Fare_Adult之类的列,而是具有带有fare_id列的表booking_passengers,因此您可以基于ID进行联接。
因此,预订(或您所说的客户)已经代表了一个团体。 您是否需要有关副乘客的更多详细信息,然后将保留每个乘客一个记录的表替换为booking_passengers:
表格booking_passenger
您的旅游额外费用结构看起来不错。 当我称呼您的客户或团体预订时,我的表格将是:
表booking_extras
对于旅游价格,我假设有这样一张表格,顺便说一句:
表tour_price
上表中的主键为斜体。 您应该使用外键。 它们的存在是为了保证数据的一致性,例如不要让没有预订的乘客。 数据库人员总是将关系数据库中的外键视为理所当然,并且在数据一致性和可用索引方面都依赖于它们的存在。 因此,表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.