0

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

一个工作属于一个客户,一个工作属于一个联系人。客户有很多工作并有很多联系人。一个联系人属于一个客户并且有很多工作。我需要帮助在工作表中设置外键,以便只能插入属于选定客户的联系人。(即如果客户 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)以及所有非非活动的客户和联系人(非活动=0)。我不知道在这种情况下多列索引(工作)或两个单独的索引(客户/联系人)是否会有所帮助。

请放轻松,因为我还在学习。感谢您的时间。

4

1 回答 1

0

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

是的,是的。

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

我的另一个目标是设置索引以列出所有非无效的工作(status_void=0)以及所有非非活动的客户和联系人(非活动=0)。我不知道在这种情况下多列索引(工作)或两个单独的索引(客户/联系人)是否会有所帮助。

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

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

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

于 2012-11-06T01:18:37.953 回答