简体   繁体   English

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

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

I'm currently working on a project for a client. 我目前正在为客户进行项目。 His needs have changed and so my database structure has to change too. 他的需求已经改变,因此我的数据库结构也必须改变。

My client runs a tour operator business and he registers many people per day. 我的客户经营一家旅行社业务,他每天要注册许多人。 What he wants to achieve is to be able to group passengers. 他想要实现的目标是能够对乘客进行分组。 So in the admin interface, you click the passengers you want to group, and voila. 因此,在管理界面中,单击要分组的乘客,然后瞧。 They're in a group. 他们在一个小组中。

In each group, you can assign extras eg lunch, drinks, hire gear so staff members can map a price to that group. 在每个组中,您可以分配额外的费用,例如午餐,饮料,租用设备,以便员工可以将价格映射到该组。

The following is the what I need, my questions is how do I build the SQL tables from this. 以下是我所需要的,我的问题是如何从中构建SQL表。 I'm currently reading through one-many many-many relationships, foreign keys etc. In the long run I want to be able to query the database without any issues, had many issues in my past experience: 我目前正在阅读一对多关系,外键等。从长远来看,我希望能够毫无问题地查询数据库,在我过去的经验中有很多问题:

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

Groups Contains all the passengers in that group. 包含该组中的所有乘客。 There will only be one leader and the customer_ID will be used as a reference to another table for all contact personal for that passenger. 只有一位领导者,该客户的所有联系人个人的customer_ID将用作另一张表的参考。 The fare_Type will be an int which will reference the Fare_Type table. fare_Type将是一个整数,它将引用Fare_Type表。 the dependant_Fare_Ch and adult are integers too. Dependant_Fare_Ch和Adult也是整数。 this will determine how many children and children charged at adult prices are assigned to the dependant. 这将确定有多少儿童和按成人价格收费的儿童被分配给受抚养人。

Tour_Extras holds types of extras group can have. Tour_Extras拥有团体可拥有的附加类型。 eg lunch, gear hire 例如午餐,装备租赁

Tour_Extra_Price holds prices for particular extra as well as fare_ID which will determine what price to charge (child, adult, senior) Tour_Extra_Price会保留特定额外费用的价格以及fare_ID,这将决定要收取的价格(儿童,成人,老人)

Fare_Type holds the fare_Id and the names (child, adult, senior) Fare_Type包含fare_Id和名称(儿童,成人,老人)

Group_Extras This is the biggy. Group_Extras这是biggy It will reference the groups, tour_extra and possible the Fare_Type table. 它将引用组,tour_extra以及可能的Fare_Type表。 This will be used to determine what the total amount will be for that particular group. 这将用于确定该特定组的总金额。 For eg: 例如:

gp_ID TE_ID quantity fare_ID
  1     1      3       1

For group with an id of 1, they have chosen TE_ID of 1 (eg lunch) and purchased quantity (3) and will be charged to fare_ID 1 (eg child) 对于ID为1的组,他们选择了TE_ID为1(例如午餐)并购买了数量(3),并将被计入fare_ID 1(例如儿童)

This may be of help to some people: 这可能对某些人有帮助:

Tour_Extras can have many Tour_Extra_Price Tour_Extras可以有许多Tour_Extra_Price

Tour_Extra_Price can have one Fare_Type Tour_Extra_Price可以有一种Fare_Type

Group_Extras can have many Groups, Tour_Extras and/or Fare_Type (unsure whether to link with Fare_Type directly, or go through Tour_Extras, then Tour_Extra_Price, then Fare_Type) Group_Extras可以有多个Groups,Tour_Extras和/或Fare_Type(不确定是直接与Fare_Type链接,还是先经过Tour_Extras,然后依次浏览Tour_Extra_Price和Fare_Type)

I have other questions like are foreign keys needed? 我还有其他问题,例如是否需要外键? Is it best to have primary keys on the Group_Extras table and foreign keys on the other tables? 最好在Group_Extras表上具有主键,而在其他表上具有外键?

