我应该索引一个外键吗?我应该使用此表的主键吗?

时间:2011-11-04 16:03:56

标签: mysql database-design foreign-keys timestamp primary-key

CREATE TABLE titlexplan(
  id INTEGER NOT NULL,
  title_id INTEGER NOT NULL ,
  plan_id INTEGER NOT NULL ,
  start_date DATETIME NOT NULL,
  end_date DATETIME
  CHECK (start_date < end_date),
  PRIMARY KEY(id),
  INDEX (title_id),
    FOREIGN KEY (title_id)
    REFERENCES title(id)
  INDEX (plan_id),
    FOREIGN KEY (plan_id)
    REFERENCES plan(id)    
);

这是我正在使用的代码,我收到语法错误:#​​1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INDEX (plan_id), FOREIGN KEY (plan_id) REFERENCES plan(id) )' at line 10

我正在尝试让title_id和plan_id在其他表的相应ID更新时更新,并且我正在尝试跟踪更改。

我无法找到如何执行此操作的明确指南,这些查询部分工作但不是整体工作。我认为我不需要在此表中使用主键,但我收到警告:“Warning, table contains no primary key,”当我不使用主键时。所以,我刚刚添加了'id'列。不过,我并不认为它确实需要。

请告知。

谢谢。

3 个答案:

答案 0 :(得分:2)

由于缺少逗号,您收到该错误:

...  
  INDEX (title_id),
    FOREIGN KEY (title_id)
    REFERENCES title(id)  ,        ---  <---- missing comma here
  INDEX (plan_id),
    FOREIGN KEY (plan_id)
    REFERENCES plan(id) 
);

另一件事是你有CHECK约束:

CHECK (start_date < end_date),

这将 NOT 产生任何错误,但SQL引擎不会检查该约束。正如MySQL文档在 CREATE TABLE, CHECK constraints 中所解释的那样:

  

CHECK子句被解析但被所有存储引擎忽略。

答案 1 :(得分:1)

CREATE TABLE titlexplan(
  id INTEGER NOT NULL,
  title_id INTEGER NOT NULL ,
  plan_id INTEGER NOT NULL ,
  start_date DATETIME NOT NULL,
  end_date DATETIME
  CHECK (start_date < end_date),
  PRIMARY KEY(id),

  FOREIGN KEY (title_id)
  REFERENCES title(id)
  ON UPDATE CASCADE,

  FOREIGN KEY (plan_id)
  REFERENCES plan(id)
  ON UPDATE CASCADE
);

我相信这应该有效。 “ON UPDATE CASCADE”将导致这些外键在他们引用更新的任何时候更新。

还要确保使用innoDB引擎使外键正常工作。

如果您不想要id列,并且title_id和plan_id的组合始终是唯一的,那么您可以

CREATE TABLE titlexplan(
  title_id INTEGER NOT NULL ,
  plan_id INTEGER NOT NULL ,
  start_date DATETIME NOT NULL,
  end_date DATETIME
  CHECK (start_date < end_date),
  PRIMARY KEY(title_id, plan_id),

  FOREIGN KEY (title_id)
  REFERENCES title(id)
  ON UPDATE CASCADE,

  FOREIGN KEY (plan_id)
  REFERENCES plan(id)
  ON UPDATE CASCADE   
);

答案 2 :(得分:1)

Clay向您展示了如何进行级联,所以让我添加一下:

在外键上创建索引通常是个好主意。如果你正在做一个级联,你真的应该。

我认为标准SQL中没有任何方法可以创建索引作为CREATE TABLE的一部分。 (MYSQL可能有一个扩展来执行此操作 - 我承认我没有检查。)所以你应该单独创建索引。

create index idx_titlexplan_title on titlexplan (title_id);
create index idx_titlexplan_plan on titlexplan (plan_id);