数据库中两个表之间的关系更灵活?

时间:2016-12-08 00:58:38

标签: database postgresql foreign-keys table-relationships

我们假设有两个表。(我做了示例表只是为了解释我的想法的概念,定义它会有一些错误。)

TableA '用户'

CREATE TABLE user
(
  id serial PRIMARY KEY
  name character varying(80) UNIQUE NOT NULL,
)

TableB '历史'

CREATE TABLE history
(
  id serial PRIMARY KEY,
  action character varying(80) NOT NULL,
  CONSTRAINT history_action_key UNIQUE (name)
)

我认为有两种方法可以在两个表之间建立关系。

单向:在一个表中添加ForeignKey约束

CREATE TABLE user
    (
      id serial PRIMARY KEY,
      name character varying(80) NOT NULL UNIQUE,
      history_id integer REFERENCES history
    )

这意味着还有另一个名为history_id的字段,用于在用户表中使用FK指向相关历史记录。正确?

第二种方式:您正在创建新表格(比如说TableC'关系')。 TableC将仅显示TableA和TableB之间的关系

CREATE TABLE relationship
(
  id serial PRIMARY KEY,
  user_id integer NOT NULL REFERENCES remann_users (id),
  history_id integer NOT NULL REFERENCES history,
)

所以我的问题

在数据库中存储数据的第二种方式更灵活吗?

我觉得第二种方式似乎更灵活 因为用户表和历史记录表在各个表中完全分开。只是另一张表有数据来告诉他们的关系。但第一种方式似乎用户表有一个字段' history_id'在它的表格中。所以我觉得它的方式是两个表之间更多的耦合。

我的想法是否正确?

我认为我先与许多托马尼的关系感到困惑。

'用户'表格中包含以下数据

pk name

1 John

2亚当

3凯莉

'历史'表格中包含以下数据

行动

1打了baksetball

2玩视频游戏

现在我想在用户和历史之间建立关系。

如果John扮演baksetball,Adam打篮球,Kelly玩电子游戏,我可以通过在用户表中添加一列来建立关系。

'用户'表

pk name fk

1 John 1

2 Adam 1

3 Kelly 2

但如果有一个案例,约翰打篮球,同时玩视频游戏。这成了许多托马尼的关系。我需要像下面这样表达这种关系。

'用户'表

pk name first action(fk)second action(fk)

1 John 1 2

2 Adam 1 NULL

3 Kelly 2 NULL

但这不是一个好主意,因为如果要向一个特定用户添加更多操作,则必须更改架构。例如,用户玩baksetball,踢足球和玩视频游戏。你需要添加第三个动作(fk),其他用户行将具有空值。

因此您可以创建另一个表来组合两个表而不会出现此问题。这将是我上面解释的第二种方式。制作另一个表来显示两个表之间的关系只是使它在许多情况下更有效的方法。正确?

这是我对你的答案感到困惑的原因。 "更灵活" 更灵活意味着如果你有像第二种方式的桥牌表或只是m2m关系更灵活,显示m2m数据更灵活?我比什么更困惑?

1 个答案:

答案 0 :(得分:0)

  

这意味着还有另一个名为history_id的字段,用于在用户表中使用FK指向相关历史记录。正确?

无论你想要什么,都可以命名,但是。

  

我觉得第二种方式似乎更灵活,因为用户表和历史表在各个表中完全分开。只是另一张表有数据来告诉他们的关系。但第一种方式似乎用户表有一个字段' history_id'在它的表格中。所以我觉得它的方式是两个表之间更多的耦合。 ...... 我的想法是否正确?

我得到了我的想法。是的,你是对的。您调用关系表的内容确定了数据库管理员调用Many-to-many模型的内容。

  • 它更灵活。
  • 它也慢了。
  • 查询起来比较困难。

问题是用户可以有多个历史记录,如果他们不知道为什么你要使所有的查询变得更加复杂到支持吗?

在PostgreSQL的普通M2M表格中,你有类似的东西,

CREATE TABLE user (
  user_id serial PRIMARY KEY,
  name    text   NOT NULL
);
CREATE TABLE history (
  history_id serial PRIMARY KEY,
  tz         timestamp DEFAULT NOW()
);
CREATE TABLE relationship (
  user_id int REFERENCES users,
  history_id integer REFERENCES history,
  PRIMARY KEY (user_id, history_id)
)
  • 如果您有一个拥有两个历史记录的用户会怎样?

INSERT INTO relationship VALUES (1,1), (1,2);
  • 如果我们有两个具有相同历史记录的用户会怎样?

INSERT INTO relationship VALUES (1,1), (2,1);

如果您的应用无法实现这些功能,请不要多对多。