我需要帮助设置外键才能迁移到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)。我不知道在这种情况下,多列索引(作业)或两个单独的索引(客户/联系人)是否会有所帮助。
在我还在学习的时候,请放轻松。谢谢你的时间。
答案 0 :(得分:0)
这可能与外键有关,还是我必须用我选择的编程语言进行验证?
是的,是的。
这是FK为您的数据添加的参照完整性。但是,如果您还没有在应用程序中对其进行说明,那么您将提供一种糟糕的用户体验,允许用户输入不属于客户的联系人,并在提交给DB后收到错误。最好在你的应用程序中考虑到这一点,以防止这种情况被发送到数据库,并且FK是一种备份,以防止以某种方式通过。
我的另一个目标是设置索引以列出所有非空的作业(status_void = 0)以及所有非活动的客户和联系人(非活动= 0)。我不知道在这种情况下,多列索引(作业)或两个单独的索引(客户/联系人)是否会有所帮助。
要构建的索引往往是特定于查询的。因此,您希望显示一个示例查询,以便最好地获取索引建议,而不仅仅是您的最终目标。重要的是要知道查询中每个表引用只能使用一个索引。因此,如果一个表在where子句中有多个过滤器,那么通过使用多列索引可以获得最佳性能。
在规划索引时,最好考虑哪些列具有较少的唯一值,这些值将过滤掉较大数量的行并在索引中首先列出这些行。
所有这一切,如果没有代表性的查询和解释声明的结果,外部人员就索引的建议不能做太多,因为它们的有效性取决于它们被用来对抗的数据。 / p>