2017-09-25 5 views
-1

MySQL에서 DB를 설계하고 있습니다. 사용자 또는 사무실에 여러 전화 번호를 허용하려는 경우 사용자 테이블, 사무실 테이블 및 전화 번호 테이블이 있습니다. 그래서 저는 전화 번호 테이블에 외래 키를 사무실 테이블과 사용자 테이블에 추가해야 할 필요가 있음을 압니다. 하지만 null 레코드가 없으면 어떻게해야합니까? 전화 번호 레코드에 userId가 아닌 officeId가 아닌 null을 지정하는 가장 적합한 방법은 무엇입니까?사용자 또는 사무실에 전화 번호를 매핑하는 최상의 정규화 된 방법

내 전화 번호 테이블

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의 경우, 단지 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을 갖는 것이 좋지 않은 몇 가지 모범 사례 문서를 읽었다는 것입니다. (null은 업무상 필요로 할 수 있습니다.)이 경우 여기에 사무실 전화 번호 레코드가있을 때 userId가 null입니다. 사용자 전화 번호 레코드가 있으면 사무실 ID가 null입니다. 그것을 피할 수있는 방법이 있습니까? –

+0

당신은 그것을 피할 수 없습니다 ** 만약 ** 전화 번호에 대해 하나의 테이블을 유지하고 싶습니다. 사용자와 사무실이 서로 다른 엔티티이고 관련이없는 경우 두 개의 전화 테이블이 필요하거나 사용자와 사무실 테이블을 결합하고 유형 (U/O)을 추가해야합니다. NULL을 갖는 것은 나쁜 것이 아닙니다. AFAIK. 이는 존재하지 않거나 관련성이없는 데이터를 표시하는 확실한 방법입니다. –

+0

당신은'NULL' 레코드가 없지만'NULL' ** 필드 **가 있습니다. 'NULL' 필드는 OK입니다! –