请提供数据库架构建议

时间:2013-05-15 05:37:26

标签: php mysql database-design database-schema

我有一个场景,我对如何为它设计数据库架构感到困惑。

在我的软件(php)中 有公司和申请。

公司需要拥有访问应用程序的许可证。

现在每个应用程序的字段(购买许可证时的表单)都不同。

代表:

对于application1

字段是:

  1. no of users
  2. no of groups
  3. 对于application2

    1. no of users
    2. 对于application3

      1. 使用小时数
      2. 价格基于这些字段。

        现在我需要为此设计架构,以便在一个页面上公司可以管理所有应用程序的许可证。

        如何使此架构通用?

        请帮忙。 感谢。

5 个答案:

答案 0 :(得分:1)

你可以选择这种结构

select * from applicationMaster



| APPID |      APPNAME |
------------------------
|     1 | Application1 |
|     2 | Application2 |

ApplicationMaster将提供主要的应用程序相关详细信息,不会重复这些名称,日期等。

查询2

select * from applicationField



| FIELDID | APPID |   FIELDNAME |
---------------------------------
|       1 |     1 |   NoOfUsers |
|       2 |     1 |  NoOfGroups |
|       3 |     2 | NoHourusage |

ApplicationField可以为特定的appId调整任意数量的字段。 因此,AppId 1有2个字段NoofUsersNoOfGroups。如果您愿意,它还可以为特定应用调整新字段。

查询3

ApplicationValue将包含每个许可证应用程序的值,因此它将具有compId,它表示使用fieldId应用了哪个公司,而fieldId引用了我们可以获取的应用值存储的applicationField表。

select * from applicationValue



| ID | COMPID | FIELDID | FIELDVALUE |
--------------------------------------
|  1 |      1 |       1 |         50 |
|  2 |      1 |       2 |        150 |
|  3 |      2 |       3 |        350 |
|  4 |      3 |       1 |        450 |
|  5 |      3 |       2 |         50 |

applicationPriceMaster存储每个应用程序的价格包。应用程序可能有多个包。

select * from applicationPriceMaster


| APPPACKAGE | APPID | TOTALPRICE |
-----------------------------------
|          1 |     1 |         50 |
|          2 |     1 |        100 |

对于每个应用程序包,其详细信息将发布在此表中。

select * from applicationPriceDetail


| APPPACKAGE | FIELDID | QUANT |
--------------------------------
|          1 |       1 |     1 |
|          1 |       2 |     1 |
|          2 |       1 |    10 |
|          2 |       2 |     1 |

注意请检查结构,因为它现在过于复杂,请检查您将在这些表上运行的查询类型及其性能。

select apm.APPPACKAGE, TOTALPRICE from
applicationPriceMaster apm
inner join 
(select APPPACKAGE from applicationPriceDetail
where FIELDID=1 and QUANT=1)a
on apm.APPPACKAGE = a.APPPACKAGE
inner join
(select APPPACKAGE from applicationPriceDetail
where FIELDID=2 and QUANT=1)b
on 
a.APPPACKAGE=b.APPPACKAGE

SQL FIDDLE

| APPPACKAGE | TOTALPRICE |
---------------------------
|          1 |         50 |

对于单个过滤器,您必须使用此查询,因此您必须使用内部过滤器的数量来增加内部查询的数量。

select apm.APPPACKAGE, TOTALPRICE from
applicationPriceMaster apm
inner join 
(select APPPACKAGE from applicationPriceDetail
where FIELDID=1 and QUANT=1)a
on apm.APPPACKAGE = a.APPPACKAGE

注意 - 这个查询非常复杂,只有在packagedetail表中提到的值相同时才有效,并且只有在值为2的情况下才能工作,你必须删除1个内连接只有1个过滤器。所以我建议你在使用这种方法之前重新考虑。

答案 1 :(得分:1)

你有什么,可以很容易地映射到OO语言的类(如PHP)。您有一个抽象许可证,然后是3个子类(ApplicationByUsersAndGroups等)。然后,映射到Relational数据库是一个非常常见的问题,这里有一篇很好的文章:http://www.ibm.com/developerworks/library/ws-mapping-to-rdb/

它有3个选项,它取决于你想要构建应用程序的方式,你应该使用哪个。我建议阅读它,时间不长。

答案 2 :(得分:0)

以这种方式构建的表如何:

LicenseId int  PK
CompanyId Int  PK 
AppId     Int  PK
LicenseType int
NumberOfUsers int
NumberOfGroups int
NumberOfHours int
Price    Money

根据LicenseType,您将在业务逻辑中使用不同的列, 您可能需要添加CompanyID和/或AppID,这取决于您如何构建这些表以及公司/ app / license之间的关系。

要考虑的一些问题:

  • 一家公司可以为同一个应用程序使用不同的许可类型吗?
  • 一家公司可以有不同的应用程序吗?

答案 3 :(得分:0)

一种方法是

Table LICENCES:
LICENSE_ID ==> UNIQUE IDENTIFIER
COMPANY_ID ==> references table COMPANIES
APPLICATION_ID ==> references table APPLICATIONS
LICENCE_TYPE ==> either of "BY_GROUPS_AND_USERS", "BY_USERS", "BY_HOURS"
LICENCE_BODY_ID ==> ID of specific body table
[...]

Table LIC_TYPE_BY_GROUPS_AND_USERS: 
LICENCE_BODY_ID ==> body identifier
NO_GROUP 
NO_USERS
[...]

Table LIC_TYPE_BY_USERS: 
LICENCE_BODY_ID ==> body identifier
NO_USERS
[...]

这样,你的意图很明确。即使经过很长一段时间的回归,你也会立刻知道事情是如何组织的,在哪种情况下会使用哪些字段......

答案 4 :(得分:0)

如果用户数量不受限制,请不要使事情复杂化,然后将其设置为999999或其他一些最大值。

这样可以使许可证检查逻辑(每次用户登录时都会运行)对所有应用程序都保持简单和相同。

许可证维护应用程序中需要额外的逻辑,但这也应该非常简单: 如果cost_per_user = 0,则设置no_of_users = 99999

同样,您最终会为所有应用程序提供相同的许可屏幕和逻辑。