我有一个场景,我对如何为其设计数据库架构感到困惑。
在我的软件 (php) 中有公司和应用程序。
公司需要获得许可才能访问应用程序。
现在每个应用程序的字段(购买许可证时的表单)都不同。
例如:
对于应用程序1:
字段是:
- 用户数
- 组数
对于应用程序2:
- 用户数
应用程序3:
- 使用小时数
价格基于这些字段。
现在我需要为此设计架构,以便公司可以在一页上管理所有应用程序的许可证。
我怎样才能使这个模式通用?
请帮忙。谢谢。
我有一个场景,我对如何为其设计数据库架构感到困惑。
在我的软件 (php) 中有公司和应用程序。
公司需要获得许可才能访问应用程序。
现在每个应用程序的字段(购买许可证时的表单)都不同。
例如:
对于应用程序1:
字段是:
对于应用程序2:
应用程序3:
价格基于这些字段。
现在我需要为此设计架构,以便公司可以在一页上管理所有应用程序的许可证。
我怎样才能使这个模式通用?
请帮忙。谢谢。
您可以使用这种类型的结构
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 个字段NoofUsers
和NoOfGroups
. 如果您愿意,它还能够为特定应用程序调整更新的字段。
查询 3:
ApplicationValue 将具有每个许可证应用程序的值,因此它将具有 compId,它表示使用 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
| 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 个内部连接。所以我建议你在使用这种方法之前重新考虑一下。
您在那里拥有的东西可以很容易地映射到 OO 语言(如 PHP)中的类。您有一个抽象许可证,然后是 3 个子类(ApplicationByUsersAndGroups 等)。然后,映射到关系数据库是一个非常常见的问题,这里有一篇关于它的好文章:http: //www.ibm.com/developerworks/library/ws-mapping-to-rdb/
它有 3 个选项,这取决于您要构建应用程序的方式,您应该使用哪一个。推荐阅读,篇幅不长。
以这种方式构建的表格怎么样:
LicenseId int PK
CompanyId Int PK
AppId Int PK
LicenseType int
NumberOfUsers int
NumberOfGroups int
NumberOfHours int
Price Money
根据 LicenseType,您将在业务逻辑中使用不同的列,您可能需要添加 CompanyID 和/或 AppID,这取决于您将如何构建这些表以及公司/应用程序/许可证之间的关系。
一些需要思考的问题:
一种方法是
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
[...]
这样,你的意图就很清楚了。即使经过很长时间回来,您也会很快知道事物是如何组织的,在哪种情况下使用了哪些字段......
不要使事情复杂化,如果用户数量不受限制,则将其设置为 999999 或其他最大值。
这使许可证检查逻辑(每次用户登录时都会运行)保持简单并且对于所有应用程序都是相同的。
您将需要在许可证维护应用程序中添加额外的逻辑,但这也应该非常简单:如果 cost_per_user = 0,则设置 no_of_users = 99999
同样,您最终会得到所有应用程序的相同许可屏幕和逻辑。