我有一个正在尝试在 SQL 上创建的数据库,并且正在尝试将关系连接在一起。共有三个表:superhero、power 和 superheroPower。表 superhero 和 power 是多对多关系,由表 superheroPower 表示。
下面的语法对于表(以及其他所有内容)之间的外键是否正确?另外,这些表在设置方面还有其他建议吗?
CREATE TABLE superhero( id INT NOT NULL AUTO_INCREMENT,
heroName VARCHAR(255) NOT NULL,
firstName VARCHAR(255),
lastName VARCHAR(255),
firstAppearance DATE,
gender VARCHAR(255),
bio TEXT,
universe VARCHAR(255),
PRIMARY KEY(id)
) ENGINE=InnoDB;
CREATE TABLE power(
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
description TEXT NOT NULL,
PRIMARY KEY(id)
) ENGINE=InnoDB;
CREATE TABLE superheroPower(
superheroID INT,
powerID INT,
PRIMARY KEY(superheroID, powerID),
FOREIGN KEY(superheroID) REFERENCES superhero(id),
FOREIGN KEY(powerID) REFERENCES power(id)
) ENGINE=InnoDB;
最佳答案
是的,那里的一切看起来都不错。但是...
<小时/>一些注意事项:
我们会为gender
列使用更短的数据类型;我不认为我们需要 255 个字符来表达这一点。 (强制执行的行的最大大小有限制。)如果只有几个值,我们会考虑 ENUM
数据类型。
我们还可能在其中几个列上添加 NOT NULL
约束,例如英雄名、名字、姓氏。我们还可能添加DEFAULT ''
。有时,出于某种原因,我们确实需要允许 NULL 值,但我们会尽可能使用 NOT NULL
。
我对 TEXT
列犹豫不决。使用 TEXT
数据类型没有任何问题,但我只是怀疑这些数据类型可能“隐藏”了一些最好存储在其他列中的信息。
对于外键,我们将按照我们使用的模式为约束分配一个名称,并且还可能添加ON UPDATE CASCADE ON DELETE CASCADE
CONSTRAINT FK_superheroPower_power FOREIGN KEY (powerID)
REFERENCES power(id) ON UPDATE CASCADE ON DELETE CASCADE
<小时/>
关于标识符(表名和列名)的注释
我们这样做的方式是,所有表名都是小写的。 (我们有一个 MySQL 选项集,强制所有表名都小写。)我们这样做是为了避免不同操作系统/文件系统(其中一些区分大小写,有些不区分大小写)的不兼容问题。
此外,表名称是单数。表的名称命名了表的一行所代表的内容。我们也不将 _table
作为名称的一部分。
MySQL 中的列名从不区分大小写,但我们也始终使用小写的列名。我们的列名称不使用“驼峰命名法”,我们使用下划线字符作为分隔符,例如power_id
与 powerID
、hero_name
与 heroName
。
跟进
我上面的“注释”并不是必须遵守的具体规则;这些只是我们使用的模式。
遵循这些模式并不能保证我们会拥有成功的软件,但它确实对我们有帮助。
为了供您引用,我将展示这些 table 作为我们商店的“初剪”的外观,作为另一种图案的说明;这不是“正确的方式”,这只是我们作为一个团队确定的“一种方式”。
CREATE TABLE superhero
( id INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'pk'
, hero_name VARCHAR(255) NOT NULL COMMENT ''
, first_name VARCHAR(255) NOT NULL DEFAULT '' COMMENT ''
, last_name VARCHAR(255) NOT NULL DEFAULT '' COMMENT ''
, first_appearance DATE COMMENT 'date superhero first appeared'
, gender ENUM('female','male','other') COMMENT 'female,male or other'
, biography_text TEXT COMMENT ''
, universe VARCHAR(255) COMMENT ''
, PRIMARY KEY(id)
, UNIQUE KEY superhero_UX1 (hero_name)
) ENGINE=InnoDB;
CREATE TABLE power
( id INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'pk'
, name VARCHAR(255) NOT NULL COMMENT ''
, description_text TEXT NOT NULL COMMENT ''
, PRIMARY KEY(id)
, UNIQUE KEY power_UX1 (name)
) ENGINE=InnoDB;
CREATE TABLE superheropower
( superhero_id INT UNSIGNED NOT NULL COMMENT 'pk, fk ref superhero'
, power_id INT UNSIGNED NOT NULL COMMENT 'pk, fk ref power'
, PRIMARY KEY(superhero_id, power_id)
, CONSTRAINT FK_superheropower_superhero
FOREIGN KEY(superhero_id) REFERENCES superhero(id)
ON UPDATE CASCADE ON DELETE CASCADE
, CONSTRAINT FK_superheropower_power
FOREIGN KEY (power_id) REFERENCES power(id)
ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=InnoDB;
关于mysql - SQL 多个表之间的多对多关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53132712/