1

我有以下表格:

CREATE TABLE `students` (
    `student_id`            int NOT NULL AUTO_INCREMENT,        
    `student_name`          varchar(40) NOT NULL DEFAULT '',
    PRIMARY KEY (`student_id`)
);

CREATE TABLE `courses` (
    `course_id`             int NOT NULL AUTO_INCREMENT,        
    `course_name`           varchar(40) NOT NULL DEFAULT '',
    PRIMARY KEY (`course_id`)
);

CREATE TABLE `students_courses` (
    `id`                    int NOT NULL AUTO_INCREMENT,        
    `student_id`            int NOT NULL DEFAULT '0',
    `course_id`             int NOT NULL DEFAULT '0',
    PRIMARY KEY (`id`)
);

在这里,我使用students_courses表来存储学生和课程之间的关系。因为一名学生可以注册多于一门课程。

我的疑问是,应该索引什么以及如何索引该表。

1)我应该像这样单独索引student_idcourse_id

CREATE TABLE `students_courses` (
    `id`                    int NOT NULL AUTO_INCREMENT,        
    `student_id`            int NOT NULL DEFAULT '0',
    `course_id`             int NOT NULL DEFAULT '0',
    PRIMARY KEY (`id`),
    KEY (`student_id`),
    KEY (`course_id`)
);

student_id2) 或者,为and创建一个复合索引course_id

CREATE TABLE `students_courses` (
    `id`                    int NOT NULL AUTO_INCREMENT,        
    `student_id`            int NOT NULL DEFAULT '0',
    `course_id`             int NOT NULL DEFAULT '0',
    PRIMARY KEY (`id`),
    KEY (`student_id`, `course_id`)
);

3)如果使用复合键,我应该删除那个id主键并使 PRIMARY KEY 复合吗?

我将主要在 JOIN 期间使用此关系表。所以在这里有点困惑。

4

1 回答 1

2

假设我们坚持使用 Auto Incrementid列作为主键。现在,我们还需要确保数据是一致的,值的组合没有重复的行(student_id, course_id)。因此,我们需要在应用程序代码中处理这个问题(每次在插入/更新之前进行选择),或者我们可以通过UNIQUE(student_id, course_id).

现在,主键基本上是唯一的非空键。如果您查看表定义,这个新定义的 UNIQUE 约束基本上只是一个主键(因为字段也不是 NULL)。因此,在这种特殊情况下,您实际上并不需要使用代理主键id

随机 DML(插入/更新/删除)期间的开销差异很小,因为仅使用 UNIQUE 索引时也会有类似的开销。因此,您可以定义一个 Natural Primary Composite Key (student_id, course_id)

-- Drop the id column
ALTER TABLE students_courses DROP COLUMN id;

-- Add the composite Primary Key
ALTER TABLE students_courses ADD PRIMARY(student_id, course_id);

上面还将对(student_id, course_id). 此外,您将每行节省4 个字节(大小int为 4 个字节)。当您有大桌子时,这将派上用场。

现在,在从表连接时studentsstudents_courses主键上方将是一个足够的索引。courses但是,如果您需要从students_courses表连接,则需要另一个键来实现此目的。course_id因此,您可以按如下方式再定义一个键:

ALTER TABLE students_courses ADD INDEX (course_id);

此外,您应该定义外键约束以确保数据完整性:

ALTER TABLE students_courses ADD FOREIGN KEY (student_id) 
                             REFERENCES students(student_id);

ALTER TABLE students_courses ADD FOREIGN KEY (course_id) 
                             REFERENCES courses(course_id);
于 2019-10-03T08:57:51.380 回答