Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 多个表之间的SQL多对多关系_Mysql_Sql - Fatal编程技术网

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

Mysql 多个表之间的SQL多对多关系,mysql,sql,Mysql,Sql,我有一个数据库,我正试图在SQL上创建,我正试图将这些关系连接在一起。有三张表格:超级英雄、力量和超级英雄力量。表superhero和power是一种多对多关系,由表Superherower表示 对于表之间的外键(以及其他所有键),下面的语法是否正确?此外,在这些表格的设置方面是否有其他建议 CREATE TABLE superhero( id INT NOT NULL AUTO_INCREMENT, heroName VARCHAR(255) NOT NULL, firstName VAR

我有一个数据库,我正试图在SQL上创建,我正试图将这些关系连接在一起。有三张表格:超级英雄、力量和超级英雄力量。表superhero和power是一种多对多关系,由表Superherower表示

对于表之间的外键(以及其他所有键),下面的语法是否正确?此外,在这些表格的设置方面是否有其他建议

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;

编辑[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更改为非null,反之亦然,具体取决于您是否希望用户在不安装其他信息的情况下移动过去。我以前从未在我的sql表中使用过自动增量,所以对我来说,这是我刚从你那里学到的新东西

是的,那里的一切看起来都很好。但是


请注意:

对于
gender
列,我们将使用较短的数据类型;我不认为我们需要255个字符来表达。(对强制执行的行的最大大小有限制)。如果只有几个值,我们会考虑<代码>枚举< /代码>数据类型。< /P> 我们还可能在其中几个列上添加
notnull
约束,例如heroname、firstname、lastname。我们还可能添加
默认值'
。有时,出于某种原因,我们确实需要允许空值,但我们尽可能使用
notnull

我对
文本
列犹豫不决。使用
TEXT
datatype并没有什么错,但我怀疑它们可能“隐藏”了一些信息,这些信息最好存储在其他列中

对于外键,我们将按照我们使用的模式为约束指定一个名称,还可能在更新级联时添加
,在删除级联时添加

CONSTRAINT FK_superheroPower_power FOREIGN KEY (powerID) 
  REFERENCES power(id) ON UPDATE CASCADE ON DELETE CASCADE

关于标识符(表名和列名)的说明

按照我们的方式,所有表名都是小写的。(我们有一个MySQL选项集,它强制所有表名小写。)我们这样做是为了避免不同操作系统/文件系统(有些是区分大小写的,有些不是)

此外,表名是单数的。表的名称指定了表的一行所代表的内容。我们也不将
\表
作为名称的一部分

MySQL中的列名从不区分大小写,但我们也总是使用小写作为列名。我们不使用“camelCase”我们的列名,我们使用下划线字符作为分隔符,例如,
power\u id
vs.
powerID
hero\u name
vs.
heroName


跟进

我上面的“注意事项”不是必须遵守的具体规则;这些只是我们使用的模式

遵循这些模式并不能保证我们会有一个成功的软件,但它确实帮助了我们

为了您的参考,我将展示这些桌子将如何作为我们商店的“第一次切割”,作为另一种模式的说明;这不是“正确的方式”,这只是我们作为一个团队已经确定的“方式”

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;

您的设计似乎在正确的轨道上,这是我将使用的表-为字段添加一些索引,您可能会搜索并添加约束键所需的操作

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;

找到答案的最简单方法是尝试一下,看看会发生什么:-)可能更适合于代码复查一些您称之为更正的内容只是首选项,其他则删除重要信息。此外,使用自动递增是一种常见的做法。@Gorilla:有几种不同的模式可以遵循。例如,有些人会反对使用代理
id
列的模式。我们碰巧为实体表使用了代理整数主键,并使用
id
作为列名。(我们的模式是有原因的。)我们所遵循的模式适合我们;我们的模式不是成功软件的唯一模式,它只是“适合”我们。作为另一个例子,我们将所有表名和列名都降为小写。没有规定说这是“正确”的方法。这只是我的团队遵循的一个指导原则。@spencer7593我完全理解,每个人都有自己的方式。像上面的代码一样,我使我更容易理解以及如何编写SQL语法。我还在学校学习计算机编程,所以我没有其他公司喜欢的工作经验,只是想说清楚。我包括的笔记只是我工作的一家特定商店的细节。这并不是说每个人都应该这样做。这只是关于我们这家店的几点说明;我通常只是指出我在我们店里看到的不同的东西。我们非常一致,遵循相当严格的模式和指导方针。大多数模式都有很好的理由,如果有很好的理由,也有偏离它们的空间。其他商店遵循不同的模式,更好地为他们工作,他们需要做什么。