【问题标题】:Designing a database and querying with mySQL - Not sure if i modeled this correctly?设计数据库并使用 mySQL 进行查询 - 不确定我是否正确建模?
【发布时间】:2019-04-18 21:37:48
【问题描述】:

我是数据库设计的新手,所以我有点不确定我是否在这里做事。

我正在为假摩托车租赁服务创建一个数据库。以下是会影响我的数据库的事件:

如果有新客户进入商店:

Store customer info,

If they were referred:

    Make note of name of referrer

如果以前的客户进入:

Retrieve previous customer info,

**If this customer has an un-returned scooter, they can't borrow another

如果客户租用滑板车,请跟踪:

Date/hour of borrow,

Date/hour of return,

How much paid, 

Freeform notes that are categorized, ie Issues while scooter is returned or when used

当滑板车归还时:

When it was returned,

Is return late, 

Is scooter damaged, 

Additional fees for damage / late return

我将对数据库进行的查询:

所有有旗帜的人,

所有可用的踏板车,

所有借来的滑板车,

所有迟到的踏板车,

推荐次数排名前 5 的人,

对于一个人,显示该人借过滑板车的所有时间,

对于借款实例,请显示任何额外费用,并且

所有滑板车制造商

这是我想出的(还不是实际的图表,只是不同的表和关系),完全不确定这是否在正确的轨道上: https://imgur.com/a/NzqB0CE

【问题讨论】:

  • 为了评论 Schema,我需要查看主要查询。
  • 我相信我已经在操作中列出了它们

标签: mysql sql database database-design entity-relationship


【解决方案1】:

没错。您的设计存在一些问题。 SQL DB 中的想法是“规范化”信息,这意味着没有数据重复。这是要记住的一件事,另一件事是您必须考虑这些实体之间的“实体”和“关系”,而不是对象和动作。让我们看看:

CUSTOMER
 -name
 -email

SCOOTER
 -manufacturer
 -model

RENTALS
 -customerID
 -scooterID
 -startDate
 -plannedEndDate
 -actualEndDate

因此,这里的“RENTALS”是一个多对多表,涉及可以租用许多滑板车的客户,以及在其生命周期内将拥有许多客户的滑板车。 customerID 和 scooterID 可以是 MySQL 的自动 ROWID,也可以在特定 ID 字段中显式设置。

通过此设置,您可以通过设计查询获得大量信息:

踏板车有货吗?

SELECT * FROM RENTALS WHERE scooterID = X AND plannedEndDate > DATE()

意思是,滑板车是租来的,将来会归还。

我们有滑板车迟到了吗?

SELECT * FROM RENTALS WHERE plannedEndDate < DATE() AND actualEndDate = NULL

意思是,应该已经归还但没有归还的踏板车。

等等。希望对您有所帮助!

【讨论】:

  • 第一个选择:INDEX(scooterID, plannedEndDate);第二:INDEX(actualEndDate, plannedEndDate)Bug:不要做= NULL;而是做IS NULL
  • 这确实有很大帮助,但 SCOOTER 不应该是多对多而不是出租吗? RENTALS 中的一行不应该只针对一个租赁实例吗?
  • 好的,我想我现在明白了。那么,CUSTOMER 与 RENTALS 和 SCOOTER 是否存在多对多关系?
  • CUSTOMER与SCOOTER是多对多的关系,意思是1个客户可以租多辆滑板车,每辆租一排,一辆滑板车可以租多次,每辆租一排。在这个设计中,RENTALS 不是一个实体,而是一种关系,将滑板车和客户联系起来。表只允许直接连接 1-many,要进行多对多,则需要一个中间表,在本例中为出租
【解决方案2】:

没有任何“复数”列。相反,有另一个表链接回该表。示例:推荐、借用实例。

“推荐次数排名前 5 的人”将更容易从上面提到的额外表中查询。

踏板车当前是否正在使用中的说明是什么?也许 Scooters.Availability ?请注意,当 Scooter 被“占用”和“归还”时,您可能需要插入/更新多个表。

“所有迟到的滑板车”可能难以从建议的架构中确定。您可能需要另一个专注于“销售”的表格。即借滑板车时加一行;也许事情会随着时间而改变;当踏板车“归还”时,该行被标记为“完成”(可能未删除)。请注意,此表为查看“易手”的“钱”的人提供了简单的信息。它还可能提供“过去租用的滑板车”的来源,我在上面批评过。

所以,我建议再增加 3 个表,并将几列移到这些表中。

推荐...

您应该尝试将数组放入列中。它很乱、很笨拙等。相反,创建另一个表 (Referrals) 并将其链接回主表 (Customers)。

当您有“多对一”映射时(“一个”客户的“多”推荐):

Customer:  customer_id MEDIUMINT UNSIGNED NOT NULL, etc
    -- no mention of "referrals"
CREATE TABLE Referrals (
    customer_id MEDIUMINT UNSIGNED NOT NULL,  -- the referree
    name,   -- who referred
    PRIMARY KEY(customer_id, name)
) ENGINE=InnoDB

这允许多个“名称”引用一个“客户 ID”。

如果“推荐人”必然是其他客户,那么您有一个多对多表:

Customer:  customer_id MEDIUMINT UNSIGNED NOT NULL, etc
    -- no mention of "referrals"
CREATE TABLE Referrals (
    ee_id MEDIUMINT UNSIGNED NOT NULL,  -- customer_id of the referee
    er_id MEDIUMINT UNSIGNED NOT NULL,  -- customer_id of the referer
    PRIMARY KEY(ee_id, er_id),
    INDEX(er_id, ee_id)
) ENGINE=InnoDB

【讨论】:

  • 那么您建议添加的表格以及塞尔吉奥在上面写的内容是推荐、销售和借款?如果我已经有一个出租表,为什么还需要借用?此外,如果我的 Customer 表的其中一列是“referrals”,如果我将 Referrals 表链接到 Customer 表的推荐字段,那么类型是什么?
  • @user10366926 -- 哎呀,借用和销售是一样的。 1:1通常不是一个好主意。考虑将 Borrow 和 Return 组合到一个表中,NULL 用于返回信息。 (这是一个建议,而不是“要求”。)
  • @user10366926 - 是的,Referals 表将是一个推荐列表,链接到客户 (many:one)。如果推荐只来自客户,那么它是一个多对多表,将客户与客户联系起来。
  • 那么当我用 CREATE TABLE 写我的 SQL 表时,我为引荐输入的类型是什么?
  • 好的,我提供了关于 table 推荐的细节。不要尝试将数组放在列中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多