设置MySQL外键和索引-迁移到InnoDB

设置MySQL外键和索引-迁移到InnoDB,mysql,foreign-keys,innodb,indexing,Mysql,Foreign Keys,Innodb,Indexing,我需要帮助设置外键以迁移到InnoDB。情况是,我有3张表:工作、客户和联系人 工作属于客户,工作属于联系人。客户有很多工作和联系人。联系人属于客户,有许多工作。我需要帮助在jobs表中设置外键,以便只能插入属于选定客户的联系人。(即,如果客户A有联系人A1和A2,而客户B有联系人B1,一旦您选择客户A作为工作的客户,它将拒绝A1或A2以外的联系人条目)。这是否可能与外键有关,或者我必须用我选择的编程语言进行验证 以下是我的模式: CREATE TABLE jobs( job_id INT(

我需要帮助设置外键以迁移到InnoDB。情况是,我有3张表:工作、客户和联系人

工作属于客户,工作属于联系人。客户有很多工作和联系人。联系人属于客户,有许多工作。我需要帮助在jobs表中设置外键,以便只能插入属于选定客户的联系人。(即,如果客户A有联系人A1和A2,而客户B有联系人B1,一旦您选择客户A作为工作的客户,它将拒绝A1或A2以外的联系人条目)。这是否可能与外键有关,或者我必须用我选择的编程语言进行验证

以下是我的模式:

CREATE TABLE jobs(
  job_id INT(11) NOT NULL AUTO_INCREMENT,
  customer_id INT(11) DEFAULT NULL,
  contact_id INT(11) DEFAULT NULL,
  job_number INT(11) UNSIGNED NOT NULL DEFAULT 0,
  status_void TINYINT(1) DEFAULT 0,
  PRIMARY KEY (job_id),
  INDEX active_jobs (job_number, status_void),
  INDEX customer_id (customer_id),
  UNIQUE INDEX job_number (job_number),
  CONSTRAINT FK_jobs_contacts_contact_id FOREIGN KEY (contact_id)
  REFERENCES contacts (contact_id) ON DELETE SET NULL ON UPDATE CASCADE,
  CONSTRAINT FK_jobs_customers_customer_id FOREIGN KEY (customer_id)
  REFERENCES customers (customer_id) ON DELETE SET NULL ON UPDATE CASCADE
)
ENGINE = INNODB
CHARACTER SET utf8
COLLATE utf8_general_ci;`

CREATE TABLE customers(
  customer_id INT(11) NOT NULL AUTO_INCREMENT,
  inactive TINYINT(1) DEFAULT 0,
  customer_name VARCHAR(50) NOT NULL DEFAULT '',
  PRIMARY KEY (customer_id),
  UNIQUE INDEX customer_name (customer_name),
  INDEX inactive (inactive)
)
ENGINE = INNODB
CHARACTER SET utf8
COLLATE utf8_general_ci;

CREATE TABLE contacts(
  contact_id INT(11) NOT NULL AUTO_INCREMENT,
  customer_id INT(11) DEFAULT NULL,
  inactive TINYINT(1) DEFAULT 0,
  first_name VARCHAR(50) DEFAULT NULL,
  last_name VARCHAR(50) DEFAULT NULL,
  PRIMARY KEY (contact_id),
  UNIQUE INDEX contact_key (customer_id, last_name, first_name),
  INDEX customer_id (customer_id),
  INDEX inactive (inactive),
  INDEX name (last_name, first_name),
  CONSTRAINT fk_contacts_customers_customer_id FOREIGN KEY (customer_id)
  REFERENCES customers (customer_id) ON DELETE RESTRICT ON UPDATE CASCADE
)
ENGINE = INNODB
CHARACTER SET utf8
COLLATE utf8_general_ci;
我的另一个目标是设置索引,以便列出所有未作废的作业(status_void=0)以及所有未停用的客户和联系人(inactive=0)。我不知道在这种情况下,多列索引(作业)或两个单独的索引(客户/联系人)是否有帮助

我还在学习,请对我放松点。谢谢你抽出时间

这是否可能与外键有关,或者我必须用我选择的编程语言进行验证

是的,是的

这是FKs添加到数据中的引用完整性。但是,如果您在应用程序中没有考虑到这一点,您将呈现一种可怕的用户体验,允许用户输入不属于客户的联系人,并在提交给DB后获得错误。最好在应用程序中说明这一点,以防止这种情况被发送到DB,而FK是一种备份,以防以某种方式通过

我的另一个目标是设置索引,以便列出所有未作废的作业(status_void=0)以及所有未停用的客户和联系人(inactive=0)。我不知道在这种情况下,多列索引(作业)或两个单独的索引(客户/联系人)是否有帮助

要构建的索引往往是特定于查询的。因此,您可能希望显示一个示例查询,以便在索引中获得最佳建议,而不仅仅是您的最终目标是什么。必须知道,查询中的每个表引用只能使用一个索引。因此,如果一个表在where子句中有多个过滤器,那么通过使用多列索引,您往往可以获得最佳性能

在规划索引时,最好考虑哪些列的唯一值较少,从而过滤掉更多的行,并在索引中首先列出这些行


综上所述,如果没有代表性的查询和解释声明的结果,局外人就无法就索引向您提供太多建议,因为索引的有效性取决于它们所针对的数据。

感谢您的回复。出于好奇,如何设置Jobs表的外键,使其只允许属于所选客户的联系人?这不是真正可以做到的。您可以使用FK确保联系人表中存在联系人,使用另一个FK确保客户表中存在客户,但不能在一个表中使用FK强制其他两个表的关系。不过,我确实看到了你的结构中可能存在的问题。有没有可能在没有联系人的情况下找到工作?在我看来,你不需要将工作与客户联系起来,因为他们之间的关系实际上只通过联系人存在。不幸的是,系统需要能够跟踪哪些工作属于联系人。这对与大公司合作很有帮助。如果结构有问题,请告诉我如何跟踪联系人的工作。我可以在应用程序级别强制执行这种关系。我只是想知道是否有办法通过外键强制执行。@KrispyK-可能是误解。我想知道为什么要将作业链接到作业表中的客户。除非联系人是可选字段,否则您可以使用“联系人”表将作业链接到其联系人,并使用该链接链接到客户。联系人是可选字段,但客户是必填字段。在这种情况下,表结构正常吗?