Apologies for the long post but I want to exhaust all options and do my research before diving into this project. 很长的道歉,但我想尽一切办法,然后再研究该项目。

ps I won't be back on for a few hours. ps我几个小时都不会回来。 So ask questions please and I'll answer them within 12 hours. 因此,请提出问题,我会在12小时内回答。

Your database structure is generally fine for the requirements that you described. 您的数据库结构通常适合于您描述的需求。 I would suggest you add a "Group" table which you could use for common attributes shared for the group member, eg the ID, a name for the group if necessary, or a timestamp. 我建议您添加一个“组”表,该表可用于组成员共享的常用属性,例如ID,组名(如有必要)或时间戳。 You could also set the ID of the leader here directly, instead of having a "leader" flag in each row of the groups table. 您也可以在此处直接设置领导者的ID,而不是在groups表的每一行中都具有“ leader”标志。

Other than that I would make one change; 除此之外,我会做出一个改变; since you are using MySQL you might choose to use an ENUM field for the fareType instead of a Fare_Type table (since I assume the 3 values are unlikely to change - if they change, you can easily add more values). 由于您使用的是MySQL,因此您可能会选择对FareType使用ENUM字段而不是Fare_Type表(因为我假设这3个值不太可能更改-如果更改,则可以轻松添加更多值)。 This would simplify your queries since you have to do one less join, and also makes your database a bit more readable while debugging. 这将简化查询,因为您必须减少一次连接,并且还可以使数据库在调试时更具可读性。 Academically your solution is correct, I would just change this to make your life a bit easier (and make the database more readable). 从理论上讲,您的解决方案是正确的,我只是更改此设置即可使您的生活更轻松(并使数据库更具可读性)。 Of course, if the users want to edit the fareTypes themselves you have to keep it as a seperate table. 当然,如果用户要自己编辑fareType,则必须将其保存为单独的表。

Technically you don't need any foreign keys - your application will work just fine if you only add primary keys and keep the relations in mind in your update/deletion/insertion logic. 从技术上讲,您不需要任何外键-如果您仅添加主键并在更新/删除/插入逻辑中牢记这些关系,则您的应用程序将可以正常工作。 If you add foreign keys, it will add constraints on your tables so that their integrity can't be violated. 如果添加外键,则会在表上添加约束,以免破坏其完整性。 Eg if you want to delete a Tour_Extra, you would first have to make sure that no other table has a reference on it, or you would get a constraint error. 例如,如果要删除Tour_Extra,则首先必须确保没有其他表具有引用,否则将得到约束错误。 Although things have improved, I'm not really keen to work with foreign keys in MySQL, there used to be a lot of problems. 尽管情况有所改善,但我并不是很想在MySQL中使用外键,但是以前存在很多问题。 If you choose to use them, you need to set your tables to the InnoDB database engine in any case. 如果选择使用它们,则无论如何都需要将表设置为InnoDB数据库引擎。

Your primary keys should be pretty clear: 您的主键应该很清楚:

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

And the foreign keys, if you choose to assign them: 还有外键(如果选择分配它们):

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

Obviously we live some hours apart from each other, so the question-answer round trips in the requests comment section take too much time. 显然,我们彼此相距几个小时,因此请求注释部分中的问题与答案往返花费了太多时间。 So instead of asking more one-per-day-questions, here are my thoughts: 因此,我没有提出更多每天提出的问题,而是我的想法:

To start with: What does a customer_id actually represent? 首先:customer_id实际代表什么? Do you have customers stored, so you recognize them when they repeatedly book tours? 您是否存储了客户,以便在他们重复预订旅行时识别他们? It doesn't seem so to me (and anyway, what would you gain from this?). 在我看来,情况并非如此(无论如何,您将从中得到什么?)。 From what I see, it looks more like a tour booking to me. 从我看来,对我来说,它更像是一个旅行预订。 So every time Mr. Miller books a tour he gets a new customer_id. 因此,每次Mi​​ller先生预定行程时,他都会获得一个新的customer_id。 But if so, doesn't the customer_id represent his complete booking already? 但是,如果是这样,customer_id是否已经代表了他的完整预订? You wouldn't need a customer_id for Mrs. Miller, because she would be included in that booking. 您不需要Miller太太的customer_id,因为她会包含在预订中。

