Oracle SQL,寻找有关约束的想法
我有一个包含班级、教师和领导者行的表,
班级和教师是数字,领导者是布尔值(实际上只是一个 Char(1))
该表表示教师和班级之间的关系。
一个班级可以有多个老师,或者一个老师可以有多个班级。
我需要进行约束或检查,以便对于每个不同的类,它出现的一个且只有一个行必须将 Leader 设为 true。
例如。
Teacher | Class | Leader 1 | 1 | True 2 | 1 | False 2 | 2 | True
会被接受,因为每个不同的类都有一行,其中它的 Leader 值为 true,但不超过一行。
如果有人能提出如何将其表示为约束的想法,我将不胜感激。
I have a table with Class, Teacher, and Leader rows,
Class and Teacher are Numbers, and Leader is a Boolean (really just a Char(1))
The table represents a relationship between teachers and classes.
A class can have many teachers, or a teacher many classes.
I need to make a constraint or check so that for each distinct class, one, and only one of the rows it occurs in must have Leader as true.
Eg.
Teacher | Class | Leader 1 | 1 | True 2 | 1 | False 2 | 2 | True
Would be accepted, as each distinct class, has one row in which it occurs having a Leader value of true, but no more than one row.
Would appreciate if anyone could offer up an idea on how to represent this as a constraint.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
创建一个基于函数的索引来强制执行约束的“不超过一个领导者”部分是很容易的。
不幸的是,创建一个声明性约束来强制执行每个类都有一个领导者的要求并不容易。我知道执行此操作的唯一声明性方法是创建一个按类聚合数据的物化视图,将该物化视图设置为 REFRESH FAST 并在物化视图上创建一个约束,以确保物化视图中的
NUM_LEADERS
列始终为 1。这要求您创建适当的物化视图日志,这会增加表上 DML 的开销。这也意味着在您提交之前不会违反约束,如果您的应用程序没有编写为假设提交可能会失败,那么这可能会出现问题。It's easy enough to create a function-based index that enforces the "no more than one leader" portion of the constraint
Unfortunately, it's not so easy to create a declarative constraint that enforces the requirement that each class has a leader. The only declarative way I'm aware of to do that would be to create a materialized view that aggregates the data by class, set that materialized view to
REFRESH FAST
and create a constraint on the materialized view that ensures that theNUM_LEADERS
column in the materialized view is always 1. That requires that you create an appropriate materialized view log which adds overhead to DML on the table. It also means that the constraint won't be violated until you commit which can be problematic if your applications aren't written to assume that commit can ever fail.考虑将
is_Leader
(布尔值)列更改为leadership_rank
(整数),对(教师、班级领导力_rank)创建复合唯一约束。然后稍微改变语义,以便每个老师得到一个唯一的随机/递增/有意义的整数值。然后,班级的宣布领导者是老师,其中
leadership_rank = 1
(或者可能是该组的最低排名,以使事情更加灵活),也许使用视图。Consider changing the column
is_Leader
(Boolean) column toleadership_rank
(Integer), create a compound unique constraint on(Teacher, Class leadership_rank)
. Then change the semantics slightly so that each teacher gets a unique random/incrementing/meaningful integer value. Then the declared leader for the class is the teacher whereleadership_rank = 1
(or perhaps the lowest rank for the group, to make things a little more flexible), perhaps using a view.另一种方法是创建一个名为
Leader
的表,其中包含:并删除 ClassTeacher.Leader 列。
Another way would be to create a table, called
Leader
with:and drop the ClassTeacher.Leader column.
考虑以不同的方式对关系进行建模,而不是添加约束。
由于 class 和 class 之间存在一对一的关系。领导者
我认为实现您想要的结果的最简单方法是将领导者 (class_teacher_id) 与班级记录一起存储。您需要将唯一的代理键 (class_teacher_id) 添加到多对多表 (class_teacher),然后可以删除领导者布尔列。
如果可能有一个没有领导者的类,那么只需允许 learderid 可为空
当然,不要忘记创建外键约束以强制 class.leaderid 和新的 class_teacher.class_teacher_id 之间的引用完整性。
Rather than adding a constraint consider modeling the relationship in a different way.
As there is one-to-one relationship between class & leader
The easiest way I can see to achieve your desired results would be to store the leader (class_teacher_id) with the class record. You will need to add a unique surrogate key (class_teacher_id) to your many-to-many table (class_teacher), then you can drop the leader boolean column.
If it is possible to have a class without a leader then simply allow the learderid to be nullable
and of course don't forget create foreign key constraints to enforce referential integrity between the class.leaderid and the new class_teacher.class_teacher_id.
要强制要求每个班级都有一个领导者,您可以使用触发器
To enforces the requirement that each class has a leader you can use a Trigger