mySQL 复合键、主键、唯一键和对复合键的引用

标签 mysql sql database-design foreign-keys create-table

我对特定键以及如何引用它们有疑问。我正在学习,这将非常有帮助,在此先感谢您。

在 SQL 中,这些样式有什么区别?

另外,当创建复合主键时,外键也必须有一个复合外键来匹配复合主键。在第一个表中,如果我在规范中添加了 unique 而没有创建外部组合,我可以引用它,但是如果我删除了 unique,我就无法引用主键,因为它是一个组合。为什么添加 unique 允许我在没有外部复合键的情况下引用第一个表中的复合主键?另外,为什么我可以在组合键中添加 UNIQUE 键?

此外,这是否类似于在第二张表中添加 UNIQUE KEY 组合?第三个表不允许我引用该表,因为我必须有一个复合外键。

CREATE TABLE college.LocationNTime(
    CourseN INT,
    `Quarter` VARCHAR(30) UNIQUE,
    DayTime VARCHAR(30) UNIQUE,
    RoomN INT,
    PRIMARY KEY (CourseN, `Quarter`, DayTime),
    FOREIGN KEY (CourseN) REFERENCES Course(CourseN)
);
CREATE TABLE college.LocationNTime(
    CourseN INT,
    `Quarter` VARCHAR(30),
    DayTime VARCHAR(30),
    RoomN INT,
    PRIMARY KEY (CourseN),
    UNIQUE KEY(`Quarter`, DayTime),
    FOREIGN KEY (CourseN) REFERENCES Course(CourseN)
);
CREATE TABLE college.LocationNTime(
    CourseN INT,
    `Quarter` VARCHAR(30),
    DayTime VARCHAR(30),
    RoomN INT,
    PRIMARY KEY (CourseN, `Quarter`, DayTime),
    FOREIGN KEY (CourseN) REFERENCES Course(CourseN)
);

最佳答案

PRIMARY KEY (CourseN, `Quarter`, DayTime),
FOREIGN KEY (CourseN) REFERENCES Course(CourseN)

在此构造中,您将创建一个包含列 (CourseN, Quarter DayTime) 的复合主键。这意味着这三列的值的任何组合在表中必须是唯一的。此外,您指出 CourseN 是引用表 Course 中同义词列的外键,因此您引用表中 CourseN 列的每个值LocationNTime 必须出现在引用的表 Course 中。

这看起来像是一个有效的设置,其中 LocationNTime 就像是 Course 的从属表(像子表或类似的)。


PRIMARY KEY (CourseN),
UNIQUE KEY(`Quarter`, DayTime),
FOREIGN KEY (CourseN) REFERENCES Course(CourseN)

这里,CourseN 是表的主键,因此该列中的每个值都必须是唯一的。但它也是 Course 的外键。这在规范化方面并没有真正意义:如果 LocationNTime 中的每条记录都与 Course 中的唯一记录相关,那么为什么要创建两个表而不是存储所有Course 中单个记录中的数据?

除此之外,您正在 (Quarter, DayTime) 上创建唯一约束,因此表示这些列中值的组合是唯一的。

这个设计看起来有缺陷。


考虑以下数据集:

CourseN    Quarter    DayTime
1          1          14:00:00
1          2          14:10:00
1          3          14:00:00
1          4          14:10:00

第一个设计将允许此数据集,而第二个则不允许,因为它们在 CourseN 中是重复的。也不允许使用以下数据集,因为 (Quarter, DayTime) 中存在重复项:

CourseN    Quarter    DayTime
1          1          14:00:00
2          2          14:10:00
3          1          14:00:00
4          2          14:10:00

我相信第一个设计可能就是您所需要的。


最后:您似乎认为具有外键约束的列(此处为LocationNTime(CourseN))需要UNIQUE:事实并非如此.它唯一需要的是一个索引(当你声明它时,MySQL 会在后台为你创建它)。它是由外键引用的列(此处为 Course(CourseN))需要唯一。

关于mySQL 复合键、主键、唯一键和对复合键的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58230589/

相关文章:

php - MySQLi 等效的 MySQL 代码

sql - 论坛线程投票/ View 的数据库架构,以及增加和显示 View 数量的策略

sql-server - 数据库设计建议-涉及多个表的关系

android - 如何将数据提供给网站的移动应用程序

mysql - 计算 Sql 表中的不同值

php - 根据列的字符串长度从 MySQL 中进行选择 - CodeIgniter

mysql - 如何将 "COUNT"与 "GROUP BY"和 "WHERE"一起使用

PHP 使用 IF 更新查询

mysql - 在 MySql 中将 VARCHAR 转换为 DECIMAL 值

sql - PostgreSQL 查找周围的值