我有一个数据库,我正在尝试在SQL上创建,我正在尝试将这些关系连接在一起。有三个表:superhero,power和superheroPower。表超级英雄和权力是多对多的关系,由表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;
答案 0 :(得分:2)
是的,那里的一切看起来还不错。但...
一些注意事项:
我们对save
列使用较短的数据类型;我没有看到我们需要255个字符才能表达出来。 (强制执行的行的最大大小有限制。)如果只有少数值,我们会考虑gender
数据类型。
我们还可能在其中几个列上添加ENUM
个约束,例如heroname,firstname,lastname。我们也可能会添加NOT NULL
。有时,出于某种原因,我们确实需要允许NULL值,但我们尽可能使用DEFAULT ''
。
我对NOT NULL
列犹豫不决。使用TEXT
数据类型没有任何问题,但我只是怀疑那些可能“隐藏”一些可能更好地存储在其他列中的信息。
对于外键,我们会根据我们使用的模式为约束指定一个名称,并且还可能添加TEXT
ON UPDATE CASCADE ON DELETE CASCADE
关于标识符(表名和列名)的说明
我们这样做,所有表名都是小写。 (我们有一个MySQL选项集,强制所有表名都小写。)我们这样做是为了避免不同操作系统/文件系统的不兼容问题(其中一些是区分大小写的,有些则不是)。
此外,表名是单数。表的名称命名表的一行。我们也不包括CONSTRAINT FK_superheroPower_power FOREIGN KEY (powerID)
REFERENCES power(id) ON UPDATE CASCADE ON DELETE CASCADE
作为名称的一部分。
MySQL中的列名从不区分大小写,但我们也总是使用小写作为列名。我们没有“camelCase”我们的列名,我们使用下划线字符作为分隔符,例如_table
与power_id
,powerID
与hero_name
。
<强>后续强>
上面的“注释”不是必须遵循的具体规则;这些只是我们使用的模式。
遵循这些模式并不能保证我们会有一个成功的软件,但它确实对我们有帮助。
作为您的参考,我将展示这些表格如何从我们的商店看作“第一次切割”,作为另一种模式的说明;这是 not “正确的方式”,它只是我们作为一个团队确定的“方式”。
heroName
答案 1 :(得分:0)
编辑[1]:这是我如何做的SQL代码版本!
CREATE TABLE superhero
(
Superheo_id INT NOT NULL AUTO_INCREMENT,
heroName VARCHAR(255) NOT NULL,
firstName VARCHAR(255)NULL,
lastName VARCHAR(255)NULL,
firstAppearance DATE NULL,
gender VARCHAR(255) NULL,
bio TEXT NULL,
universe VARCHAR(255) NULL,
CONSTRAINT SUPERHERO_PK PRIMARY KEY(SUPERHERO_id)
);
CREATE TABLE power
(
POWER_id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
description TEXT NOT NULL,
CONSTRAINT POWER_PK PRIMARY KEY(POWER_id)
);
CREATE TABLE superheroPower
(
superheroID INT DEFAULT(0) NOT NULL,
powerID INT DEFAULT(0) NOT NULL,
CONSTRAINT SUPERHEROPOWERS_SUPERHERO_FK FOREIGN KEY(superheroID) REFERENCES superhero(id),
CONSTRAINT SUPERHEROPOWERS_POWERS_FK FOREIGN KEY(powerID) REFERENCES power(id)
);
编辑[2]:您可以将 null 更改为非空,反之亦然,具体取决于您是否希望用户移出而不安装其他信息。我以前从未在我的sql表中使用过Auto_increment,所以对我来说这是我刚从你那里学到的新东西
答案 2 :(得分:0)
您的设计似乎在正确的轨道上,这是我将要使用的表格 - 为字段添加一些索引,您可能会搜索并添加CONSTRAINT键所需的操作
CREATE TABLE `_superhero` (
`id` int(11) NOT NULL auto_increment,
`heroName` varchar(255) NOT NULL,
`firstName` varchar(255) default NULL,
`lastName` varchar(255) default NULL,
`firstAppearance` date default NULL,
`gender` enum('Other','Female','Male') default NULL,
`bio` text,
`universe` varchar(255) default NULL,
PRIMARY KEY (`id`),
KEY `indxHname` (`heroName`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `_power` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(255) NOT NULL,
`description` text NOT NULL,
PRIMARY KEY (`id`),
KEY `indx4` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `_superheropower` (
`superheroID` int(11) NOT NULL default '0',
`powerID` int(11) NOT NULL default '0',
PRIMARY KEY (`superheroID`,`powerID`),
KEY `indx1` (`superheroID`),
KEY `indx2` (`powerID`),
CONSTRAINT `fk2` FOREIGN KEY (`powerID`) REFERENCES `_power` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION,
CONSTRAINT `fk1` FOREIGN KEY (`superheroID`) REFERENCES `_superhero` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;