Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql 如果我对PK使用约束会发生什么?_Postgresql_Constraints - Fatal编程技术网

Postgresql 如果我对PK使用约束会发生什么?

Postgresql 如果我对PK使用约束会发生什么?,postgresql,constraints,Postgresql,Constraints,如果我有一个PK,并对其进行了限制,会发生什么。 我知道,当我尝试在DB中写入同一个实体时,它将覆盖它,而不是由于约束而产生冲突。 问题是为什么? 它会覆盖它,因为它是用hibernates(spring数据jpa)编写的,方法是jpaRepository.save()。因此,如果实体具有相同的主键,并且所有其他列都相同,那么它会覆盖实体 即使在以下情况下也会发生这种情况: 我对3个VARCHAR列有一个约束:(名称、版本、类型) 我有一个由3个varchar组成的PK:name\u versi

如果我有一个PK,并对其进行了限制,会发生什么。 我知道,当我尝试在DB中写入同一个实体时,它将覆盖它,而不是由于约束而产生冲突。 问题是为什么? 它会覆盖它,因为它是用hibernates(spring数据jpa)编写的,方法是jpaRepository.save()。因此,如果实体具有相同的主键,并且所有其他列都相同,那么它会覆盖实体

即使在以下情况下也会发生这种情况: 我对3个VARCHAR列有一个约束:(名称、版本、类型) 我有一个由3个varchar组成的PK:name\u version\u type

创建模式时,sql文件中的spring和flyway会发生以下情况:

CREATE TABLE package
(
   id surrogate_id PRIMARY KEY,
   CONSTRAINT uq_package_name_version_type UNIQUE(surrogate_id),
   name VARCHAR NOT NULL,
   version VARCHAR NOT NULL,
   type VARCHAR NOT NULL
)
;
public static final String hash(String name, String version, String type)
{
    return new StringBuilder().append(name)
                              .append("_").append(version)
                              .append("_").append(type)
                              .toString();
}
这就是java中使用Hibernate时发生的情况:

@Table(name = PackageEntity.TABLE_NAME, uniqueConstraints = {
    @UniqueConstraint(columnNames = {"package"}, name = ConstraintName.SURROGATE_ID)})
各栏:

@NotNull
private String name;

@NotNull
private String version;

@NotNull
private String type;

@Id
@Column(name = "surrogate_id")
private String surrogateId;
以及如何创建代理id:

CREATE TABLE package
(
   id surrogate_id PRIMARY KEY,
   CONSTRAINT uq_package_name_version_type UNIQUE(surrogate_id),
   name VARCHAR NOT NULL,
   version VARCHAR NOT NULL,
   type VARCHAR NOT NULL
)
;
public static final String hash(String name, String version, String type)
{
    return new StringBuilder().append(name)
                              .append("_").append(version)
                              .append("_").append(type)
                              .toString();
}

我希望它看到相同的PK并试图覆盖实体,但我也希望停止事务,因为它在3列上看到冲突。这不会发生。它只考虑PK。为什么?

允许但多余地在主键上添加
UNIQUE
约束,因为主键意味着唯一性


您应该删除额外的约束,因为它会导致创建额外的索引,这将浪费空间并减慢数据修改的速度。

允许但多余地在主键上添加
唯一
约束,因为主键意味着唯一性


您应该删除额外的约束,因为它会导致创建额外的索引,这将浪费空间并减慢数据修改的速度。

在spring
JpaRepository
中,默认情况下,
保存操作如下所示:

  • 如果实体没有设置主键(带有
    @Id
    注释的字段),则使用
    INSERT
    SQL语句在数据库中创建新记录
  • 如果实体确实有主键-则使用
    UPDATE
    SQL语句修改现有记录
  • 因此,在您的情况下,spring认为您正在更新现有实体,并且没有发生插入,因此不会发生冲突。这就是为什么约束是无用的


    为了克服这个问题,您可以实现接口和
    isNew
    方法,专门让spring知道您正在插入一个新实体。在这种情况下,spring将执行插入操作,而不进行更新。

    在spring
    JpaRepository
    中,默认情况下,
    保存操作如下所示:

  • 如果实体没有设置主键(带有
    @Id
    注释的字段),则使用
    INSERT
    SQL语句在数据库中创建新记录
  • 如果实体确实有主键-则使用
    UPDATE
    SQL语句修改现有记录
  • 因此,在您的情况下,spring认为您正在更新现有实体,并且没有发生插入,因此不会发生冲突。这就是为什么约束是无用的


    为了克服这个问题,您可以实现接口和
    isNew
    方法,专门让spring知道您正在插入一个新实体。在这种情况下,spring将执行insert而不是update。

    当您有一个主键并尝试插入具有相同主键的行时,它不会更新它(除非您使用UPSERT)。它抛出了一个重复键的错误,并且看不到任何其他构造。如果无法插入行,则查看其他内容是没有意义的。如果您有一个PK并尝试插入具有相同PK的行,则不会更新该PK(除非您使用UPSERT)。它会抛出一个重复键错误,并且不会查看任何其他解释。如果无法插入行,则查看其他任何内容都没有意义。您可以(通过单击下面的链接)提问吗并添加
    CREATE TABLE
    语句,包括您创建的所有约束,谢谢,先生!我现在就知道了。谢谢,先生!我现在就知道了。所以考虑到@Roman Konova的回答,这意味着它进行了更新,但没有约束,因为约束由于PK而被忽略,对吗?不,唯一的
    约束Is在更新过程中被选中,因为它由唯一索引支持。因此,您需要付出两次唯一性检查(和两次索引修改)的代价,但您没有任何好处,因为主键已经保证了唯一性。因此,考虑到@Roman Konova的回答,这意味着它进行了更新,但没有约束,因为约束由于PK而被忽略,对吗?不,在
    更新过程中检查
    唯一
    约束,因为它有唯一的i因此,您需要付出两次唯一性检查(和两次索引修改!)的代价,但您没有任何好处,因为主键已经保证了唯一性。