2017-09-25 62 views
-1

我正在設計一個MySQL數據庫。我有一張用戶桌,辦公桌和電話號碼錶,因爲我打算允許多個電話號碼給用戶或辦公室。所以我知道我需要將電話號碼錶中的外鍵添加到辦公室表格和用戶表格中,而不是相反。但是,如何在沒有空記錄的情況下做到這一點? 什麼是最好的規範化的方式,使這與既不officeId不userId在電話號碼記錄空?用戶或辦公室映射電話號碼的最佳規範化練習

我的電話號碼錶

CREATE TABLE `phonenumber` (
    `Id` varchar(36) NOT NULL, 
    `Title` varchar(100) DEFAULT NULL, 
    `UserId` varchar(36) DEFAULT NULL, 
    `SchoolId` int(11) DEFAULT NULL, 
    `CreatedOn` datetime NOT NULL, 
    `ModifiedOn` datetime NOT NULL, 
    `CreatedBy` varchar(36) NOT NULL, 
    `ModifiedBy` varchar(36) NOT NULL, 
    `Number` varchar(20) NOT NULL, 
    PRIMARY KEY (`Id`), 
    KEY `FK_Phone_User` (`UserId`), 
    KEY `FK_Phone_School` (`SchoolId`), 
    CONSTRAINT `FK_Phone_School` FOREIGN KEY (`SchoolId`) REFERENCES `school` (`Id`), 
    CONSTRAINT `FK_Phone_User` FOREIGN KEY (`UserId`) REFERENCES `user` (`Id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

我的用戶表

CREATE TABLE `user` (
    `Id` varchar(36) NOT NULL, 
    `UserName` varchar(20) NOT NULL, 
    `DisplayName` varchar(100) DEFAULT NULL, 
    `OfficialName` varchar(100) DEFAULT NULL, 
    `PasswordHash` varchar(50) DEFAULT NULL, 
    `CreatedOn` datetime DEFAULT NULL, 
    `CreatedBy` varchar(36) DEFAULT NULL, 
    `ModifiedOn` datetime DEFAULT NULL, 
    `ModifiedBy` varchar(36) DEFAULT NULL, 
    PRIMARY KEY (`Id`), 
    UNIQUE KEY `UserName` (`UserName`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

我校表

CREATE TABLE `school` (
    `Id` int(11) NOT NULL AUTO_INCREMENT, 
    `Name` varchar(100) NOT NULL, 
    `AddressId` varchar(36) DEFAULT NULL, 
    `CreatedOn` datetime NOT NULL, 
    `ModifiedOn` datetime NOT NULL, 
    `CreatedBy` varchar(36) NOT NULL, 
    `ModifiedBy` varchar(36) NOT NULL, 
    PRIMARY KEY (`Id`), 
    KEY `FK_School_Address` (`AddressId`), 
    CONSTRAINT `FK_School_Address` FOREIGN KEY (`AddressId`) REFERENCES `address` (`Id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 
+0

如果這兩個值都爲空,只是將它們設置爲null,每當使用的電話號碼,你更新的記錄 – thelmuxkriovar

+0

'長50 PasswordHash'是不是一個好兆頭。使用'VARCHAR(255)'作爲默認的「字符串」列類型,並且只在絕對必要時限制長度。使用'INT'作爲主鍵,自動遞增類型,而不是用戶名。如果你沒有準備好的話,那些可以並且將會改變的將會弄亂你的數據庫。 – tadman

+0

**警告**:編寫您自己的訪問控制層並不容易,並且有很多機會使其嚴重錯誤。請不要在[Laravel](http://laravel.com/)等任何現代開發框架(http://codegeekz.com/best-php-frameworks-for-developers/)上編寫自己的認證系統,內置了強大的[認證系統](https://laravel.com/docs/master/authentication)。絕對不會遵循[推薦的安全最佳實踐](http://www.phptherightway.com/#security),並且**絕不會將密碼與SHA1或MD5 **等受損散列一起存儲。 – tadman

回答

3

您只需在創作的過程中,允許NULL領域Phone_numbers表。你被警告的是整個記錄NULL s。您正確地處理了字段,但沒有說出任何內容或說NULL。這裏有一個例子:

CREATE TABLE Phone_numbers(
phone_number VARCHAR(15) NOT NULL, 
user_id   INT UNSIGNED, 
office_id  INT UNSIGNED, 
PRIMARY KEY (phone_number), 
CONSTRAINT RefUsers1 FOREIGN KEY (user_id) 
REFERENCES Users(user_id), 
CONSTRAINT RefOffices2 FOREIGN KEY (office_id) 
REFERENCES Offices(office_id) 
)ENGINE=INNODB 
; 

對於這個簡單的模型 enter image description here

+0

這個答案與我所做的完全不同。我的實際擔憂是,我已經閱讀過一些最佳實踐文檔,即任何記錄的任何列中都有空值是不好的。 (儘管允許null可以按照業務需要完成)。在這種情況下,當我有辦公室電話號碼記錄時,userId爲空,當我有用戶電話號碼記錄時,辦公室Id爲空。有沒有辦法避免這種情況? –

+0

你不能避免它**如果**你想保留一個電話號碼錶。用戶和辦公室是不同的實體,如果它們不相關,那麼您需要兩(2)個電話表,或者需要組合用戶和辦公室表並添加一個類型(U/O)。有一個NULL不是一件壞事,AFAIK。這是標記不存在或不相關數據的可靠方法。 –

+0

您沒有'NULL'記錄,而是'NULL' **字段**。 NULL字段是可以的! –