Hibernate 基于父表中的参数的唯一约束检查
表用户具有Hibernate 基于父表中的参数的唯一约束检查,hibernate,database-design,jpa,Hibernate,Database Design,Jpa,表用户具有(userId,scoreType,…) --分数类型可以是分数或百分比 表UserScore(id、userId、分数、百分比) 我希望提供基于user.scoreType存储点数或百分比的灵活性。所以,如果用户的scoreType标记为points,我们可以假设UserScore表将只填充点,反之亦然 a。我假设由于上述要求,我将无法在UserScore.points或UserScore.percentage上添加nullable=false检查 b。如何定义@UniqueCons
(userId,scoreType,…)
--分数类型可以是分数或百分比
表UserScore(id、userId、分数、百分比)
我希望提供基于user.scoreType存储点数或百分比的灵活性。所以,如果用户的scoreType标记为points,我们可以假设UserScore表将只填充点,反之亦然
a。我假设由于上述要求,我将无法在UserScore.points或UserScore.percentage上添加nullable=false检查
b。如何定义@UniqueConstraint
检查UserScore
表。应该是吗
@Table(name = "UserScore", uniqueConstraints = {
@UniqueConstraint(columnNames = userId, points),
@UniqueConstraint(columnNames = userId, percentage))
如果您对这个问题有任何其他看法,我们将不胜感激
a。我假设由于上述要求,我将无法在UserScore.points或UserScore.percentage上添加nullable=false检查
正确的
b。如何为UserScore表定义@UniqueConstraint检查。它应该是@Table(name=“UserScore”,uniqueConstraints={@UniqueConstraint(columnNames=userId,points),@UniqueConstraint(columnNames=userId,percentage))
两者都不适用于您提到的业务规则。
@UniqueConstraint(columnNames=userId,points)
只允许userId和points的唯一组合;@UniqueConstraint(columnNames=userId,percentage)
只允许用户ID和百分比的唯一组合。您可以使用相同的列来表示点和百分比,如score int
。然后使用“假定小数点”存储百分比,如25.7%score=257
。这样,就不需要约束
您还可以将scoreType
移动到UserScore
表中,以便为每个用户混合评分——毕竟,它确实描述了评分
CREATE TABLE UserScore (
id int
,[userID] int
,scoreType varchar(3)
,score int
)
查询表时(SQL server):
我从您的描述中读到的是,用户在userScore中只能有一个条目,该条目只能包含点数或百分比,但不能同时包含两者。如果是这样,则用户和userScore表应该只是一个包含userId、points、percentage列的表。scoreType已经是隐式的,可以省略。然后使用复选框培训以确保只填写一个分数和百分比
CREATE TABLE User (
userId int PRIMARY KEY,
points int,
percentage numeric,
CHECK (points IS NULL OR percentage IS NULL),
CHECK (points IS NOT NULL OR percentage IS NOT NULL) -- if desired
);
如果确实需要scoreType列,请创建一个视图:
CREATE VIEW UserView AS
SELECT userId,
CASE WHEN points IS NOT NULL THEN 'points'
ELSE 'percentage' END AS scoreType
...
FROM User;
这里有两种情况,取决于您能够/允许将多少更改引入现有模式 如果您可以更改架构,最简单的解决方案是仅使用一个字段,并使用用户记录中的scoreType字段来确定如何解释数据。如果您的百分比始终为小数点后两位,则您可以创建如下表:
CREATE TABLE userScore (
id INT,
userID INT,
scoreValue INT
);
SELECT id,
CASE WHEN scoreType = 'points' THEN scoreValue ELSE NULL END as points,
CASE WHEN scoreType = 'percentage' THEN scoreValue / 100.0 ELSE NULL END as percentage
WHERE userID = ?
然后像这样查询:
CREATE TABLE userScore (
id INT,
userID INT,
scoreValue INT
);
SELECT id,
CASE WHEN scoreType = 'points' THEN scoreValue ELSE NULL END as points,
CASE WHEN scoreType = 'percentage' THEN scoreValue / 100.0 ELSE NULL END as percentage
WHERE userID = ?
现在不需要任何形式的约束
如果用户的scoreType字段可以更改,并且所使用的字段(分数或百分比)将取决于存储分数时scoreType的值,则必须将scoreType添加到我的userScore版本中,以保持解释每条记录数据的规则,因为不能依赖父记录的一致性(但它确实消除了连接的需要)
如果您没有更改模式的选项,则可以使用ON INSERT/UPDATE触发器获取scoreType字段,以验证生成的记录只在正确的字段中有一个值(为清楚起见,v_*字段是变量/参数):
希望这些想法中的一个能有所帮助!当分数类型为“分”时,您可以尝试将百分比默认为一些荒谬的值 当scoreType为percentage时,对分数执行相同的操作。 场景1:User=Bob,ScoreType=Points
User= Bob, Points=2.5,Percentage -100000 (Default value for percentage)
然后您可以定义一个复合主键
@表(name=“UserScore”,uniqueConstraints={
@UniqueConstraint(columnNames=userId,points,percentage)}是的,我需要的是类似@UniqueConstraint(userId,points或percentage)的东西基于User.scoreType。不清楚如何实现此限制。是否有办法修改架构以获得类似的结果?我很抱歉没有说得很清楚,User表与UserScore表有一个单一的关系,因此上述解决方案不适合我使用。我很抱歉没有说得很清楚显然,用户表与UserScore表有一个OneToMany关系。如果scoreType是points,我希望UserScore表中存储的所有值都是points列的一部分,如果scoreType是percentage,我希望所有值都在percentage列中。
User= Bob, Points=2.5,Percentage -100000 (Default value for percentage)