【问题标题】:Classpass.com like database designClasspass.com 类似数据库设计
【发布时间】:2016-10-19 19:00:32
【问题描述】:

我正在努力创建类似于数据库设计的类通行证。我是数据库设计的新手,有一些事情不适合我如何实现它们,我无法完全理解。

您可以查看 classpass 示例:

编辑 1: 想法如下:每个城市都有多个社区,拥有多个工作室/场地。

看了spencer7593的评论,下面是我自带的,还有一些不太清楚的:

所以我不太确定的是:

  1. 我不确定如何存储场地/工作室地址和地理位置。拥有定义 id | 的表 Region 会更好吗?姓名 | parent_id 并递归存储城市和社区?或者为城市和社区添加外键约束?我应该将 lan/lon 存储到场地表、地址甚至单独的位置表中吗?我希望能够执行如下搜索:

    • 告诉我该社区或城市的场地
    • 显示距离位置 XX 半径内的场地
  2. 每个班级都应该有一个时间表,目前我不知道如何设计它。例如:从上午 9 点到上午 10 点的动感单车课、Mo、We、Fr。我想 能够进行如下查询:

    • 告诉我场地,在 Mo 上有旋转课程
    • 或向我展示旋转、拳击等类别中的所有课程
    • 甚至可以带我看看提供动感单车课程的场所
  3. 我应该在这里创建一个额外的表计划吗?或者只是创建某种创建时间表的视图?如果是一张额外的桌子,我应该如何描述一周中每一天的开始、结束?

【问题讨论】:

  • 要记住的一件事...实体名称始终采用单数形式。例如,NEIGHBORHOOD 代替 NEIGHBORHOOD,CITY 代替 CITIES 等。我稍后会发布一个示例。

标签: mysql database-design relational-database database-schema


【解决方案1】:

实体关系建模。

实体是可以唯一标识的人、地点、事物、概念或事件,对业务很重要,我们可以存储有关信息。

根据问题中的信息,一些被视为实体的候选人可能是:

工作室

评分

邻里

城市

对于每个实体,什么唯一标识它?找出候选键。

并找出实体和基数之间的关系。 (什么与什么有关,有多少,必需或可选?)

studio 是否与 class 相关?

studio 可以有多个class 吗?

工作室可以有零classes吗?

class 可以与多个studio 相关联吗?

neighborhood 是否与零、一个或多个 city 相关?

studio 可以与多个 neighborhood 相关联吗?

获得实体和关系后,获取分配给每个实体的属性非常简单。只需确保每个属性都依赖于键、整个键,并且只依赖于键。

【讨论】:

  • 非常感谢您的详细回复。知道如何存储课程的信息,例如:上午 10 点开始,上午 11 点结束。一整周或多或少类似于日历的格式?
  • 能否请您检查我的编辑并再次分享您的想法? ;)
【解决方案2】:

第一

你的问题不适合发到Stack Overflow,因为我想最好发到Database Administrators


第二次

这里有一些信息可供阅读,只是为了给您构建数据库一个良好的开端:

  1. Data Modeling(有点宽泛,但更好)
  2. Logical Data Model(简短而全面)

第三

基本上,在设计数据库时您应该首先了解系统中需要的所有数据,然后将它们分组(如果需要)以使其更小。 对其进行标准化以减少数据冗余。

示例

假设表venue 将是您的主表或系统中所有事务的中心。这样,venue 可能有子数据,例如 branch,它可能包含不同的分支位置......并且 branch 也可能有子数据,例如 scheduleteacher 和/或 class,这也可能彼此相关(子数据从另一个子数据中获取数据)……依此类推。

然后您也可以创建独立的表,但仍与其他表有联系。例如neighborhood表,它可能包含邻居位置和主会场位置(所以它应该从venue表中获取所选会场的id)......等等与相关和独立的表.

注意

只要记住“一对一,一对多”的关系。如果一个数据将包含多种子数据,只需将它们拆分到不同的表中。如果数据将只包含 (1) 种子数据,则将它们全部放在一个表中。

