多个表之间的SQL多对多关系

时间:2015-05-26 17:49:28

标签: mysql sql

我有一个数据库,我正在尝试在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;

3 个答案:

答案 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”我们的列名,我们使用下划线字符作为分隔符,例如_tablepower_idpowerIDhero_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;