【问题标题】:sqlite what happens to id when you delete a row with a foreign key?sqlite 删除带有外键的行时 id 会发生什么?
【发布时间】:2022-01-06 04:31:35
【问题描述】:

我有这两张表:

class User(Base):
    """ User entry in database """
    __tablename__ = "users"
    # ID uniquely identifies 
    id             = Column(Integer, primary_key=True, index=True)
    kerberos       = Column(String, unique=True, index=True)
    hashpass       = Column(String)
    is_active      = Column(Boolean, default=True)
    creation_date  = Column(DateTime, default=None)

    scores = relationship("Score", back_populates="owner")

class Score(Base):
    """ Stores each users scores """
    __tablename__ = "scores"
    
    id    = Column(Integer, primary_key=True, index=True)
    user_id = Column(String, ForeignKey("users.id"), index=True)    
    score = Column(Integer)
    time = Column(DateTime)
    
    owner = relationship("User", back_populates="scores")

我已经读到添加新的“用户”会自动增加“id”字段。 现在,“scores”表中的每个条目都有一个指向 users.id 的外键。这意味着(如果我错了,请纠正我),每个“分数”条目都映射到一个且唯一的唯一用户(因此分数:用户关系是多:一个)。

我想知道这是否是一个好的设计,特别是如果我删除一个用户,会发生什么? 删除用户是否会自动使通过已删除用户的 id(这些分数的外键)链接的相应分数无效/删除?我担心删除用户之后,所有用户 id 都会下移一位,因此在查看用户的分数时会出现一个问题。

这是好的设计吗?随意链接资源/重定向到另一个问题(我找不到任何具体的问题)

【问题讨论】:

    标签: sql database sqlite orm fastapi


    【解决方案1】:

    我想知道这是否是一个好的设计,尤其是如果我删除了一个用户,会发生什么?

    就目前而言,您将无法删除用户,因为会导致外键冲突。如果您没有 FK 约束来保护参照完整性,那么您将孤立分数(它们将没有父级),这可能会导致意外结果甚至崩溃。

    为了能够删除用户,我相信你可以使用ForeignKey("users.id", onupdate="CASCADE", ondelete="CASCADE")

    然后删除用户(父级)将 CASCADE 删除,从而删除由于onDelete="CASCADE" 而导致的子级(链接到该特定父级的分数)。

    如果您更改用户的 id 值,那么子项中的 user_id 将被更改(即对 id 的更新将向下级联到子项)。

    我担心删除一个用户之后所有用户 ID 都会向下移动一个,

    不,它们不会,除非您制作它们(您可能不想这样做)。但是,如果将 onUpdate 操作作为 CASCADE,如果 id 发生更改,则对 id 的更改将被 CASCADEd。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-08
      • 1970-01-01
      • 2021-09-04
      相关资源
      最近更新 更多