【讨论】:

    【解决方案3】:

    @Dimitar,

    即使@rhavendc 是正确的,这个问题也应该放在数据库管理员中,我会尽我所知按照相应的顺序回答你的问题。

    1. 我不知道如何存储场地/工作室地址和地理位置。 [...]

    您可以通过网络搜索轻松找到地理位置。以MyGeoPosition 为例。

     

    我希望能够执行类似的搜索

    • 告诉我该社区或城市的场地。

    您可以轻松做到这一点。有几种方法可以做到这一点,每种方法都需要对您的 ERD 设计进行一些调整。使用我在下面附加的示例,您可以运行查询以列出所有具有 address_id 后跟城市 ID 的场所。黄色实体是我添加以确保完整性的实体。

    例如:

    -- venue.name is using the "[table].[field]" format to help
    -- the engine recognize where the field is coming from.
    -- This is useful if you are pulling the fields of the
    -- same name from different tables.
    select  venue.name, city.name
    from    venue    join
            address  using (address_id)    join
            city     using (city_id);
    

    注意:您不必包含 city_name。我只是把它扔在那里,所以你可以试一试,看看所有匹配它的场地。

    如果您想在附近执行此操作,则必须通过在 ADDRESS 表中添加 neighbor_id 来调整我给您的 ERD。我附上了下面的例子,你还必须添加neighbor_id 从那里,你可以运行这样的查询:

    使用此 ERD:

    -- Remember the format from the previously mentioned code.
    select  venue.name, neighborhood.name
    from    venue        join
            address      using (address_id)    join
            neighborhood using (neighbor_id);
    

     

    • 显示距离位置 XX 半径内的场地

    您可以使用Haversine's Formula根据经度和纬度计算英里、公里等的数量。

     

    1. 每个班级都应该有一个时间表,目前我不知道如何设计它。例如:从上午 9 点到上午 10 点的动感单车课、Mo、We、Fr。我希望能够进行如下查询:
      • 告诉我场地,在 Mo 上有旋转课程
      • 或向我展示旋转、拳击等类别中的所有课程
      • 甚至可以带我看看提供动感单车课程的场所

    这可以很容易地从我在此处附加的任何一个 ERD 中得出。在CLASS 表中,我添加了一个名为parent_class_id 的字段,它从同一个表中获取class_id。这使用递归,我知道这有点让人头疼。这种递归将允许分配了父类的类显示这些类也在不同的时间提供。

    你可以通过这样做得到这个结果:

    -- Remember the format from the previously mentioned code.
    select  class1.name, class1.class_id, class2.class_id
    from    class as class1,
            class as class2
    where   class1.parent_class_id = class2.class_id;
    

     

    • 甚至可以带我看看提供动感单车课程的场所

    这可能是一个棘手的问题...如果您想知道哪些场地提供动感单车课程,其中动感单车是课程的一部分或课程名称,而不是类别,这很简单。

    试试这个...

    -- Remember the format from the previously mentioned code.
    select  venue_id
    from    venue    join
            class    using (venue_id)
    where   class_name = 'spinning';
    

     

    注意:请记住,大多数 SQL 语言在搜索文字时都区分大小写。您可以尝试使用where UPPER(class_name) = 'SPINNING'

    如果类名中可能包含“spinning”以外的词,请改用:where UPPER(class_name) like '%SPINNING%'

    如果您想知道哪些类提供旋转类,其中旋转是一个类别,那就是棘手的问题。我相信您必须为此使用子查询。

    试试这个:

    -- Remember the format from the previously mentioned code.
    select  class_id
    from    class             join
            class_category    using (class_id)
    where   cat_id =          (select    cat_id
                               from      category
                               where     name = 'spinning');
    

     

    再次强调,SQL 引擎在文字搜索方面通常很敏感。确保您的案例使用正确的大写或小写。

    1. 我应该在这里创建一个额外的表计划吗?或者只是创建某种创建时间表的视图?如果是一张额外的桌子,我应该如何描述一周中每一天的开始、结束?

    是和不是。你可以,但如果你能理解数据库系统中的递归,你就不必了。

    希望这会有所帮助。 :)

    【讨论】:

    • 如果它给你带来了问题,请告诉我,然后我今晚会努力解决它。
    猜你喜欢
    • 1970-01-01
    • 2010-10-07
    • 2012-03-22
    • 2011-01-18
    • 2010-11-18
    • 2010-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多