2015-05-26 112 views
1

我有一个数据库,我正尝试在SQL上创建,我试图将这些关系连接在一起。有三个表格:超级英雄,力量和超级英雄力量。表超级英雄和权力是一个多对多的关系,这是由表superheroPower代表。多个表之间的SQL多对多关系

下面的语句是否正确地用于表(和其他所有内容)之间的外键?另外,在这些表格的设置方面是否还有其他建议?

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; 
+2

找出最简单的方法就是试试看看会发生什么:-) –

+0

可能更适合代码审阅 – OneHoopyFrood

回答

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]:你是能够改变NOT NULL并根据如果你想要一个用户移动过去用了安装其他信息,反之亦然。我从来没有在我的sql表中使用过Auto_increment,所以对于我来说这是我刚刚从你那里学到的新东西

+1

您称为更正的部分内容只是偏好设置,其他的则删除重要信息。另外,使用AUTO_INCREMENT是一种常见的做法。 – OneHoopyFrood

+0

@Gorilla:有几种不同的模式可以遵循。例如,有些人会反对使用代理'id'列的模式。我们碰巧为实体表使用了代理整数主键,我们使用'id'作为列名。 (我们有我们的模式的原因。)我们遵循的模式适合我们;我们的模式不是成功软件的唯一模式,它对我们来说是“正确的”。作为另一个例子,我们小写了所有的表名和列名。没有规定说这是做到这一点的“正确”方式。这只是我的团队遵循的准则。 – spencer7593

+0

@ spencer7593我完全明白,每个人都有自己的方式。就像我上面的代码一样,我让我更容易理解以及如何编写SQL语法。我仍然在学校进行计算机编程,所以我没有其他公司喜欢代码偏好的工作经验。 – Gorilla

1

是的,一切都看起来没问题。但是......


的几个注意事项:

,我们会根据对gender列较短的数据类型;我没有看到我们需要255个字符来表达这一点。 (强制执行的最大行数有限制。)如果只有少数值,我们会考虑ENUM数据类型。

我们也可能会在其中几个列上添加NOT NULL约束,例如heroname,firstname,lastname。我们也可能会添加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中的列名从不区分大小写,但我们也总是使用小写字母作为列名。我们不使用“camelCase”列名称,我们使用下划线字符作为分隔符,例如power_idpowerID,hero_name对比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; 
+0

只是要清楚。我收录的笔记仅仅是关于我工作的一个特定商店的细节。这不是一个宣告人人都应该这样做。这只是关于我们*特别*商店做生意的一些注意事项;我主要只是指出了我看到的情况,在我们的店里会有所不同。我们非常一致,遵循相当严格的模式和指导原则。大多数模式都有很好的理由,当有充分的理由时,也有可能偏离这些模式。其他商店遵循*不同的*模式,为他们工作*更好*,他们需要做什么。 – spencer7593

0

您的设计似乎是正确的轨道上,这是表我会去用 - 增加了一些指标为它有可能,你将搜索字段,添加用于约束按键的操作

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;