So what I see is a booking. 所以我看到的是预订。 This consists of one person's name and contact details (Mr. Miller in my example) plus number of travelers. 这由一个人的姓名和联系方式(在我的示例中为Miller先生)加上旅客人数组成。 That would be: 那将是:

table booking 订餐

  • booking_id booking_id
  • tour_id tour_id
  • name 名称
  • address 地址
  • phone 电话

table booking_passengers 表预订_乘客

  • booking_id booking_id
  • fare_type_id (adult / child / senior) fare_type_id (成人/儿童/老人)
  • quantity (how many of that type in that booking 数量(该预订中有多少种类型

Data should always be in the tables, not in a table name or column name. 数据应始终在表中,而不是表名或列名。 So you would not have columns like dependant_Fare_Child and dependant_Fare_Adult, but a table booking_passengers with a column fare_id instead, so you can join based on the ID. 因此,您将不会有诸如dependentant_Fare_Child和Dependant_Fare_Adult之类的列,而是具有带有fare_id列的表booking_passengers,因此您可以基于ID进行联接。

So the booking (or customer as you call it) already represents a group. 因此,预订(或您所说的客户)已经代表了一个团体。 Do you need more details on the co-passengers, then replace booking_passengers with a table that hold one record per passenger: 您是否需要有关副乘客的更多详细信息,然后将保留每个乘客一个记录的表替换为booking_passengers:

table booking_passenger 表格booking_passenger

  • booking_id booking_id
  • fare_type_id (adult / child / senior) fare_type_id (成人/儿童/老人)
  • name 名称
  • age 年龄

Your structure for tour extras looks fine. 您的旅游额外费用结构看起来不错。 As I call your customer or group a booking, my table would be: 当我称呼您的客户或团体预订时,我的表格将是:

table booking_extras 表booking_extras

  • booking_id booking_id
  • tour_extra_id (lunch / gear / ...) tour_extra_id (午餐/齿轮/ ...)
  • fare_type_id (adult / child / senior) fare_type_id (成人/儿童/老人)
  • quantity 数量

For the tour prices I assume such a table, btw: 对于旅游价格,我假设有这样一张表格,顺便说一句:

table tour_price 表tour_price

  • tour_id tour_id
  • fare_type_id (adult / child / senior) fare_type_id (成人/儿童/老人)
  • price 价钱

Primary keys in above tables are italic. 上表中的主键为斜体。 You should use foreign keys. 您应该使用外键。 They exist to guarantee data consistency, eg not to have passengers without a booking. 它们的存在是为了保证数据的一致性,例如不要让没有预订的乘客。 Database people would always take it for granted to have foreign keys in a relational database and rely on their existence as much in regard to data consistency as to available indexes. 数据库人员总是将关系数据库中的外键视为理所当然,并且在数据一致性和可用索引方面都依赖于它们的存在。 So the table booking_extras would have a primary key booking_id + tour_extra_id + fare_type_id. 因此,表booking_extras将具有主键booking_id + tour_extra_id + fare_type_id。 You would have a foreign key to tables booking via booking_id, tour_extra via tour_extra_id, and fare_type via fare_type_id. 您将有一个外键,用于通过booking_id预订表,通过tour_extra_id预订tour_extra和通过fare_type_id预订fare_type。

Hope this helps. 希望这可以帮助。 If I misunderstood anything, just tell me so in comments and I will hopefully find the time to adjust my answer accordingly. 如果我误解了什么,请在评论中告诉我,这样我将希望有时间相应地调整我的答案。

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

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