代码之家  ›  专栏  ›  技术社区  ›  mherzl

有两个具有双射行对应的SQL表是一种好的做法吗?

  •  2
  • mherzl  · 技术社区  · 8 年前

    我有一张任务表,

     id | name
    ----+-------------
     1  | brush teeth
     2  | do laundry
    

    还有一张州表。

     taskid | state
    --------+-------------
     1      | completed
     2      | uncompleted
    

    表之间存在双射对应,即。 中的每一行 task 表正好对应于 state 桌子

    另一种实现方法是放置 状态 中的行 任务 桌子

     id | name        | state
    ----+-------------+-------------
     1  | brush teeth | completed
     2  | do laundry  | uncompleted
    

    我选择使用两个表而不是这一个表的主要原因是更新 状态 然后将导致任务发生更改 id . 我有其他表引用 task(id) 列,并且不希望在更改任务状态时也必须更新所有其他表。

    关于这一点,我有两个问题。

    1. 在双射行-行对应中有两个表是好的做法吗?
    2. 是否有办法确保约束中只有一行 状态 中每行对应的表 任务 桌子

    我使用的系统是 postgresql .

    1 回复  |  直到 8 年前
        1
  •  4
  •   Gordon Linoff    8 年前

    您可以通过将每个表中的id设置为主键和引用另一个表中id的外键来确保1-1对应。这是允许的,可以保证1-1'ness。

    有时,您需要这样的表,但其中一个表的行数比另一个表的行数少。当存在子集关系,并且不希望所有行上都有额外的列时,就会发生这种情况。

    另一个目的是在不同的地方存储单独的列。当我了解数据库时,这种方法被称为 垂直分区 . 如今,柱状数据库比较常见;这些将这个概念发挥到了极致——每个列都有一个单独的“存储”(虽然“存储”并不完全是一个“表”)。

    你为什么要这样做?以下是一些原因:

    • 您有一些不经常使用的列,您不想为更频繁的列上的每个查询加载这些列。
    • 您经常更新列,不想锁定其余列。
    • 您的列太多,无法存储在一行中。
    • 您对不同的列有不同的安全要求。

    Postgres确实提供了您可能会觉得相关的其他机制。特别是,表继承在您的情况下可能会很有用。

    尽管如此,您通常不会设计这样的数据库。这样做有很好的理由,但更典型的做法是将与实体相关的所有列放在同一个表中。