Я должен индексировать внешний ключ?Должен ли я использовать первичный ключ для этой таблицы? - PullRequest
0 голосов
/ 04 ноября 2011
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 обновляться при обновлении соответствующих идентификаторов из других таблиц, и я пытаюсь отслеживать изменения.

Я не смог найти четкого руководства, как это сделать, и эти запросы работают частично, но не полностью. Я не думаю, что мне нужен первичный ключ в этой таблице, но я получаю предупреждение: "Warning, table contains no primary key", когда я не использую первичные ключи. Итак, я только что добавил столбец «id». Я не думаю, что это на самом деле нужно, хотя.

Пожалуйста, сообщите.

Спасибо.

Ответы [ 3 ]

2 голосов
/ 05 ноября 2011

Вы получаете эту ошибку из-за пропущенной запятой:

...  
  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),

Это будет НЕ выдает какую-либо ошибку, но механизм SQL не будет проверять на наличие этого ограничения.Как объясняется в документах MySQL в CREATE TABLE, ограничения CHECK :

Предложение CHECK анализируется, но игнорируется всеми механизмами хранения.

1 голос
/ 04 ноября 2011

Клей показал вам, как сделать каскад, поэтому позвольте мне добавить это:

Часто хорошей идеей является создание индекса для внешнего ключа.Если вы делаете каскад, вы действительно должны.

Я не думаю, что в стандартном SQL есть какой-либо способ создать индекс как часть CREATE TABLE.(MYSQL может иметь расширение для этого - я признаю, что не проверял.) Так что вам следует просто создать индекс отдельно.

create index idx_titlexplan_title on titlexplan (title_id);
create index idx_titlexplan_plan on titlexplan (plan_id);
1 голос
/ 04 ноября 2011
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   
);
...