数据库设计/规范化结构需要包含 AND、OR、可选元素及其关系
我想将大学课程的详细信息存储在(MySql)数据库中,但我不确定如何维护模块和选择之间的关系。
基本上,一门课程可以有必修部分、一组可选模块、一个选项部分,并且每个部分中都可以有包含模块之间 AND 或 OR 的选择。
简单示例:
一门 60 学分的课程有一些必修模块,总共 40 学分。剩下 20 个学分可供从可选模块组中选择。 (模块本身可以持有不同数量的学分)。有效地; ('强制模块 1' AND '强制模块 2'... AND'强制模块 N') AND (来自 '可选模块' 的 40 个学分)
,
ANDs & OR:
当我在上面说模块时,它可以是单个模块,也可以是“模块 x 或模块 Y”,即在强制部分中。 (这些模块显然必须具有相同的信用权重)。 或者在可选部分中可能有单个模块,甚至其中一个选项可能类似于“模块 x AND 模块 y”。
选项:
学生可能必须选修必修模块以及n个选项之一,其中可能包含也可能不包含 AND、OR 以及必修的 & 选项。可选部分;即“选项”具有整个课程模块选择的所有属性。选项部分将与其他部分(如强制或可选)进行 AND 或 OR 运算;即强制模块“加上以下选项之一”。实际上,选项部分只是“选项 1”或“选项 2”...或“选项 N”
。
问题是当操作数可能是另一个 AND/OR 运算或单个模块时,如何存储所有 AND 和 OR 关系,并跟踪每个选择允许的积分数量;例如“来自以下内容的 20 学分:”(可选模块组)。
I want to store the details of college courses in a (MySql) database but I'm not sure how to maintain the relationship between modules and selections.
Basically, a course can have mandatory section, group of optional modules, an options section and within each there can be selections which contain ANDs or ORs between modules.
Simple example:
A 60 credit course has a few mandatory modules which make up 40 credits. That leaves 20 credits to be selected from the group of optional modules. (Modules themselves can hold different amount of credits). Effectively; ('Mandatory module 1' AND 'Mandatory module 2'... AND'Mandatory module N') AND (40 credits from 'optional modules')
,
ANDs & ORs:
When I say modules above, it could be a single module or it could be "Module x OR Module Y" i.e. in the mandatory section. (those modules would obviously have to have the same credit weight).
Or in the optional section there might be single modules or even one of the choices could be something like "module x AND module y"
.
Options:
The students may have to take the mandatory modules plus one of n options which may or may not contain ANDs, ORs, and mandatory & optional sections; i.e. An 'Option' has all the attributes of the overall course modules selection. The Options section would be AND'd or OR'd with other sections like mandatory or optional; i.e. mandatory modules "plus one of the following options". Effectively the options section is just 'Option 1' OR 'Option 2'... OR 'Option N'
.
The problem is how do I store all of the AND and OR relationships when the operand may be another AND/OR operation or a single module, and keep track of the amount of credits allowed for each selection; e.g. "20 credits from the following:" (group of optional modules).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
一个非常简单的第一种方法是仅使用 4 个表:
以及通过这 2 个表允许的组合:
现在,如果您允许的模块和课程组合更复杂,正如您的描述所示,而不是
Course_Module
和Course_MandatoryModule
表,您可以定义一个复杂的分层模型:课程:
模块和组(模块):
以及关系(模块属于组):
并且(最后)课程可以有模块组:
A very simple, first approach would be using just 4 tables:
and the combinations allowed through these 2:
Now, if your allowed combinations of modules and courses is more complicated, as your description suggests, instead of the
Course_Module
and theCourse_MandatoryModule
tables you could define a complex hierarchical model:Courses:
Modules and groups of (modules):
and relationship (module belongs to group):
and (finally) course can have group of modules:
该设计相当简单,您只需要一个带有约束的递归“组”表。
一个示例结构是
快速浏览...课程“数学专业”在其下有两个组“核心模块”和“辅助模块”。 “核心模块”需要至少 2 名儿童且至少 40 个学分。
“中学模块”需要至少 1 个孩子且至少 20 个学分。
您可以看到“核心模块”下的组的约束比“辅助模块”下的组的约束更严格。
输出上面的示例结构会是这样的。
因此,如果您有一门课程和模块,您可以从 Course_Group 表中获取课程的所有组,并从 Group_Module 表中获取模块所属的组。一旦您将模块放入组中,您就可以沿着 Group.GroupID 父系链检查组的约束 AtLeastNSelections 和 AtLeastNCredits,直到到达 Group.GroupID = NULL。
The design is fairly straight-forward you just need a recursive "group" table with constraints.
An example structure would be
A quick walk through... the course "Math Major" has two groups under it "Core Modules" and "Secondary Modules". "Core Modules" requires AT LEAST 2 children AND AT LEAST 40 credits.
"Secondary Modules" requires AT LEAST 1 child AND AT LEAST 20 credits.
You can see that the constraints of the groups under "Core Modules" are more restrictive than the constraints of the groups under "Secondary Modules".
To output the example structure above would be something like.
So if you have a course and modules you can get all the groups for the course from the Course_Group table and get which group the modules belong to from the Group_Module table. Once you have the modules in their group(s) you can check the group's constraints AtLeastNSelections AND AtLeastNCredits walking up the Group.GroupID parentage chain until you get to Group.GroupID = NULL.
您可以在此处创建递归表结构,其中选项引用其父选项。
然后可以通过查询此表中具有“空”父项的所有选项来识别“主”选项。
“与或”关系可以通过单独的“选项集”表来实现,其中主键是“选项”。具有空自引用的选项集表是定义课程选项的“根”点。从那时起,您将选择父=根的选项集记录。这将是选项的第一个“级别”。有些是强制性的,有些则不是。为了表达这一点,您必须在选项集表上有一个布尔属性作为标志。因此,每个选项集都是根据更小的选项集来定义的。当然,最终,一旦你深入了解,你的选项集将在某个时候定义一个实际的类。
我建议可以更有效地用 JSON 或 XML 进行建模,因为这些数据结构以更具表现力的方式支持层次结构。
You can create a recursive table structure here, wherein Options reference their parent options.
The "main" options can then be identified by querying this table for all options with "null" parents.
The "and-or" relationships can be implemented by a separate "option-set" table, where the primary key is to an "option". The option-set table's with null self-references are the "root" point for defining a course's options. From that point, you will select option-set records with parent = root. This will be the first "level" of options. Some will be mandatory, some won't. To express that, you will have to have a boolean attribute on the option-set table as a flag. Thus each option-set is defined in terms of smaller option-sets. Of course, ultimately, once you get to the bottom, your option-set's will define an actual class at some point.
I would suggest that this can much more effectively be modelled in JSON or XML, since those data structures support hierarchies in a much more expressive manner.
您可能可以这样做:
如果您确实需要能够创建组模块,即从多个其他模块创建的单个模块,那么表
module
将需要有一个标志字段:以及下表应该添加:
这更多是伪代码,但你明白了。表
course
和course_module_relationship
将没有键并存储您的关系,因为据我了解这个问题,它们可以是多对多的。因此,基本上,读取处理选择的代码必须检查这是否符合course_definition
的标准。如果必修部分与课程是一对一的关系,您可以将必修部分分成单独的表,但您必须更彻底地分析数据。
You can probably do something like this:
If you really need to be able to create group modules aka single module created from the multiple other modules then table
module
will need to have a flag field:and the following table should be added:
This is more of pseudo code but you get the idea. The table
course
andcourse_module_relationship
will have no keys and store your relationships as they can be many to many as I understand the problem. So basically the code that will read process the selections will have to check whether or not this meets the criteria for thecourse_definition
.If the Mandatory section to Course is a 1-to-1 relationship you can separate your mandatory section into a separate table but you will have to analyze your data more thoroughly.
使用和/或(如您的系统)的生产质量系统可以免费查看,它是 entlib 5.0 安全块。 http://entlib.codeplex.com/
每个规则均按名称检索到获得完整表达。图案和样式实践团队为表达式创建了自己的简短DSL,以避免使 xml 结构/db 结构复杂化。
这是实验练习 ex02 app.config 中的内容。要将规则存储在数据库中,您需要实现自定义的 AuthorizationRuleProvider。
R:=角色名; U:= username
dev 用法
虽然不是立即答案,但我认为这提供了一个很好的示例,说明如何实现基于规则表达式的系统。
A production quality system using and/or's (like your system) that you can review for free is entlib 5.0 Security block. http://entlib.codeplex.com/
Each rule is retrieved by name to get the full expression. the patterns & practice team created their own short DSL for the expression to avoid complicating the xml structure/db structure.
this is inside the hands on labs exercise ex02 app.config. To store rules inside the database you would need to implement a custom AuthorizationRuleProvider.
R: = rolename; U: = username
dev usage
While not an immediate answer I think this provides a good example of how to implement rule-expression based systems.