2015-05-26 49 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;